001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.rest; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertFalse; 022 023import java.io.ByteArrayInputStream; 024import java.io.IOException; 025import javax.xml.bind.JAXBContext; 026import javax.xml.bind.JAXBException; 027import org.apache.hadoop.conf.Configuration; 028import org.apache.hadoop.hbase.HBaseTestingUtil; 029import org.apache.hadoop.hbase.NamespaceDescriptor; 030import org.apache.hadoop.hbase.client.Admin; 031import org.apache.hadoop.hbase.rest.client.Client; 032import org.apache.hadoop.hbase.rest.client.Cluster; 033import org.apache.hadoop.hbase.rest.client.Response; 034import org.apache.hadoop.hbase.rest.model.NamespacesModel; 035import org.apache.hadoop.hbase.rest.model.TestNamespacesModel; 036import org.apache.hadoop.hbase.testclassification.MediumTests; 037import org.apache.hadoop.hbase.testclassification.RestTests; 038import org.apache.hadoop.hbase.util.Bytes; 039import org.junit.jupiter.api.AfterAll; 040import org.junit.jupiter.api.BeforeAll; 041import org.junit.jupiter.api.Tag; 042import org.junit.jupiter.api.Test; 043 044@Tag(RestTests.TAG) 045@Tag(MediumTests.TAG) 046public class TestNamespacesResource { 047 048 private static String NAMESPACE1 = "TestNamespacesInstanceResource1"; 049 private static String NAMESPACE2 = "TestNamespacesInstanceResource2"; 050 051 private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 052 private static final HBaseRESTTestingUtility REST_TEST_UTIL = new HBaseRESTTestingUtility(); 053 private static Client client; 054 private static JAXBContext context; 055 private static Configuration conf; 056 private static TestNamespacesModel testNamespacesModel; 057 058 @BeforeAll 059 public static void setUpBeforeClass() throws Exception { 060 conf = TEST_UTIL.getConfiguration(); 061 TEST_UTIL.startMiniCluster(); 062 REST_TEST_UTIL.startServletContainer(conf); 063 client = new Client(new Cluster().add("localhost", REST_TEST_UTIL.getServletPort())); 064 testNamespacesModel = new TestNamespacesModel(); 065 context = JAXBContext.newInstance(NamespacesModel.class); 066 } 067 068 @AfterAll 069 public static void tearDownAfterClass() throws Exception { 070 REST_TEST_UTIL.shutdownServletContainer(); 071 TEST_UTIL.shutdownMiniCluster(); 072 } 073 074 private static NamespacesModel fromXML(byte[] content) throws JAXBException { 075 return (NamespacesModel) context.createUnmarshaller() 076 .unmarshal(new ByteArrayInputStream(content)); 077 } 078 079 private boolean doesNamespaceExist(Admin admin, String namespaceName) throws IOException { 080 NamespaceDescriptor[] nd = admin.listNamespaceDescriptors(); 081 for (NamespaceDescriptor namespaceDescriptor : nd) { 082 if (namespaceDescriptor.getName().equals(namespaceName)) { 083 return true; 084 } 085 } 086 return false; 087 } 088 089 private void createNamespaceViaAdmin(Admin admin, String name) throws IOException { 090 NamespaceDescriptor.Builder builder = NamespaceDescriptor.create(name); 091 NamespaceDescriptor nsd = builder.build(); 092 admin.createNamespace(nsd); 093 } 094 095 @Test 096 public void testNamespaceListXMLandJSON() throws IOException, JAXBException { 097 String namespacePath = "/namespaces/"; 098 NamespacesModel model; 099 Response response; 100 101 // Check that namespace does not yet exist via non-REST call. 102 Admin admin = TEST_UTIL.getAdmin(); 103 assertFalse(doesNamespaceExist(admin, NAMESPACE1)); 104 model = testNamespacesModel.buildTestModel(); 105 testNamespacesModel.checkModel(model); 106 107 // Check that REST GET finds only default namespaces via XML and JSON responses. 108 response = client.get(namespacePath, Constants.MIMETYPE_XML); 109 assertEquals(200, response.getCode()); 110 model = fromXML(response.getBody()); 111 testNamespacesModel.checkModel(model, "hbase", "default"); 112 response = client.get(namespacePath, Constants.MIMETYPE_JSON); 113 assertEquals(200, response.getCode()); 114 model = testNamespacesModel.fromJSON(Bytes.toString(response.getBody())); 115 testNamespacesModel.checkModel(model, "hbase", "default"); 116 117 // Create namespace and check that REST GET finds one additional namespace. 118 createNamespaceViaAdmin(admin, NAMESPACE1); 119 response = client.get(namespacePath, Constants.MIMETYPE_XML); 120 assertEquals(200, response.getCode()); 121 model = fromXML(response.getBody()); 122 testNamespacesModel.checkModel(model, NAMESPACE1, "hbase", "default"); 123 response = client.get(namespacePath, Constants.MIMETYPE_JSON); 124 assertEquals(200, response.getCode()); 125 model = testNamespacesModel.fromJSON(Bytes.toString(response.getBody())); 126 testNamespacesModel.checkModel(model, NAMESPACE1, "hbase", "default"); 127 128 // Create another namespace and check that REST GET finds one additional namespace. 129 createNamespaceViaAdmin(admin, NAMESPACE2); 130 response = client.get(namespacePath, Constants.MIMETYPE_XML); 131 assertEquals(200, response.getCode()); 132 model = fromXML(response.getBody()); 133 testNamespacesModel.checkModel(model, NAMESPACE1, NAMESPACE2, "hbase", "default"); 134 response = client.get(namespacePath, Constants.MIMETYPE_JSON); 135 assertEquals(200, response.getCode()); 136 model = testNamespacesModel.fromJSON(Bytes.toString(response.getBody())); 137 testNamespacesModel.checkModel(model, NAMESPACE1, NAMESPACE2, "hbase", "default"); 138 139 // Delete namespace and check that REST still finds correct namespaces. 140 admin.deleteNamespace(NAMESPACE1); 141 response = client.get(namespacePath, Constants.MIMETYPE_XML); 142 assertEquals(200, response.getCode()); 143 model = fromXML(response.getBody()); 144 testNamespacesModel.checkModel(model, NAMESPACE2, "hbase", "default"); 145 response = client.get(namespacePath, Constants.MIMETYPE_JSON); 146 assertEquals(200, response.getCode()); 147 model = testNamespacesModel.fromJSON(Bytes.toString(response.getBody())); 148 testNamespacesModel.checkModel(model, NAMESPACE2, "hbase", "default"); 149 150 admin.deleteNamespace(NAMESPACE2); 151 } 152 153 @Test 154 public void testNamespaceListPBandDefault() throws IOException { 155 String schemaPath = "/namespaces/"; 156 NamespacesModel model; 157 Response response; 158 159 // Check that namespace does not yet exist via non-REST call. 160 Admin admin = TEST_UTIL.getAdmin(); 161 assertFalse(doesNamespaceExist(admin, NAMESPACE1)); 162 model = testNamespacesModel.buildTestModel(); 163 testNamespacesModel.checkModel(model); 164 165 // Check that REST GET finds only default namespaces via PB and default Accept header. 166 response = client.get(schemaPath, Constants.MIMETYPE_PROTOBUF); 167 assertEquals(200, response.getCode()); 168 model.getObjectFromMessage(response.getBody()); 169 testNamespacesModel.checkModel(model, "hbase", "default"); 170 response = client.get(schemaPath); 171 assertEquals(200, response.getCode()); 172 173 // Create namespace and check that REST GET finds one additional namespace. 174 createNamespaceViaAdmin(admin, NAMESPACE1); 175 response = client.get(schemaPath, Constants.MIMETYPE_PROTOBUF); 176 assertEquals(200, response.getCode()); 177 model.getObjectFromMessage(response.getBody()); 178 testNamespacesModel.checkModel(model, NAMESPACE1, "hbase", "default"); 179 response = client.get(schemaPath); 180 assertEquals(200, response.getCode()); 181 182 // Create another namespace and check that REST GET finds one additional namespace. 183 createNamespaceViaAdmin(admin, NAMESPACE2); 184 response = client.get(schemaPath, Constants.MIMETYPE_PROTOBUF); 185 assertEquals(200, response.getCode()); 186 model.getObjectFromMessage(response.getBody()); 187 testNamespacesModel.checkModel(model, NAMESPACE1, NAMESPACE2, "hbase", "default"); 188 response = client.get(schemaPath); 189 assertEquals(200, response.getCode()); 190 191 // Delete namespace and check that REST GET still finds correct namespaces. 192 admin.deleteNamespace(NAMESPACE1); 193 response = client.get(schemaPath, Constants.MIMETYPE_PROTOBUF); 194 assertEquals(200, response.getCode()); 195 model.getObjectFromMessage(response.getBody()); 196 testNamespacesModel.checkModel(model, NAMESPACE2, "hbase", "default"); 197 response = client.get(schemaPath); 198 assertEquals(200, response.getCode()); 199 200 admin.deleteNamespace(NAMESPACE2); 201 } 202}