http://git-wip-us.apache.org/repos/asf/hbase/blob/052a6f07/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java new file mode 100644 index 0000000..749b8ea --- /dev/null +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestTableScan.java @@ -0,0 +1,615 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.rest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.DataInputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.core.MediaType; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.stream.XMLStreamException; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.MediumTests; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Admin; +import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.filter.ParseFilter; +import org.apache.hadoop.hbase.filter.PrefixFilter; +import org.apache.hadoop.hbase.rest.client.Client; +import org.apache.hadoop.hbase.rest.client.Cluster; +import org.apache.hadoop.hbase.rest.client.Response; +import org.apache.hadoop.hbase.rest.model.CellModel; +import org.apache.hadoop.hbase.rest.model.CellSetModel; +import org.apache.hadoop.hbase.rest.model.RowModel; +import org.apache.hadoop.hbase.rest.provider.JacksonProvider; +import org.apache.hadoop.hbase.util.Bytes; +import org.codehaus.jackson.JsonFactory; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonToken; +import org.codehaus.jackson.map.ObjectMapper; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; + +@Category(MediumTests.class) +public class TestTableScan { + + private static final TableName TABLE = TableName.valueOf("TestScanResource"); + private static final String CFA = "a"; + private static final String CFB = "b"; + private static final String COLUMN_1 = CFA + ":1"; + private static final String COLUMN_2 = CFB + ":2"; + private static Client client; + private static int expectedRows1; + private static int expectedRows2; + private static Configuration conf; + + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + private static final HBaseRESTTestingUtility REST_TEST_UTIL = + new HBaseRESTTestingUtility(); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + conf = TEST_UTIL.getConfiguration(); + conf.set(Constants.CUSTOM_FILTERS, "CustomFilter:" + CustomFilter.class.getName()); + TEST_UTIL.startMiniCluster(); + REST_TEST_UTIL.startServletContainer(conf); + client = new Client(new Cluster().add("localhost", + REST_TEST_UTIL.getServletPort())); + Admin admin = TEST_UTIL.getHBaseAdmin(); + if (!admin.tableExists(TABLE)) { + HTableDescriptor htd = new HTableDescriptor(TABLE); + htd.addFamily(new HColumnDescriptor(CFA)); + htd.addFamily(new HColumnDescriptor(CFB)); + admin.createTable(htd); + expectedRows1 = TestScannerResource.insertData(conf, TABLE, COLUMN_1, 1.0); + expectedRows2 = TestScannerResource.insertData(conf, TABLE, COLUMN_2, 0.5); + } + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + TEST_UTIL.getHBaseAdmin().disableTable(TABLE); + TEST_UTIL.getHBaseAdmin().deleteTable(TABLE); + REST_TEST_UTIL.shutdownServletContainer(); + TEST_UTIL.shutdownMiniCluster(); + } + + @Test + public void testSimpleScannerXML() throws IOException, JAXBException, XMLStreamException { + // Test scanning particular columns + StringBuilder builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_LIMIT + "=10"); + Response response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_XML); + assertEquals(200, response.getCode()); + assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type")); + JAXBContext ctx = JAXBContext.newInstance(CellSetModel.class); + Unmarshaller ush = ctx.createUnmarshaller(); + CellSetModel model = (CellSetModel) ush.unmarshal(response.getStream()); + int count = TestScannerResource.countCellSet(model); + assertEquals(10, count); + checkRowsNotNull(model); + + //Test with no limit. + builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_XML); + assertEquals(200, response.getCode()); + assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type")); + model = (CellSetModel) ush.unmarshal(response.getStream()); + count = TestScannerResource.countCellSet(model); + assertEquals(expectedRows1, count); + checkRowsNotNull(model); + + //Test with start and end row. + builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_START_ROW + "=aaa"); + builder.append("&"); + builder.append(Constants.SCAN_END_ROW + "=aay"); + response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_XML); + assertEquals(200, response.getCode()); + model = (CellSetModel) ush.unmarshal(response.getStream()); + count = TestScannerResource.countCellSet(model); + RowModel startRow = model.getRows().get(0); + assertEquals("aaa", Bytes.toString(startRow.getKey())); + RowModel endRow = model.getRows().get(model.getRows().size() - 1); + assertEquals("aax", Bytes.toString(endRow.getKey())); + assertEquals(24, count); + checkRowsNotNull(model); + + //Test with start row and limit. + builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_START_ROW + "=aaa"); + builder.append("&"); + builder.append(Constants.SCAN_LIMIT + "=15"); + response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_XML); + assertEquals(200, response.getCode()); + assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type")); + model = (CellSetModel) ush.unmarshal(response.getStream()); + startRow = model.getRows().get(0); + assertEquals("aaa", Bytes.toString(startRow.getKey())); + count = TestScannerResource.countCellSet(model); + assertEquals(15, count); + checkRowsNotNull(model); + } + + @Test + public void testSimpleScannerJson() throws IOException, JAXBException { + // Test scanning particular columns with limit. + StringBuilder builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_LIMIT + "=20"); + Response response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_JSON); + assertEquals(200, response.getCode()); + assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type")); + ObjectMapper mapper = new JacksonProvider() + .locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE); + CellSetModel model = mapper.readValue(response.getStream(), CellSetModel.class); + int count = TestScannerResource.countCellSet(model); + assertEquals(20, count); + checkRowsNotNull(model); + + //Test scanning with no limit. + builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_2); + response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_JSON); + assertEquals(200, response.getCode()); + assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type")); + model = mapper.readValue(response.getStream(), CellSetModel.class); + count = TestScannerResource.countCellSet(model); + assertEquals(expectedRows2, count); + checkRowsNotNull(model); + + //Test with start row and end row. + builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_START_ROW + "=aaa"); + builder.append("&"); + builder.append(Constants.SCAN_END_ROW + "=aay"); + response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_JSON); + assertEquals(200, response.getCode()); + model = mapper.readValue(response.getStream(), CellSetModel.class); + RowModel startRow = model.getRows().get(0); + assertEquals("aaa", Bytes.toString(startRow.getKey())); + RowModel endRow = model.getRows().get(model.getRows().size() - 1); + assertEquals("aax", Bytes.toString(endRow.getKey())); + count = TestScannerResource.countCellSet(model); + assertEquals(24, count); + checkRowsNotNull(model); + } + + /** + * An example to scan using listener in unmarshaller for XML. + * @throws Exception the exception + */ + @Test + public void testScanUsingListenerUnmarshallerXML() throws Exception { + StringBuilder builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_LIMIT + "=10"); + Response response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_XML); + assertEquals(200, response.getCode()); + assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type")); + JAXBContext context = JAXBContext.newInstance(ClientSideCellSetModel.class, RowModel.class, + CellModel.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + + final ClientSideCellSetModel.Listener listener = new ClientSideCellSetModel.Listener() { + @Override + public void handleRowModel(ClientSideCellSetModel helper, RowModel row) { + assertTrue(row.getKey() != null); + assertTrue(row.getCells().size() > 0); + } + }; + + // install the callback on all ClientSideCellSetModel instances + unmarshaller.setListener(new Unmarshaller.Listener() { + public void beforeUnmarshal(Object target, Object parent) { + if (target instanceof ClientSideCellSetModel) { + ((ClientSideCellSetModel) target).setCellSetModelListener(listener); + } + } + + public void afterUnmarshal(Object target, Object parent) { + if (target instanceof ClientSideCellSetModel) { + ((ClientSideCellSetModel) target).setCellSetModelListener(null); + } + } + }); + + // create a new XML parser + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + XMLReader reader = factory.newSAXParser().getXMLReader(); + reader.setContentHandler(unmarshaller.getUnmarshallerHandler()); + assertFalse(ClientSideCellSetModel.listenerInvoked); + reader.parse(new InputSource(response.getStream())); + assertTrue(ClientSideCellSetModel.listenerInvoked); + + } + + @Test + public void testStreamingJSON() throws Exception { + // Test scanning particular columns with limit. + StringBuilder builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_LIMIT + "=20"); + Response response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_JSON); + assertEquals(200, response.getCode()); + assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type")); + ObjectMapper mapper = new JacksonProvider() + .locateMapper(CellSetModel.class, MediaType.APPLICATION_JSON_TYPE); + CellSetModel model = mapper.readValue(response.getStream(), CellSetModel.class); + int count = TestScannerResource.countCellSet(model); + assertEquals(20, count); + checkRowsNotNull(model); + + //Test scanning with no limit. + builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_2); + response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_JSON); + assertEquals(200, response.getCode()); + assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type")); + model = mapper.readValue(response.getStream(), CellSetModel.class); + count = TestScannerResource.countCellSet(model); + assertEquals(expectedRows2, count); + checkRowsNotNull(model); + + //Test with start row and end row. + builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_START_ROW + "=aaa"); + builder.append("&"); + builder.append(Constants.SCAN_END_ROW + "=aay"); + response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_JSON); + assertEquals(200, response.getCode()); + + count = 0; + JsonFactory jfactory = new JsonFactory(mapper); + JsonParser jParser = jfactory.createJsonParser(response.getStream()); + boolean found = false; + while (jParser.nextToken() != JsonToken.END_OBJECT) { + if(jParser.getCurrentToken() == JsonToken.START_OBJECT && found) { + RowModel row = jParser.readValueAs(RowModel.class); + assertNotNull(row.getKey()); + for (int i = 0; i < row.getCells().size(); i++) { + if (count == 0) { + assertEquals("aaa", Bytes.toString(row.getKey())); + } + if (count == 23) { + assertEquals("aax", Bytes.toString(row.getKey())); + } + count++; + } + jParser.skipChildren(); + } else { + found = jParser.getCurrentToken() == JsonToken.START_ARRAY; + } + } + assertEquals(24, count); + } + + @Test + public void testSimpleScannerProtobuf() throws Exception { + StringBuilder builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_LIMIT + "=15"); + Response response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_PROTOBUF); + assertEquals(200, response.getCode()); + assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type")); + int rowCount = readProtobufStream(response.getStream()); + assertEquals(15, rowCount); + + //Test with start row and end row. + builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_START_ROW + "=aaa"); + builder.append("&"); + builder.append(Constants.SCAN_END_ROW + "=aay"); + response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_PROTOBUF); + assertEquals(200, response.getCode()); + assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type")); + rowCount = readProtobufStream(response.getStream()); + assertEquals(24, rowCount); + } + + private void checkRowsNotNull(CellSetModel model) { + for (RowModel row: model.getRows()) { + assertTrue(row.getKey() != null); + assertTrue(row.getCells().size() > 0); + } + } + + /** + * Read protobuf stream. + * @param inputStream the input stream + * @return The number of rows in the cell set model. + * @throws IOException Signals that an I/O exception has occurred. + */ + public int readProtobufStream(InputStream inputStream) throws IOException{ + DataInputStream stream = new DataInputStream(inputStream); + CellSetModel model = null; + int rowCount = 0; + try { + while (true) { + byte[] lengthBytes = new byte[2]; + int readBytes = stream.read(lengthBytes); + if (readBytes == -1) { + break; + } + assertEquals(2, readBytes); + int length = Bytes.toShort(lengthBytes); + byte[] cellset = new byte[length]; + stream.read(cellset); + model = new CellSetModel(); + model.getObjectFromMessage(cellset); + checkRowsNotNull(model); + rowCount = rowCount + TestScannerResource.countCellSet(model); + } + } catch (EOFException exp) { + exp.printStackTrace(); + } finally { + stream.close(); + } + return rowCount; + } + + @Test + public void testScanningUnknownColumnJson() throws IOException, JAXBException { + // Test scanning particular columns with limit. + StringBuilder builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=a:test"); + Response response = client.get("/" + TABLE + builder.toString(), + Constants.MIMETYPE_JSON); + assertEquals(200, response.getCode()); + assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type")); + ObjectMapper mapper = new JacksonProvider().locateMapper(CellSetModel.class, + MediaType.APPLICATION_JSON_TYPE); + CellSetModel model = mapper.readValue(response.getStream(), CellSetModel.class); + int count = TestScannerResource.countCellSet(model); + assertEquals(0, count); + } + + @Test + public void testSimpleFilter() throws IOException, JAXBException { + StringBuilder builder = new StringBuilder(); + builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_START_ROW + "=aaa"); + builder.append("&"); + builder.append(Constants.SCAN_END_ROW + "=aay"); + builder.append("&"); + builder.append(Constants.SCAN_FILTER + "=" + URLEncoder.encode("PrefixFilter('aab')", "UTF-8")); + Response response = + client.get("/" + TABLE + builder.toString(), Constants.MIMETYPE_XML); + assertEquals(200, response.getCode()); + JAXBContext ctx = JAXBContext.newInstance(CellSetModel.class); + Unmarshaller ush = ctx.createUnmarshaller(); + CellSetModel model = (CellSetModel) ush.unmarshal(response.getStream()); + int count = TestScannerResource.countCellSet(model); + assertEquals(1, count); + assertEquals("aab", new String(model.getRows().get(0).getCells().get(0).getValue())); + } + + @Test + public void testCompoundFilter() throws IOException, JAXBException { + StringBuilder builder = new StringBuilder(); + builder = new StringBuilder(); + builder.append("/*"); + builder.append("?"); + builder.append(Constants.SCAN_FILTER + "=" + + URLEncoder.encode("PrefixFilter('abc') AND QualifierFilter(=,'binary:1')", "UTF-8")); + Response response = + client.get("/" + TABLE + builder.toString(), Constants.MIMETYPE_XML); + assertEquals(200, response.getCode()); + JAXBContext ctx = JAXBContext.newInstance(CellSetModel.class); + Unmarshaller ush = ctx.createUnmarshaller(); + CellSetModel model = (CellSetModel) ush.unmarshal(response.getStream()); + int count = TestScannerResource.countCellSet(model); + assertEquals(1, count); + assertEquals("abc", new String(model.getRows().get(0).getCells().get(0).getValue())); + } + + @Test + public void testCustomFilter() throws IOException, JAXBException { + StringBuilder builder = new StringBuilder(); + builder = new StringBuilder(); + builder.append("/a*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_FILTER + "=" + URLEncoder.encode("CustomFilter('abc')", "UTF-8")); + Response response = + client.get("/" + TABLE + builder.toString(), Constants.MIMETYPE_XML); + assertEquals(200, response.getCode()); + JAXBContext ctx = JAXBContext.newInstance(CellSetModel.class); + Unmarshaller ush = ctx.createUnmarshaller(); + CellSetModel model = (CellSetModel) ush.unmarshal(response.getStream()); + int count = TestScannerResource.countCellSet(model); + assertEquals(1, count); + assertEquals("abc", new String(model.getRows().get(0).getCells().get(0).getValue())); + } + + @Test + public void testNegativeCustomFilter() throws IOException, JAXBException { + StringBuilder builder = new StringBuilder(); + builder = new StringBuilder(); + builder.append("/b*"); + builder.append("?"); + builder.append(Constants.SCAN_COLUMN + "=" + COLUMN_1); + builder.append("&"); + builder.append(Constants.SCAN_FILTER + "=" + URLEncoder.encode("CustomFilter('abc')", "UTF-8")); + Response response = + client.get("/" + TABLE + builder.toString(), Constants.MIMETYPE_XML); + assertEquals(200, response.getCode()); + JAXBContext ctx = JAXBContext.newInstance(CellSetModel.class); + Unmarshaller ush = ctx.createUnmarshaller(); + CellSetModel model = (CellSetModel) ush.unmarshal(response.getStream()); + int count = TestScannerResource.countCellSet(model); + // Should return no rows as the filters conflict + assertEquals(0, count); + } + + public static class CustomFilter extends PrefixFilter { + private byte[] key = null; + + public CustomFilter(byte[] key) { + super(key); + } + + @Override + public boolean filterRowKey(byte[] buffer, int offset, int length) { + int cmp = Bytes.compareTo(buffer, offset, length, this.key, 0, this.key.length); + return cmp != 0; + } + + public static Filter createFilterFromArguments(ArrayList<byte[]> filterArguments) { + byte[] prefix = ParseFilter.removeQuotesFromByteArray(filterArguments.get(0)); + return new CustomFilter(prefix); + } + } + + /** + * The Class ClientSideCellSetModel which mimics cell set model, and contains listener to perform + * user defined operations on the row model. + */ + @XmlRootElement(name = "CellSet") + @XmlAccessorType(XmlAccessType.FIELD) + public static class ClientSideCellSetModel implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * This list is not a real list; instead it will notify a listener whenever JAXB has + * unmarshalled the next row. + */ + @XmlElement(name="Row") + private List<RowModel> row; + + static boolean listenerInvoked = false; + + /** + * Install a listener for row model on this object. If l is null, the listener + * is removed again. + */ + public void setCellSetModelListener(final Listener l) { + row = (l == null) ? null : new ArrayList<RowModel>() { + private static final long serialVersionUID = 1L; + + public boolean add(RowModel o) { + l.handleRowModel(ClientSideCellSetModel.this, o); + listenerInvoked = true; + return false; + } + }; + } + + /** + * This listener is invoked every time a new row model is unmarshalled. + */ + public static interface Listener { + void handleRowModel(ClientSideCellSetModel helper, RowModel rowModel); + } + } +} + + +
http://git-wip-us.apache.org/repos/asf/hbase/blob/052a6f07/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestVersionResource.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestVersionResource.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestVersionResource.java new file mode 100644 index 0000000..ef68084 --- /dev/null +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestVersionResource.java @@ -0,0 +1,179 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hbase.rest; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.MediumTests; +import org.apache.hadoop.hbase.rest.client.Client; +import org.apache.hadoop.hbase.rest.client.Cluster; +import org.apache.hadoop.hbase.rest.client.Response; +import org.apache.hadoop.hbase.rest.model.StorageClusterVersionModel; +import org.apache.hadoop.hbase.rest.model.VersionModel; +import org.apache.hadoop.hbase.util.Bytes; + +import static org.junit.Assert.*; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.sun.jersey.spi.container.servlet.ServletContainer; +import org.junit.experimental.categories.Category; + +@Category(MediumTests.class) +public class TestVersionResource { + private static final Log LOG = LogFactory.getLog(TestVersionResource.class); + + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + private static final HBaseRESTTestingUtility REST_TEST_UTIL = + new HBaseRESTTestingUtility(); + private static Client client; + private static JAXBContext context; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + TEST_UTIL.startMiniCluster(); + REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration()); + client = new Client(new Cluster().add("localhost", + REST_TEST_UTIL.getServletPort())); + context = JAXBContext.newInstance( + VersionModel.class, + StorageClusterVersionModel.class); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + REST_TEST_UTIL.shutdownServletContainer(); + TEST_UTIL.shutdownMiniCluster(); + } + + private static void validate(VersionModel model) { + assertNotNull(model); + assertNotNull(model.getRESTVersion()); + assertEquals(model.getRESTVersion(), RESTServlet.VERSION_STRING); + String osVersion = model.getOSVersion(); + assertNotNull(osVersion); + assertTrue(osVersion.contains(System.getProperty("os.name"))); + assertTrue(osVersion.contains(System.getProperty("os.version"))); + assertTrue(osVersion.contains(System.getProperty("os.arch"))); + String jvmVersion = model.getJVMVersion(); + assertNotNull(jvmVersion); + assertTrue(jvmVersion.contains(System.getProperty("java.vm.vendor"))); + assertTrue(jvmVersion.contains(System.getProperty("java.version"))); + assertTrue(jvmVersion.contains(System.getProperty("java.vm.version"))); + assertNotNull(model.getServerVersion()); + String jerseyVersion = model.getJerseyVersion(); + assertNotNull(jerseyVersion); + assertEquals(jerseyVersion, ServletContainer.class.getPackage() + .getImplementationVersion()); + } + + @Test + public void testGetStargateVersionText() throws IOException { + Response response = client.get("/version", Constants.MIMETYPE_TEXT); + assertTrue(response.getCode() == 200); + assertEquals(Constants.MIMETYPE_TEXT, response.getHeader("content-type")); + String body = Bytes.toString(response.getBody()); + assertTrue(body.length() > 0); + assertTrue(body.contains(RESTServlet.VERSION_STRING)); + assertTrue(body.contains(System.getProperty("java.vm.vendor"))); + assertTrue(body.contains(System.getProperty("java.version"))); + assertTrue(body.contains(System.getProperty("java.vm.version"))); + assertTrue(body.contains(System.getProperty("os.name"))); + assertTrue(body.contains(System.getProperty("os.version"))); + assertTrue(body.contains(System.getProperty("os.arch"))); + assertTrue(body.contains(ServletContainer.class.getPackage() + .getImplementationVersion())); + } + + @Test + public void testGetStargateVersionXML() throws IOException, JAXBException { + Response response = client.get("/version", Constants.MIMETYPE_XML); + assertTrue(response.getCode() == 200); + assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type")); + VersionModel model = (VersionModel) + context.createUnmarshaller().unmarshal( + new ByteArrayInputStream(response.getBody())); + validate(model); + LOG.info("success retrieving Stargate version as XML"); + } + + @Test + public void testGetStargateVersionJSON() throws IOException { + Response response = client.get("/version", Constants.MIMETYPE_JSON); + assertTrue(response.getCode() == 200); + assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type")); + } + + @Test + public void testGetStargateVersionPB() throws IOException { + Response response = client.get("/version", Constants.MIMETYPE_PROTOBUF); + assertTrue(response.getCode() == 200); + assertEquals(Constants.MIMETYPE_PROTOBUF, response.getHeader("content-type")); + VersionModel model = new VersionModel(); + model.getObjectFromMessage(response.getBody()); + validate(model); + response = client.get("/version", Constants.MIMETYPE_PROTOBUF_IETF); + assertTrue(response.getCode() == 200); + assertEquals(Constants.MIMETYPE_PROTOBUF_IETF, response.getHeader("content-type")); + model = new VersionModel(); + model.getObjectFromMessage(response.getBody()); + validate(model); + } + + @Test + public void testGetStorageClusterVersionText() throws IOException { + Response response = client.get("/version/cluster", Constants.MIMETYPE_TEXT); + assertTrue(response.getCode() == 200); + assertEquals(Constants.MIMETYPE_TEXT, response.getHeader("content-type")); + } + + @Test + public void testGetStorageClusterVersionXML() throws IOException, + JAXBException { + Response response = client.get("/version/cluster",Constants.MIMETYPE_XML); + assertTrue(response.getCode() == 200); + assertEquals(Constants.MIMETYPE_XML, response.getHeader("content-type")); + StorageClusterVersionModel clusterVersionModel = + (StorageClusterVersionModel) + context.createUnmarshaller().unmarshal( + new ByteArrayInputStream(response.getBody())); + assertNotNull(clusterVersionModel); + assertNotNull(clusterVersionModel.getVersion()); + LOG.info("success retrieving storage cluster version as XML"); + } + + @Test + public void doTestGetStorageClusterVersionJSON() throws IOException { + Response response = client.get("/version/cluster", Constants.MIMETYPE_JSON); + assertTrue(response.getCode() == 200); + assertEquals(Constants.MIMETYPE_JSON, response.getHeader("content-type")); + } + +} + http://git-wip-us.apache.org/repos/asf/hbase/blob/052a6f07/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteAdminRetries.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteAdminRetries.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteAdminRetries.java new file mode 100644 index 0000000..a5e5b93 --- /dev/null +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteAdminRetries.java @@ -0,0 +1,165 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.rest.client; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.regex.Pattern; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.SmallTests; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +/** + * Tests {@link RemoteAdmin} retries. + */ +@Category(SmallTests.class) +public class TestRemoteAdminRetries { + + private static final int SLEEP_TIME = 50; + private static final int RETRIES = 3; + private static final long MAX_TIME = SLEEP_TIME * (RETRIES - 1); + + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + + private RemoteAdmin remoteAdmin; + private Client client; + + @Before + public void setup() throws Exception { + client = mock(Client.class); + Response response = new Response(509); + when(client.get(anyString(), anyString())).thenReturn(response); + when(client.delete(anyString())).thenReturn(response); + when(client.put(anyString(), anyString(), any(byte[].class))).thenReturn(response); + when(client.post(anyString(), anyString(), any(byte[].class))).thenReturn(response); + Configuration configuration = TEST_UTIL.getConfiguration(); + + configuration.setInt("hbase.rest.client.max.retries", RETRIES); + configuration.setInt("hbase.rest.client.sleep", SLEEP_TIME); + + remoteAdmin = new RemoteAdmin(client, TEST_UTIL.getConfiguration(), "MyTable"); + } + + @Test + public void testFailingGetRestVersion() throws Exception { + testTimedOutGetCall(new CallExecutor() { + @Override + public void run() throws Exception { + remoteAdmin.getRestVersion(); + } + }); + } + + @Test + public void testFailingGetClusterStatus() throws Exception { + testTimedOutGetCall(new CallExecutor() { + @Override + public void run() throws Exception { + remoteAdmin.getClusterStatus(); + } + }); + } + + @Test + public void testFailingGetClusterVersion() throws Exception { + testTimedOutGetCall(new CallExecutor() { + @Override + public void run() throws Exception { + remoteAdmin.getClusterVersion(); + } + }); + } + + @Test + public void testFailingGetTableAvailable() throws Exception { + testTimedOutCall(new CallExecutor() { + @Override + public void run() throws Exception { + remoteAdmin.isTableAvailable(Bytes.toBytes("TestTable")); + } + }); + } + + @Test + @SuppressWarnings("deprecation") + public void testFailingCreateTable() throws Exception { + testTimedOutCall(new CallExecutor() { + @Override + public void run() throws Exception { + remoteAdmin.createTable(new HTableDescriptor(Bytes.toBytes("TestTable"))); + } + }); + verify(client, times(RETRIES)).put(anyString(), anyString(), any(byte[].class)); + } + + @Test + public void testFailingDeleteTable() throws Exception { + testTimedOutCall(new CallExecutor() { + @Override + public void run() throws Exception { + remoteAdmin.deleteTable("TestTable"); + } + }); + verify(client, times(RETRIES)).delete(anyString()); + } + + @Test + public void testFailingGetTableList() throws Exception { + testTimedOutGetCall(new CallExecutor() { + @Override + public void run() throws Exception { + remoteAdmin.getTableList(); + } + }); + } + + private void testTimedOutGetCall(CallExecutor callExecutor) throws Exception { + testTimedOutCall(callExecutor); + verify(client, times(RETRIES)).get(anyString(), anyString()); + } + + private void testTimedOutCall(CallExecutor callExecutor) throws Exception { + long start = System.currentTimeMillis(); + try { + callExecutor.run(); + fail("should be timeout exception!"); + } catch (IOException e) { + assertTrue(Pattern.matches(".*MyTable.*timed out", e.toString())); + } + assertTrue((System.currentTimeMillis() - start) > MAX_TIME); + } + + private static interface CallExecutor { + void run() throws Exception; + } + +} http://git-wip-us.apache.org/repos/asf/hbase/blob/052a6f07/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteHTableRetries.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteHTableRetries.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteHTableRetries.java new file mode 100644 index 0000000..547dfab --- /dev/null +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteHTableRetries.java @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.rest.client; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.Arrays; +import java.util.regex.Pattern; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.SmallTests; +import org.apache.hadoop.hbase.client.Delete; +import org.apache.hadoop.hbase.client.Get; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +/** + * Test RemoteHTable retries. + */ +@Category(SmallTests.class) +public class TestRemoteHTableRetries { + + private static final int SLEEP_TIME = 50; + private static final int RETRIES = 3; + private static final long MAX_TIME = SLEEP_TIME * (RETRIES - 1); + + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + + private static final byte[] ROW_1 = Bytes.toBytes("testrow1"); + private static final byte[] COLUMN_1 = Bytes.toBytes("a"); + private static final byte[] QUALIFIER_1 = Bytes.toBytes("1"); + private static final byte[] VALUE_1 = Bytes.toBytes("testvalue1"); + + private Client client; + private RemoteHTable remoteTable; + + @Before + public void setup() throws Exception { + client = mock(Client.class); + Response response = new Response(509); + when(client.get(anyString(), anyString())).thenReturn(response); + when(client.delete(anyString())).thenReturn(response); + when(client.put(anyString(), anyString(), any(byte[].class))).thenReturn( + response); + when(client.post(anyString(), anyString(), any(byte[].class))).thenReturn( + response); + + Configuration configuration = TEST_UTIL.getConfiguration(); + configuration.setInt("hbase.rest.client.max.retries", RETRIES); + configuration.setInt("hbase.rest.client.sleep", SLEEP_TIME); + + remoteTable = new RemoteHTable(client, TEST_UTIL.getConfiguration(), + "MyTable"); + } + + @After + public void tearDownAfterClass() throws Exception { + remoteTable.close(); + } + + @Test + public void testDelete() throws Exception { + testTimedOutCall(new CallExecutor() { + @Override + public void run() throws Exception { + Delete delete = new Delete(Bytes.toBytes("delete")); + remoteTable.delete(delete); + } + }); + verify(client, times(RETRIES)).delete(anyString()); + } + + @Test + public void testGet() throws Exception { + testTimedOutGetCall(new CallExecutor() { + @Override + public void run() throws Exception { + remoteTable.get(new Get(Bytes.toBytes("Get"))); + } + }); + } + + @Test + public void testSingleRowPut() throws Exception { + testTimedOutCall(new CallExecutor() { + @Override + public void run() throws Exception { + remoteTable.put(new Put(Bytes.toBytes("Row"))); + } + }); + verify(client, times(RETRIES)).put(anyString(), anyString(), any(byte[].class)); + } + + @Test + public void testMultiRowPut() throws Exception { + testTimedOutCall(new CallExecutor() { + @Override + public void run() throws Exception { + Put[] puts = { new Put(Bytes.toBytes("Row1")), + new Put(Bytes.toBytes("Row2")) }; + remoteTable.put(Arrays.asList(puts)); + } + }); + verify(client, times(RETRIES)).put(anyString(), anyString(), any(byte[].class)); + } + + @Test + public void testGetScanner() throws Exception { + testTimedOutCall(new CallExecutor() { + @Override + public void run() throws Exception { + remoteTable.getScanner(new Scan()); + } + }); + verify(client, times(RETRIES)).post(anyString(), anyString(), any(byte[].class)); + } + + @Test + public void testCheckAndPut() throws Exception { + testTimedOutCall(new CallExecutor() { + @Override + public void run() throws Exception { + Put put = new Put(ROW_1); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + remoteTable.checkAndPut(ROW_1, COLUMN_1, QUALIFIER_1, VALUE_1, put ); + } + }); + verify(client, times(RETRIES)).put(anyString(), anyString(), any(byte[].class)); + } + + @Test + public void testCheckAndDelete() throws Exception { + testTimedOutCall(new CallExecutor() { + @Override + public void run() throws Exception { + Put put = new Put(ROW_1); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + Delete delete= new Delete(ROW_1); + remoteTable.checkAndDelete(ROW_1, COLUMN_1, QUALIFIER_1, VALUE_1, delete ); + } + }); + } + + private void testTimedOutGetCall(CallExecutor callExecutor) throws Exception { + testTimedOutCall(callExecutor); + verify(client, times(RETRIES)).get(anyString(), anyString()); + } + + private void testTimedOutCall(CallExecutor callExecutor) throws Exception { + long start = System.currentTimeMillis(); + try { + callExecutor.run(); + fail("should be timeout exception!"); + } catch (IOException e) { + assertTrue(Pattern.matches(".*request timed out", e.toString())); + } + assertTrue((System.currentTimeMillis() - start) > MAX_TIME); + } + + private static interface CallExecutor { + void run() throws Exception; + } + +} http://git-wip-us.apache.org/repos/asf/hbase/blob/052a6f07/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteTable.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteTable.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteTable.java new file mode 100644 index 0000000..cade2dc --- /dev/null +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/client/TestRemoteTable.java @@ -0,0 +1,539 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hbase.rest.client; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.httpclient.Header; +import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.CellUtil; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.MediumTests; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Admin; +import org.apache.hadoop.hbase.client.Delete; +import org.apache.hadoop.hbase.client.Get; +import org.apache.hadoop.hbase.client.HTable; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.ResultScanner; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.client.Table; +import org.apache.hadoop.hbase.rest.HBaseRESTTestingUtility; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(MediumTests.class) +public class TestRemoteTable { + private static final TableName TABLE = TableName.valueOf("TestRemoteTable"); + private static final byte[] ROW_1 = Bytes.toBytes("testrow1"); + private static final byte[] ROW_2 = Bytes.toBytes("testrow2"); + private static final byte[] ROW_3 = Bytes.toBytes("testrow3"); + private static final byte[] ROW_4 = Bytes.toBytes("testrow4"); + private static final byte[] COLUMN_1 = Bytes.toBytes("a"); + private static final byte[] COLUMN_2 = Bytes.toBytes("b"); + private static final byte[] COLUMN_3 = Bytes.toBytes("c"); + private static final byte[] QUALIFIER_1 = Bytes.toBytes("1"); + private static final byte[] QUALIFIER_2 = Bytes.toBytes("2"); + private static final byte[] VALUE_1 = Bytes.toBytes("testvalue1"); + private static final byte[] VALUE_2 = Bytes.toBytes("testvalue2"); + + private static final long ONE_HOUR = 60 * 60 * 1000; + private static final long TS_2 = System.currentTimeMillis(); + private static final long TS_1 = TS_2 - ONE_HOUR; + + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + private static final HBaseRESTTestingUtility REST_TEST_UTIL = + new HBaseRESTTestingUtility(); + private RemoteHTable remoteTable; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + TEST_UTIL.startMiniCluster(); + REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration()); + } + + @Before + public void before() throws Exception { + Admin admin = TEST_UTIL.getHBaseAdmin(); + if (admin.tableExists(TABLE)) { + if (admin.isTableEnabled(TABLE)) admin.disableTable(TABLE); + admin.deleteTable(TABLE); + } + HTableDescriptor htd = new HTableDescriptor(TABLE); + htd.addFamily(new HColumnDescriptor(COLUMN_1).setMaxVersions(3)); + htd.addFamily(new HColumnDescriptor(COLUMN_2).setMaxVersions(3)); + htd.addFamily(new HColumnDescriptor(COLUMN_3).setMaxVersions(3)); + admin.createTable(htd); + Table table = null; + try { + table = new HTable(TEST_UTIL.getConfiguration(), TABLE); + Put put = new Put(ROW_1); + put.add(COLUMN_1, QUALIFIER_1, TS_2, VALUE_1); + table.put(put); + put = new Put(ROW_2); + put.add(COLUMN_1, QUALIFIER_1, TS_1, VALUE_1); + put.add(COLUMN_1, QUALIFIER_1, TS_2, VALUE_2); + put.add(COLUMN_2, QUALIFIER_2, TS_2, VALUE_2); + table.put(put); + table.flushCommits(); + } finally { + if (null != table) table.close(); + } + remoteTable = new RemoteHTable( + new Client(new Cluster().add("localhost", + REST_TEST_UTIL.getServletPort())), + TEST_UTIL.getConfiguration(), TABLE.toBytes()); + } + + @After + public void after() throws Exception { + remoteTable.close(); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + REST_TEST_UTIL.shutdownServletContainer(); + TEST_UTIL.shutdownMiniCluster(); + } + + @Test + public void testGetTableDescriptor() throws IOException { + Table table = null; + try { + table = new HTable(TEST_UTIL.getConfiguration(), TABLE); + HTableDescriptor local = table.getTableDescriptor(); + assertEquals(remoteTable.getTableDescriptor(), local); + } finally { + if (null != table) table.close(); + } + } + + @Test + public void testGet() throws IOException { + Get get = new Get(ROW_1); + Result result = remoteTable.get(get); + byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1); + byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value1); + assertTrue(Bytes.equals(VALUE_1, value1)); + assertNull(value2); + + get = new Get(ROW_1); + get.addFamily(COLUMN_3); + result = remoteTable.get(get); + value1 = result.getValue(COLUMN_1, QUALIFIER_1); + value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNull(value1); + assertNull(value2); + + get = new Get(ROW_1); + get.addColumn(COLUMN_1, QUALIFIER_1); + get.addColumn(COLUMN_2, QUALIFIER_2); + result = remoteTable.get(get); + value1 = result.getValue(COLUMN_1, QUALIFIER_1); + value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value1); + assertTrue(Bytes.equals(VALUE_1, value1)); + assertNull(value2); + + get = new Get(ROW_2); + result = remoteTable.get(get); + value1 = result.getValue(COLUMN_1, QUALIFIER_1); + value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value1); + assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2 + assertNotNull(value2); + assertTrue(Bytes.equals(VALUE_2, value2)); + + get = new Get(ROW_2); + get.addFamily(COLUMN_1); + result = remoteTable.get(get); + value1 = result.getValue(COLUMN_1, QUALIFIER_1); + value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value1); + assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2 + assertNull(value2); + + get = new Get(ROW_2); + get.addColumn(COLUMN_1, QUALIFIER_1); + get.addColumn(COLUMN_2, QUALIFIER_2); + result = remoteTable.get(get); + value1 = result.getValue(COLUMN_1, QUALIFIER_1); + value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value1); + assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2 + assertNotNull(value2); + assertTrue(Bytes.equals(VALUE_2, value2)); + + // test timestamp + + get = new Get(ROW_2); + get.addFamily(COLUMN_1); + get.addFamily(COLUMN_2); + get.setTimeStamp(TS_1); + result = remoteTable.get(get); + value1 = result.getValue(COLUMN_1, QUALIFIER_1); + value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value1); + assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1 + assertNull(value2); + + // test timerange + + get = new Get(ROW_2); + get.addFamily(COLUMN_1); + get.addFamily(COLUMN_2); + get.setTimeRange(0, TS_1 + 1); + result = remoteTable.get(get); + value1 = result.getValue(COLUMN_1, QUALIFIER_1); + value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value1); + assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1 + assertNull(value2); + + // test maxVersions + + get = new Get(ROW_2); + get.addFamily(COLUMN_1); + get.setMaxVersions(2); + result = remoteTable.get(get); + int count = 0; + for (Cell kv: result.listCells()) { + if (CellUtil.matchingFamily(kv, COLUMN_1) && TS_1 == kv.getTimestamp()) { + assertTrue(CellUtil.matchingValue(kv, VALUE_1)); // @TS_1 + count++; + } + if (CellUtil.matchingFamily(kv, COLUMN_1) && TS_2 == kv.getTimestamp()) { + assertTrue(CellUtil.matchingValue(kv, VALUE_2)); // @TS_2 + count++; + } + } + assertEquals(2, count); + } + + @Test + public void testMultiGet() throws Exception { + ArrayList<Get> gets = new ArrayList<Get>(); + gets.add(new Get(ROW_1)); + gets.add(new Get(ROW_2)); + Result[] results = remoteTable.get(gets); + assertNotNull(results); + assertEquals(2, results.length); + assertEquals(1, results[0].size()); + assertEquals(2, results[1].size()); + + //Test Versions + gets = new ArrayList<Get>(); + Get g = new Get(ROW_1); + g.setMaxVersions(3); + gets.add(g); + gets.add(new Get(ROW_2)); + results = remoteTable.get(gets); + assertNotNull(results); + assertEquals(2, results.length); + assertEquals(1, results[0].size()); + assertEquals(3, results[1].size()); + + //404 + gets = new ArrayList<Get>(); + gets.add(new Get(Bytes.toBytes("RESALLYREALLYNOTTHERE"))); + results = remoteTable.get(gets); + assertNotNull(results); + assertEquals(0, results.length); + + gets = new ArrayList<Get>(); + gets.add(new Get(Bytes.toBytes("RESALLYREALLYNOTTHERE"))); + gets.add(new Get(ROW_1)); + gets.add(new Get(ROW_2)); + results = remoteTable.get(gets); + assertNotNull(results); + assertEquals(2, results.length); + } + + @Test + public void testPut() throws IOException { + Put put = new Put(ROW_3); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + remoteTable.put(put); + + Get get = new Get(ROW_3); + get.addFamily(COLUMN_1); + Result result = remoteTable.get(get); + byte[] value = result.getValue(COLUMN_1, QUALIFIER_1); + assertNotNull(value); + assertTrue(Bytes.equals(VALUE_1, value)); + + // multiput + + List<Put> puts = new ArrayList<Put>(); + put = new Put(ROW_3); + put.add(COLUMN_2, QUALIFIER_2, VALUE_2); + puts.add(put); + put = new Put(ROW_4); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + puts.add(put); + put = new Put(ROW_4); + put.add(COLUMN_2, QUALIFIER_2, VALUE_2); + puts.add(put); + remoteTable.put(puts); + + get = new Get(ROW_3); + get.addFamily(COLUMN_2); + result = remoteTable.get(get); + value = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value); + assertTrue(Bytes.equals(VALUE_2, value)); + get = new Get(ROW_4); + result = remoteTable.get(get); + value = result.getValue(COLUMN_1, QUALIFIER_1); + assertNotNull(value); + assertTrue(Bytes.equals(VALUE_1, value)); + value = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value); + assertTrue(Bytes.equals(VALUE_2, value)); + + assertTrue(Bytes.equals(Bytes.toBytes("TestRemoteTable"), remoteTable.getTableName())); + } + + @Test + public void testDelete() throws IOException { + Put put = new Put(ROW_3); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + put.add(COLUMN_2, QUALIFIER_2, VALUE_2); + remoteTable.put(put); + + Get get = new Get(ROW_3); + get.addFamily(COLUMN_1); + get.addFamily(COLUMN_2); + Result result = remoteTable.get(get); + byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1); + byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value1); + assertTrue(Bytes.equals(VALUE_1, value1)); + assertNotNull(value2); + assertTrue(Bytes.equals(VALUE_2, value2)); + + Delete delete = new Delete(ROW_3); + delete.deleteColumn(COLUMN_2, QUALIFIER_2); + remoteTable.delete(delete); + + get = new Get(ROW_3); + get.addFamily(COLUMN_1); + get.addFamily(COLUMN_2); + result = remoteTable.get(get); + value1 = result.getValue(COLUMN_1, QUALIFIER_1); + value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value1); + assertTrue(Bytes.equals(VALUE_1, value1)); + assertNull(value2); + + delete = new Delete(ROW_3); + delete.setTimestamp(1L); + remoteTable.delete(delete); + + get = new Get(ROW_3); + get.addFamily(COLUMN_1); + get.addFamily(COLUMN_2); + result = remoteTable.get(get); + value1 = result.getValue(COLUMN_1, QUALIFIER_1); + value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value1); + assertTrue(Bytes.equals(VALUE_1, value1)); + assertNull(value2); + + delete = new Delete(ROW_3); + remoteTable.delete(delete); + + get = new Get(ROW_3); + get.addFamily(COLUMN_1); + get.addFamily(COLUMN_2); + result = remoteTable.get(get); + value1 = result.getValue(COLUMN_1, QUALIFIER_1); + value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNull(value1); + assertNull(value2); + } + + /** + * Test RemoteHTable.Scanner + */ + @Test + public void testScanner() throws IOException { + List<Put> puts = new ArrayList<Put>(); + Put put = new Put(ROW_1); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + puts.add(put); + put = new Put(ROW_2); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + puts.add(put); + put = new Put(ROW_3); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + puts.add(put); + put = new Put(ROW_4); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + puts.add(put); + remoteTable.put(puts); + + ResultScanner scanner = remoteTable.getScanner(new Scan()); + + Result[] results = scanner.next(1); + assertNotNull(results); + assertEquals(1, results.length); + assertTrue(Bytes.equals(ROW_1, results[0].getRow())); + + Result result = scanner.next(); + assertNotNull(result); + assertTrue(Bytes.equals(ROW_2, result.getRow())); + + results = scanner.next(2); + assertNotNull(results); + assertEquals(2, results.length); + assertTrue(Bytes.equals(ROW_3, results[0].getRow())); + assertTrue(Bytes.equals(ROW_4, results[1].getRow())); + + results = scanner.next(1); + assertNull(results); + scanner.close(); + + scanner = remoteTable.getScanner(COLUMN_1); + results = scanner.next(4); + assertNotNull(results); + assertEquals(4, results.length); + assertTrue(Bytes.equals(ROW_1, results[0].getRow())); + assertTrue(Bytes.equals(ROW_2, results[1].getRow())); + assertTrue(Bytes.equals(ROW_3, results[2].getRow())); + assertTrue(Bytes.equals(ROW_4, results[3].getRow())); + + scanner.close(); + + scanner = remoteTable.getScanner(COLUMN_1,QUALIFIER_1); + results = scanner.next(4); + assertNotNull(results); + assertEquals(4, results.length); + assertTrue(Bytes.equals(ROW_1, results[0].getRow())); + assertTrue(Bytes.equals(ROW_2, results[1].getRow())); + assertTrue(Bytes.equals(ROW_3, results[2].getRow())); + assertTrue(Bytes.equals(ROW_4, results[3].getRow())); + scanner.close(); + assertTrue(remoteTable.isAutoFlush()); + + } + + @Test + public void testCheckAndDelete() throws IOException { + Get get = new Get(ROW_1); + Result result = remoteTable.get(get); + byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1); + byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2); + assertNotNull(value1); + assertTrue(Bytes.equals(VALUE_1, value1)); + assertNull(value2); + assertTrue(remoteTable.exists(get)); + assertEquals(1, remoteTable.exists(Collections.singletonList(get)).length); + Delete delete = new Delete(ROW_1); + + remoteTable.checkAndDelete(ROW_1, COLUMN_1, QUALIFIER_1, VALUE_1, delete); + assertFalse(remoteTable.exists(get)); + + Put put = new Put(ROW_1); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + remoteTable.put(put); + + assertTrue(remoteTable.checkAndPut(ROW_1, COLUMN_1, QUALIFIER_1, VALUE_1, + put)); + assertFalse(remoteTable.checkAndPut(ROW_1, COLUMN_1, QUALIFIER_1, VALUE_2, + put)); + } + + /** + * Test RemoteHable.Scanner.iterator method + */ + @Test + public void testIteratorScaner() throws IOException { + List<Put> puts = new ArrayList<Put>(); + Put put = new Put(ROW_1); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + puts.add(put); + put = new Put(ROW_2); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + puts.add(put); + put = new Put(ROW_3); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + puts.add(put); + put = new Put(ROW_4); + put.add(COLUMN_1, QUALIFIER_1, VALUE_1); + puts.add(put); + remoteTable.put(puts); + + ResultScanner scanner = remoteTable.getScanner(new Scan()); + Iterator<Result> iterator = scanner.iterator(); + assertTrue(iterator.hasNext()); + int counter = 0; + while (iterator.hasNext()) { + iterator.next(); + counter++; + } + assertEquals(4, counter); + } + + /** + * Test a some methods of class Response. + */ + @Test + public void testResponse(){ + Response response = new Response(200); + assertEquals(200, response.getCode()); + Header[] headers = new Header[2]; + headers[0] = new Header("header1", "value1"); + headers[1] = new Header("header2", "value2"); + response = new Response(200, headers); + assertEquals("value1", response.getHeader("header1")); + assertFalse(response.hasBody()); + response.setCode(404); + assertEquals(404, response.getCode()); + headers = new Header[2]; + headers[0] = new Header("header1", "value1.1"); + headers[1] = new Header("header2", "value2"); + response.setHeaders(headers); + assertEquals("value1.1", response.getHeader("header1")); + response.setBody(Bytes.toBytes("body")); + assertTrue(response.hasBody()); + } + +} + http://git-wip-us.apache.org/repos/asf/hbase/blob/052a6f07/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestCellModel.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestCellModel.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestCellModel.java new file mode 100644 index 0000000..170dfab --- /dev/null +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestCellModel.java @@ -0,0 +1,84 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hbase.rest.model; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + +import com.sun.jersey.api.json.JSONJAXBContext; +import org.apache.hadoop.hbase.SmallTests; +import org.apache.hadoop.hbase.util.Base64; +import org.apache.hadoop.hbase.util.Bytes; + +import junit.framework.TestCase; +import org.junit.experimental.categories.Category; + +@Category(SmallTests.class) +public class TestCellModel extends TestModelBase<CellModel> { + + private static final long TIMESTAMP = 1245219839331L; + private static final byte[] COLUMN = Bytes.toBytes("testcolumn"); + private static final byte[] VALUE = Bytes.toBytes("testvalue"); + + public TestCellModel() throws Exception { + super(CellModel.class); + AS_XML = + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Cell " + + "column=\"dGVzdGNvbHVtbg==\" timestamp=\"1245219839331\">dGVzdHZhbHVl</Cell>"; + AS_PB = + "Egp0ZXN0Y29sdW1uGOO6i+eeJCIJdGVzdHZhbHVl"; + + AS_JSON = + "{\"column\":\"dGVzdGNvbHVtbg==\",\"timestamp\":1245219839331,\"$\":\"dGVzdHZhbHVl\"}"; + } + + protected CellModel buildTestModel() { + CellModel model = new CellModel(); + model.setColumn(COLUMN); + model.setTimestamp(TIMESTAMP); + model.setValue(VALUE); + return model; + } + + protected void checkModel(CellModel model) { + assertTrue(Bytes.equals(model.getColumn(), COLUMN)); + assertTrue(Bytes.equals(model.getValue(), VALUE)); + assertTrue(model.hasUserTimestamp()); + assertEquals(model.getTimestamp(), TIMESTAMP); + } + + public void testBuildModel() throws Exception { + checkModel(buildTestModel()); + } + + public void testFromXML() throws Exception { + checkModel(fromXML(AS_XML)); + } + + public void testFromPB() throws Exception { + checkModel(fromPB(AS_PB)); + } + +} + http://git-wip-us.apache.org/repos/asf/hbase/blob/052a6f07/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestCellSetModel.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestCellSetModel.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestCellSetModel.java new file mode 100644 index 0000000..716da14 --- /dev/null +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestCellSetModel.java @@ -0,0 +1,146 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hbase.rest.model; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Iterator; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + +import org.apache.hadoop.hbase.SmallTests; +import org.apache.hadoop.hbase.util.Base64; +import org.apache.hadoop.hbase.util.Bytes; + +import junit.framework.TestCase; +import org.junit.experimental.categories.Category; + +@Category(SmallTests.class) +public class TestCellSetModel extends TestModelBase<CellSetModel> { + + private static final byte[] ROW1 = Bytes.toBytes("testrow1"); + private static final byte[] COLUMN1 = Bytes.toBytes("testcolumn1"); + private static final byte[] VALUE1 = Bytes.toBytes("testvalue1"); + private static final long TIMESTAMP1 = 1245219839331L; + private static final byte[] ROW2 = Bytes.toBytes("testrow1"); + private static final byte[] COLUMN2 = Bytes.toBytes("testcolumn2"); + private static final byte[] VALUE2 = Bytes.toBytes("testvalue2"); + private static final long TIMESTAMP2 = 1245239813319L; + private static final byte[] COLUMN3 = Bytes.toBytes("testcolumn3"); + private static final byte[] VALUE3 = Bytes.toBytes("testvalue3"); + private static final long TIMESTAMP3 = 1245393318192L; + + public TestCellSetModel() throws Exception { + super(CellSetModel.class); + AS_XML = + "<CellSet>" + + "<Row key=\"dGVzdHJvdzE=\">" + + "<Cell timestamp=\"1245219839331\" column=\"dGVzdGNvbHVtbjE=\">" + + "dGVzdHZhbHVlMQ==</Cell>" + + "</Row>" + + "<Row key=\"dGVzdHJvdzE=\">" + + "<Cell timestamp=\"1245239813319\" column=\"dGVzdGNvbHVtbjI=\">" + + "dGVzdHZhbHVlMg==</Cell>" + + "<Cell timestamp=\"1245393318192\" column=\"dGVzdGNvbHVtbjM=\">" + + "dGVzdHZhbHVlMw==</Cell>" + + "</Row>" + + "</CellSet>"; + + AS_PB = + "CiwKCHRlc3Ryb3cxEiASC3Rlc3Rjb2x1bW4xGOO6i+eeJCIKdGVzdHZhbHVlMQpOCgh0ZXN0cm93" + + "MRIgEgt0ZXN0Y29sdW1uMhjHyc7wniQiCnRlc3R2YWx1ZTISIBILdGVzdGNvbHVtbjMYsOLnuZ8k" + + "Igp0ZXN0dmFsdWUz"; + + AS_XML = + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><CellSet>" + + "<Row key=\"dGVzdHJvdzE=\"><Cell column=\"dGVzdGNvbHVtbjE=\" timestamp=\"1245219839331\">" + + "dGVzdHZhbHVlMQ==</Cell></Row><Row key=\"dGVzdHJvdzE=\">" + + "<Cell column=\"dGVzdGNvbHVtbjI=\" timestamp=\"1245239813319\">" + + "dGVzdHZhbHVlMg==</Cell>" + + "<Cell column=\"dGVzdGNvbHVtbjM=\" timestamp=\"1245393318192\">dGVzdHZhbHVlMw==</Cell>" + + "</Row></CellSet>"; + + AS_JSON = + "{\"Row\":[{\"key\":\"dGVzdHJvdzE=\"," + + "\"Cell\":[{\"column\":\"dGVzdGNvbHVtbjE=\",\"timestamp\":1245219839331," + + "\"$\":\"dGVzdHZhbHVlMQ==\"}]},{\"key\":\"dGVzdHJvdzE=\"," + + "\"Cell\":[{\"column\":\"dGVzdGNvbHVtbjI=\",\"timestamp\":1245239813319," + + "\"$\":\"dGVzdHZhbHVlMg==\"},{\"column\":\"dGVzdGNvbHVtbjM=\"," + + "\"timestamp\":1245393318192,\"$\":\"dGVzdHZhbHVlMw==\"}]}]}"; + } + + protected CellSetModel buildTestModel() { + CellSetModel model = new CellSetModel(); + RowModel row; + row = new RowModel(); + row.setKey(ROW1); + row.addCell(new CellModel(COLUMN1, TIMESTAMP1, VALUE1)); + model.addRow(row); + row = new RowModel(); + row.setKey(ROW2); + row.addCell(new CellModel(COLUMN2, TIMESTAMP2, VALUE2)); + row.addCell(new CellModel(COLUMN3, TIMESTAMP3, VALUE3)); + model.addRow(row); + return model; + } + + protected void checkModel(CellSetModel model) { + Iterator<RowModel> rows = model.getRows().iterator(); + RowModel row = rows.next(); + assertTrue(Bytes.equals(ROW1, row.getKey())); + Iterator<CellModel> cells = row.getCells().iterator(); + CellModel cell = cells.next(); + assertTrue(Bytes.equals(COLUMN1, cell.getColumn())); + assertTrue(Bytes.equals(VALUE1, cell.getValue())); + assertTrue(cell.hasUserTimestamp()); + assertEquals(cell.getTimestamp(), TIMESTAMP1); + assertFalse(cells.hasNext()); + row = rows.next(); + assertTrue(Bytes.equals(ROW2, row.getKey())); + cells = row.getCells().iterator(); + cell = cells.next(); + assertTrue(Bytes.equals(COLUMN2, cell.getColumn())); + assertTrue(Bytes.equals(VALUE2, cell.getValue())); + assertTrue(cell.hasUserTimestamp()); + assertEquals(cell.getTimestamp(), TIMESTAMP2); + cell = cells.next(); + assertTrue(Bytes.equals(COLUMN3, cell.getColumn())); + assertTrue(Bytes.equals(VALUE3, cell.getValue())); + assertTrue(cell.hasUserTimestamp()); + assertEquals(cell.getTimestamp(), TIMESTAMP3); + assertFalse(cells.hasNext()); + } + + public void testBuildModel() throws Exception { + checkModel(buildTestModel()); + } + + public void testFromXML() throws Exception { + checkModel(fromXML(AS_XML)); + } + + public void testFromPB() throws Exception { + checkModel(fromPB(AS_PB)); + } + +} + http://git-wip-us.apache.org/repos/asf/hbase/blob/052a6f07/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestColumnSchemaModel.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestColumnSchemaModel.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestColumnSchemaModel.java new file mode 100644 index 0000000..15e1652 --- /dev/null +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestColumnSchemaModel.java @@ -0,0 +1,86 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hbase.rest.model; + +import java.io.StringReader; +import java.io.StringWriter; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + +import junit.framework.TestCase; +import org.apache.hadoop.hbase.SmallTests; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(SmallTests.class) +public class TestColumnSchemaModel extends TestModelBase<ColumnSchemaModel> { + + protected static final String COLUMN_NAME = "testcolumn"; + protected static final boolean BLOCKCACHE = true; + protected static final int BLOCKSIZE = 16384; + protected static final String BLOOMFILTER = "NONE"; + protected static final String COMPRESSION = "GZ"; + protected static final boolean IN_MEMORY = false; + protected static final int TTL = 86400; + protected static final int VERSIONS = 1; + + public TestColumnSchemaModel() throws Exception { + super(ColumnSchemaModel.class); + AS_XML = + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><ColumnSchema " + + "name=\"testcolumn\" BLOCKSIZE=\"16384\" BLOOMFILTER=\"NONE\" BLOCKCACHE=\"true\" " + + "COMPRESSION=\"GZ\" VERSIONS=\"1\" TTL=\"86400\" IN_MEMORY=\"false\"/>"; + + AS_JSON = + "{\"name\":\"testcolumn\",\"BLOCKSIZE\":\"16384\",\"BLOOMFILTER\":\"NONE\"," + + "\"BLOCKCACHE\":\"true\",\"COMPRESSION\":\"GZ\",\"VERSIONS\":\"1\"," + + "\"TTL\":\"86400\",\"IN_MEMORY\":\"false\"}"; + } + + protected ColumnSchemaModel buildTestModel() { + ColumnSchemaModel model = new ColumnSchemaModel(); + model.setName(COLUMN_NAME); + model.__setBlocksize(BLOCKSIZE); + model.__setBloomfilter(BLOOMFILTER); + model.__setBlockcache(BLOCKCACHE); + model.__setCompression(COMPRESSION); + model.__setVersions(VERSIONS); + model.__setTTL(TTL); + model.__setInMemory(IN_MEMORY); + return model; + } + + protected void checkModel(ColumnSchemaModel model) { + assertEquals(model.getName(), COLUMN_NAME); + assertEquals(model.__getBlockcache(), BLOCKCACHE); + assertEquals(model.__getBlocksize(), BLOCKSIZE); + assertEquals(model.__getBloomfilter(), BLOOMFILTER); + assertTrue(model.__getCompression().equalsIgnoreCase(COMPRESSION)); + assertEquals(model.__getInMemory(), IN_MEMORY); + assertEquals(model.__getTTL(), TTL); + assertEquals(model.__getVersions(), VERSIONS); + } + + public void testFromPB() throws Exception { + } +} + http://git-wip-us.apache.org/repos/asf/hbase/blob/052a6f07/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestModelBase.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestModelBase.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestModelBase.java new file mode 100644 index 0000000..500d924 --- /dev/null +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestModelBase.java @@ -0,0 +1,134 @@ +/* + * Copyright 2010 The Apache Software Foundation + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hbase.rest.model; + +import junit.framework.TestCase; +import org.apache.hadoop.hbase.SmallTests; +import org.apache.hadoop.hbase.rest.ProtobufMessageHandler; +import org.apache.hadoop.hbase.rest.provider.JAXBContextResolver; +import org.apache.hadoop.hbase.util.Base64; +import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.node.ObjectNode; +import org.junit.experimental.categories.Category; + +import javax.ws.rs.core.MediaType; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; + +@Category(SmallTests.class) +public abstract class TestModelBase<T> extends TestCase { + + protected String AS_XML; + + protected String AS_PB; + + protected String AS_JSON; + + protected JAXBContext context; + + protected Class<?> clazz; + + protected ObjectMapper mapper; + + protected TestModelBase(Class<?> clazz) throws Exception { + super(); + this.clazz = clazz; + context = new JAXBContextResolver().getContext(clazz); + mapper = new JacksonJaxbJsonProvider().locateMapper(clazz, + MediaType.APPLICATION_JSON_TYPE); + } + + protected abstract T buildTestModel(); + + @SuppressWarnings("unused") + protected String toXML(T model) throws JAXBException { + StringWriter writer = new StringWriter(); + context.createMarshaller().marshal(model, writer); + return writer.toString(); + } + + protected String toJSON(T model) throws JAXBException, IOException { + StringWriter writer = new StringWriter(); + mapper.writeValue(writer, model); +// original marshaller, uncomment this and comment mapper to verify backward compatibility +// ((JSONJAXBContext)context).createJSONMarshaller().marshallToJSON(model, writer); + return writer.toString(); + } + + public T fromJSON(String json) throws JAXBException, IOException { + return (T) + mapper.readValue(json, clazz); + } + + public T fromXML(String xml) throws JAXBException { + return (T) + context.createUnmarshaller().unmarshal(new StringReader(xml)); + } + + @SuppressWarnings("unused") + protected byte[] toPB(ProtobufMessageHandler model) { + return model.createProtobufOutput(); + } + + protected T fromPB(String pb) throws + Exception { + return (T)clazz.getMethod("getObjectFromMessage", byte[].class).invoke( + clazz.newInstance(), + Base64.decode(AS_PB)); + } + + protected abstract void checkModel(T model); + + public void testBuildModel() throws Exception { + checkModel(buildTestModel()); + } + + public void testFromPB() throws Exception { + checkModel(fromPB(AS_PB)); + } + + public void testFromXML() throws Exception { + checkModel(fromXML(AS_XML)); + } + + public void testToXML() throws Exception { + assertEquals(AS_XML, toXML(buildTestModel())); + } + + public void testToJSON() throws Exception { + try { + ObjectNode expObj = mapper.readValue(AS_JSON, ObjectNode.class); + ObjectNode actObj = mapper.readValue(toJSON(buildTestModel()), ObjectNode.class); + assertEquals(expObj, actObj); + } catch(Exception e) { + assertEquals(AS_JSON, toJSON(buildTestModel())); + } + } + + public void testFromJSON() throws Exception { + checkModel(fromJSON(AS_JSON)); + } +} + http://git-wip-us.apache.org/repos/asf/hbase/blob/052a6f07/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestRowModel.java ---------------------------------------------------------------------- diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestRowModel.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestRowModel.java new file mode 100644 index 0000000..e0068c8 --- /dev/null +++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/model/TestRowModel.java @@ -0,0 +1,79 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hbase.rest.model; + +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Iterator; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + +import org.apache.hadoop.hbase.SmallTests; +import org.apache.hadoop.hbase.util.Bytes; + +import junit.framework.TestCase; +import org.junit.experimental.categories.Category; + +@Category(SmallTests.class) +public class TestRowModel extends TestModelBase<RowModel> { + + private static final byte[] ROW1 = Bytes.toBytes("testrow1"); + private static final byte[] COLUMN1 = Bytes.toBytes("testcolumn1"); + private static final byte[] VALUE1 = Bytes.toBytes("testvalue1"); + private static final long TIMESTAMP1 = 1245219839331L; + + private JAXBContext context; + + public TestRowModel() throws Exception { + super(RowModel.class); + AS_XML = + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Row key=\"dGVzdHJvdzE=\">" + + "<Cell column=\"dGVzdGNvbHVtbjE=\" timestamp=\"1245219839331\">dGVzdHZhbHVlMQ==</Cell></Row>"; + + AS_JSON = + "{\"key\":\"dGVzdHJvdzE=\",\"Cell\":[{\"column\":\"dGVzdGNvbHVtbjE=\"," + + "\"timestamp\":1245219839331,\"$\":\"dGVzdHZhbHVlMQ==\"}]}"; + } + + protected RowModel buildTestModel() { + RowModel model = new RowModel(); + model.setKey(ROW1); + model.addCell(new CellModel(COLUMN1, TIMESTAMP1, VALUE1)); + return model; + } + + protected void checkModel(RowModel model) { + assertTrue(Bytes.equals(ROW1, model.getKey())); + Iterator<CellModel> cells = model.getCells().iterator(); + CellModel cell = cells.next(); + assertTrue(Bytes.equals(COLUMN1, cell.getColumn())); + assertTrue(Bytes.equals(VALUE1, cell.getValue())); + assertTrue(cell.hasUserTimestamp()); + assertEquals(cell.getTimestamp(), TIMESTAMP1); + assertFalse(cells.hasNext()); + } + + @Override + public void testFromPB() throws Exception { + //do nothing row model has no PB + } +} +
