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.Assert.assertEquals; 021import static org.junit.Assert.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.HBaseClassTestRule; 029import org.apache.hadoop.hbase.HBaseTestingUtility; 030import org.apache.hadoop.hbase.NamespaceDescriptor; 031import org.apache.hadoop.hbase.client.Admin; 032import org.apache.hadoop.hbase.rest.client.Client; 033import org.apache.hadoop.hbase.rest.client.Cluster; 034import org.apache.hadoop.hbase.rest.client.Response; 035import org.apache.hadoop.hbase.rest.model.NamespacesModel; 036import org.apache.hadoop.hbase.rest.model.TestNamespacesModel; 037import org.apache.hadoop.hbase.testclassification.MediumTests; 038import org.apache.hadoop.hbase.testclassification.RestTests; 039import org.apache.hadoop.hbase.util.Bytes; 040import org.junit.AfterClass; 041import org.junit.BeforeClass; 042import org.junit.ClassRule; 043import org.junit.Test; 044import org.junit.experimental.categories.Category; 045 046@Category({ RestTests.class, MediumTests.class }) 047public class TestNamespacesResource { 048 @ClassRule 049 public static final HBaseClassTestRule CLASS_RULE = 050 HBaseClassTestRule.forClass(TestNamespacesResource.class); 051 052 private static String NAMESPACE1 = "TestNamespacesInstanceResource1"; 053 private static String NAMESPACE2 = "TestNamespacesInstanceResource2"; 054 055 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 056 private static final HBaseRESTTestingUtility REST_TEST_UTIL = new HBaseRESTTestingUtility(); 057 private static Client client; 058 private static JAXBContext context; 059 private static Configuration conf; 060 private static TestNamespacesModel testNamespacesModel; 061 062 @BeforeClass 063 public static void setUpBeforeClass() throws Exception { 064 conf = TEST_UTIL.getConfiguration(); 065 TEST_UTIL.startMiniCluster(); 066 REST_TEST_UTIL.startServletContainer(conf); 067 client = new Client(new Cluster().add("localhost", REST_TEST_UTIL.getServletPort())); 068 testNamespacesModel = new TestNamespacesModel(); 069 context = JAXBContext.newInstance(NamespacesModel.class); 070 } 071 072 @AfterClass 073 public static void tearDownAfterClass() throws Exception { 074 REST_TEST_UTIL.shutdownServletContainer(); 075 TEST_UTIL.shutdownMiniCluster(); 076 } 077 078 private static NamespacesModel fromXML(byte[] content) throws JAXBException { 079 return (NamespacesModel) context.createUnmarshaller() 080 .unmarshal(new ByteArrayInputStream(content)); 081 } 082 083 private boolean doesNamespaceExist(Admin admin, String namespaceName) throws IOException { 084 NamespaceDescriptor[] nd = admin.listNamespaceDescriptors(); 085 for (NamespaceDescriptor namespaceDescriptor : nd) { 086 if (namespaceDescriptor.getName().equals(namespaceName)) { 087 return true; 088 } 089 } 090 return false; 091 } 092 093 private void createNamespaceViaAdmin(Admin admin, String name) throws IOException { 094 NamespaceDescriptor.Builder builder = NamespaceDescriptor.create(name); 095 NamespaceDescriptor nsd = builder.build(); 096 admin.createNamespace(nsd); 097 } 098 099 @Test 100 public void testNamespaceListXMLandJSON() throws IOException, JAXBException { 101 String namespacePath = "/namespaces/"; 102 NamespacesModel model; 103 Response response; 104 105 // Check that namespace does not yet exist via non-REST call. 106 Admin admin = TEST_UTIL.getAdmin(); 107 assertFalse(doesNamespaceExist(admin, NAMESPACE1)); 108 model = testNamespacesModel.buildTestModel(); 109 testNamespacesModel.checkModel(model); 110 111 // Check that REST GET finds only default namespaces via XML and JSON responses. 112 response = client.get(namespacePath, Constants.MIMETYPE_XML); 113 assertEquals(200, response.getCode()); 114 model = fromXML(response.getBody()); 115 testNamespacesModel.checkModel(model, "hbase", "default"); 116 response = client.get(namespacePath, Constants.MIMETYPE_JSON); 117 assertEquals(200, response.getCode()); 118 model = testNamespacesModel.fromJSON(Bytes.toString(response.getBody())); 119 testNamespacesModel.checkModel(model, "hbase", "default"); 120 121 // Create namespace and check that REST GET finds one additional namespace. 122 createNamespaceViaAdmin(admin, NAMESPACE1); 123 response = client.get(namespacePath, Constants.MIMETYPE_XML); 124 assertEquals(200, response.getCode()); 125 model = fromXML(response.getBody()); 126 testNamespacesModel.checkModel(model, NAMESPACE1, "hbase", "default"); 127 response = client.get(namespacePath, Constants.MIMETYPE_JSON); 128 assertEquals(200, response.getCode()); 129 model = testNamespacesModel.fromJSON(Bytes.toString(response.getBody())); 130 testNamespacesModel.checkModel(model, NAMESPACE1, "hbase", "default"); 131 132 // Create another namespace and check that REST GET finds one additional namespace. 133 createNamespaceViaAdmin(admin, NAMESPACE2); 134 response = client.get(namespacePath, Constants.MIMETYPE_XML); 135 assertEquals(200, response.getCode()); 136 model = fromXML(response.getBody()); 137 testNamespacesModel.checkModel(model, NAMESPACE1, NAMESPACE2, "hbase", "default"); 138 response = client.get(namespacePath, Constants.MIMETYPE_JSON); 139 assertEquals(200, response.getCode()); 140 model = testNamespacesModel.fromJSON(Bytes.toString(response.getBody())); 141 testNamespacesModel.checkModel(model, NAMESPACE1, NAMESPACE2, "hbase", "default"); 142 143 // Delete namespace and check that REST still finds correct namespaces. 144 admin.deleteNamespace(NAMESPACE1); 145 response = client.get(namespacePath, Constants.MIMETYPE_XML); 146 assertEquals(200, response.getCode()); 147 model = fromXML(response.getBody()); 148 testNamespacesModel.checkModel(model, NAMESPACE2, "hbase", "default"); 149 response = client.get(namespacePath, Constants.MIMETYPE_JSON); 150 assertEquals(200, response.getCode()); 151 model = testNamespacesModel.fromJSON(Bytes.toString(response.getBody())); 152 testNamespacesModel.checkModel(model, NAMESPACE2, "hbase", "default"); 153 154 admin.deleteNamespace(NAMESPACE2); 155 } 156 157 @Test 158 public void testNamespaceListPBandDefault() throws IOException { 159 String schemaPath = "/namespaces/"; 160 NamespacesModel model; 161 Response response; 162 163 // Check that namespace does not yet exist via non-REST call. 164 Admin admin = TEST_UTIL.getAdmin(); 165 assertFalse(doesNamespaceExist(admin, NAMESPACE1)); 166 model = testNamespacesModel.buildTestModel(); 167 testNamespacesModel.checkModel(model); 168 169 // Check that REST GET finds only default namespaces via PB and default Accept header. 170 response = client.get(schemaPath, Constants.MIMETYPE_PROTOBUF); 171 assertEquals(200, response.getCode()); 172 model.getObjectFromMessage(response.getBody()); 173 testNamespacesModel.checkModel(model, "hbase", "default"); 174 response = client.get(schemaPath); 175 assertEquals(200, response.getCode()); 176 177 // Create namespace and check that REST GET finds one additional namespace. 178 createNamespaceViaAdmin(admin, NAMESPACE1); 179 response = client.get(schemaPath, Constants.MIMETYPE_PROTOBUF); 180 assertEquals(200, response.getCode()); 181 model.getObjectFromMessage(response.getBody()); 182 testNamespacesModel.checkModel(model, NAMESPACE1, "hbase", "default"); 183 response = client.get(schemaPath); 184 assertEquals(200, response.getCode()); 185 186 // Create another namespace and check that REST GET finds one additional namespace. 187 createNamespaceViaAdmin(admin, NAMESPACE2); 188 response = client.get(schemaPath, Constants.MIMETYPE_PROTOBUF); 189 assertEquals(200, response.getCode()); 190 model.getObjectFromMessage(response.getBody()); 191 testNamespacesModel.checkModel(model, NAMESPACE1, NAMESPACE2, "hbase", "default"); 192 response = client.get(schemaPath); 193 assertEquals(200, response.getCode()); 194 195 // Delete namespace and check that REST GET still finds correct namespaces. 196 admin.deleteNamespace(NAMESPACE1); 197 response = client.get(schemaPath, Constants.MIMETYPE_PROTOBUF); 198 assertEquals(200, response.getCode()); 199 model.getObjectFromMessage(response.getBody()); 200 testNamespacesModel.checkModel(model, NAMESPACE2, "hbase", "default"); 201 response = client.get(schemaPath); 202 assertEquals(200, response.getCode()); 203 204 admin.deleteNamespace(NAMESPACE2); 205 } 206}