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