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.client; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023import static org.junit.Assert.fail; 024 025import java.io.File; 026import java.io.FileOutputStream; 027import java.io.IOException; 028import java.lang.reflect.InvocationTargetException; 029import java.nio.ByteBuffer; 030import java.util.Arrays; 031import java.util.Base64; 032import java.util.List; 033import java.util.Set; 034import org.apache.hadoop.conf.Configuration; 035import org.apache.hadoop.hbase.HBaseClassTestRule; 036import org.apache.hadoop.hbase.HBaseConfiguration; 037import org.apache.hadoop.hbase.exceptions.DeserializationException; 038import org.apache.hadoop.hbase.filter.Filter; 039import org.apache.hadoop.hbase.filter.FilterList; 040import org.apache.hadoop.hbase.filter.KeyOnlyFilter; 041import org.apache.hadoop.hbase.security.access.Permission; 042import org.apache.hadoop.hbase.security.visibility.Authorizations; 043import org.apache.hadoop.hbase.testclassification.ClientTests; 044import org.apache.hadoop.hbase.testclassification.SmallTests; 045import org.apache.hadoop.hbase.util.Bytes; 046import org.junit.Assert; 047import org.junit.ClassRule; 048import org.junit.Test; 049import org.junit.experimental.categories.Category; 050 051import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 052import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos; 053 054// TODO: cover more test cases 055@Category({ClientTests.class, SmallTests.class}) 056public class TestGet { 057 @ClassRule 058 public static final HBaseClassTestRule CLASS_RULE = 059 HBaseClassTestRule.forClass(TestGet.class); 060 061 private static final byte [] ROW = new byte [] {'r'}; 062 063 private static final String PB_GET = "CgNyb3ciEwoPdGVzdC5Nb2NrRmlsdGVyEgAwATgB"; 064 private static final String PB_GET_WITH_FILTER_LIST = 065 "CgFyIosBCilvcmcuYXBhY2hlLmhhZG9vcC5oYmFzZS5maWx0ZXIuRmlsdGVyTGlzdBJeCAESEwoP" + 066 "dGVzdC5Nb2NrRmlsdGVyEgASEQoNbXkuTW9ja0ZpbHRlchIAEjIKLG9yZy5hcGFjaGUuaGFkb29w" + 067 "LmhiYXNlLmZpbHRlci5LZXlPbmx5RmlsdGVyEgIIADABOAE="; 068 069 private static final String MOCK_FILTER_JAR = 070 "UEsDBBQACAgIANWDlEMAAAAAAAAAAAAAAAAJAAQATUVUQS1JTkYv/soAAAMAUEsHCAAAAAACAAAA" + 071 "AAAAAFBLAwQUAAgICADVg5RDAAAAAAAAAAAAAAAAFAAAAE1FVEEtSU5GL01BTklGRVNULk1G803M" + 072 "y0xLLS7RDUstKs7Mz7NSMNQz4OVyLkpNLElN0XWqBAmY6xnEG1gqaPgXJSbnpCo45xcV5BcllgCV" + 073 "a/Jy8XIBAFBLBwgxyqRbQwAAAEQAAABQSwMEFAAICAgAUoOUQwAAAAAAAAAAAAAAABMAAABteS9N" + 074 "b2NrRmlsdGVyLmNsYXNzdZHPTsJAEMa/LYVCRVFQMd68gQc38YrxUJUTetGQGE7bstrVwjbbYsSn" + 075 "0hOJJj6AD2WcFoP/4iYzX+bb32xmd9/en18B7GPLhY11BxsurEw3GUoHaqzSQ4ZCq91nsI/0UDLU" + 076 "emoszyYjX5oL4Ufk1Hs6EFFfGJXVn6adhirJ6NGUn+rgtquiVJoOQyUWJpFdo0cMjdbAa/8hnNj3" + 077 "pqmkbmvgMbgn94GMU6XHiYMm1ed6YgJJeDbNV+fejbgTVRRRYlj+cSZDW5trLmIRhJKHYqh1zENf" + 078 "JJJf5QCfcx45DJ3/WLmYgx/LRNJ1I/UgMmMxIXbo9WxkywLLZqHsUMVJGWlxdwb2lG+XKZdys4kK" + 079 "5eocgIsl0grVy0Q5+e9Y+V75BdblDIXHX/3b3/rLWEGNdJXCJmeNop7zjQ9QSwcI1kzyMToBAADs" + 080 "AQAAUEsDBBQACAgIAFKDlEMAAAAAAAAAAAAAAAAVAAAAdGVzdC9Nb2NrRmlsdGVyLmNsYXNzdVHB" + 081 "TsJAFJwthUJFERQx3ryBBzfxivFQlRN60ZAYTtuy2tXCNtti1K/SE4kmfoAfZXwtBg3RTd6bzOy8" + 082 "zezux+frO4ADbLuwsemg6cLKcIuhdKgmKj1iKLQ7Awb7WI8kQ62vJvJ8OvaluRR+REqjrwMRDYRR" + 083 "Gf8W7TRUCUO9n8ok5Wc6uOupKJWmy1CJhUlkz+gxQ7M99Dp/eJzY9x5JZrCGHoN7+hDIOFV6kjho" + 084 "Eb/QUxNIsmeJfib3b8W9qKKIEslLpzJ0tLnhIhZBKHkoRlrHPPRFIvl1buBzn0cKQ/c/r1wk4Scy" + 085 "kXTpSD2JTFhkxC69oY1sWWBZGuoOMU7ICIt7M7CXfLtMvZSLLVSoV+cGuFghrBBfJZeT/5GV75Xf" + 086 "YF3NUHhemt/5NV/GGmqE61Q2KXWqRu7f+AJQSwcIrS5nKDoBAADyAQAAUEsBAhQAFAAICAgA1YOU" + 087 "QwAAAAACAAAAAAAAAAkABAAAAAAAAAAAAAAAAAAAAE1FVEEtSU5GL/7KAABQSwECFAAUAAgICADV" + 088 "g5RDMcqkW0MAAABEAAAAFAAAAAAAAAAAAAAAAAA9AAAATUVUQS1JTkYvTUFOSUZFU1QuTUZQSwEC" + 089 "FAAUAAgICABSg5RD1kzyMToBAADsAQAAEwAAAAAAAAAAAAAAAADCAAAAbXkvTW9ja0ZpbHRlci5j" + 090 "bGFzc1BLAQIUABQACAgIAFKDlEOtLmcoOgEAAPIBAAAVAAAAAAAAAAAAAAAAAD0CAAB0ZXN0L01v" + 091 "Y2tGaWx0ZXIuY2xhc3NQSwUGAAAAAAQABAABAQAAugMAAAAA"; 092 093 @Test 094 public void testAttributesSerialization() throws IOException { 095 Get get = new Get(Bytes.toBytes("row")); 096 get.setAttribute("attribute1", Bytes.toBytes("value1")); 097 get.setAttribute("attribute2", Bytes.toBytes("value2")); 098 get.setAttribute("attribute3", Bytes.toBytes("value3")); 099 100 ClientProtos.Get getProto = ProtobufUtil.toGet(get); 101 102 Get get2 = ProtobufUtil.toGet(getProto); 103 Assert.assertNull(get2.getAttribute("absent")); 104 Assert.assertTrue(Arrays.equals(Bytes.toBytes("value1"), get2.getAttribute("attribute1"))); 105 Assert.assertTrue(Arrays.equals(Bytes.toBytes("value2"), get2.getAttribute("attribute2"))); 106 Assert.assertTrue(Arrays.equals(Bytes.toBytes("value3"), get2.getAttribute("attribute3"))); 107 Assert.assertEquals(3, get2.getAttributesMap().size()); 108 } 109 110 @Test 111 public void testGetAttributes() { 112 Get get = new Get(ROW); 113 Assert.assertTrue(get.getAttributesMap().isEmpty()); 114 Assert.assertNull(get.getAttribute("absent")); 115 116 get.setAttribute("absent", null); 117 Assert.assertTrue(get.getAttributesMap().isEmpty()); 118 Assert.assertNull(get.getAttribute("absent")); 119 120 // adding attribute 121 get.setAttribute("attribute1", Bytes.toBytes("value1")); 122 Assert.assertTrue(Arrays.equals(Bytes.toBytes("value1"), get.getAttribute("attribute1"))); 123 Assert.assertEquals(1, get.getAttributesMap().size()); 124 Assert.assertTrue(Arrays.equals(Bytes.toBytes("value1"), 125 get.getAttributesMap().get("attribute1"))); 126 127 // overriding attribute value 128 get.setAttribute("attribute1", Bytes.toBytes("value12")); 129 Assert.assertTrue(Arrays.equals(Bytes.toBytes("value12"), get.getAttribute("attribute1"))); 130 Assert.assertEquals(1, get.getAttributesMap().size()); 131 Assert.assertTrue(Arrays.equals(Bytes.toBytes("value12"), 132 get.getAttributesMap().get("attribute1"))); 133 134 // adding another attribute 135 get.setAttribute("attribute2", Bytes.toBytes("value2")); 136 Assert.assertTrue(Arrays.equals(Bytes.toBytes("value2"), get.getAttribute("attribute2"))); 137 Assert.assertEquals(2, get.getAttributesMap().size()); 138 Assert.assertTrue(Arrays.equals(Bytes.toBytes("value2"), 139 get.getAttributesMap().get("attribute2"))); 140 141 // removing attribute 142 get.setAttribute("attribute2", null); 143 Assert.assertNull(get.getAttribute("attribute2")); 144 Assert.assertEquals(1, get.getAttributesMap().size()); 145 Assert.assertNull(get.getAttributesMap().get("attribute2")); 146 147 // removing non-existed attribute 148 get.setAttribute("attribute2", null); 149 Assert.assertNull(get.getAttribute("attribute2")); 150 Assert.assertEquals(1, get.getAttributesMap().size()); 151 Assert.assertNull(get.getAttributesMap().get("attribute2")); 152 153 // removing another attribute 154 get.setAttribute("attribute1", null); 155 Assert.assertNull(get.getAttribute("attribute1")); 156 Assert.assertTrue(get.getAttributesMap().isEmpty()); 157 Assert.assertNull(get.getAttributesMap().get("attribute1")); 158 } 159 160 @Test 161 public void testNullQualifier() { 162 Get get = new Get(ROW); 163 byte[] family = Bytes.toBytes("family"); 164 get.addColumn(family, null); 165 Set<byte[]> qualifiers = get.getFamilyMap().get(family); 166 Assert.assertEquals(1, qualifiers.size()); 167 } 168 169 @Test 170 public void TestGetRowFromGetCopyConstructor() throws Exception { 171 Get get = new Get(ROW); 172 get.setFilter(null); 173 get.setAuthorizations(new Authorizations("foo")); 174 get.setACL("u", new Permission(Permission.Action.READ)); 175 get.setConsistency(Consistency.TIMELINE); 176 get.setReplicaId(2); 177 get.setIsolationLevel(IsolationLevel.READ_UNCOMMITTED); 178 get.setCheckExistenceOnly(true); 179 get.setTimeRange(3, 4); 180 get.setMaxVersions(11); 181 get.setMaxResultsPerColumnFamily(10); 182 get.setRowOffsetPerColumnFamily(11); 183 get.setCacheBlocks(true); 184 185 Get copyGet = new Get(get); 186 assertEquals(0, Bytes.compareTo(get.getRow(), copyGet.getRow())); 187 188 // from OperationWithAttributes 189 assertEquals(get.getId(), copyGet.getId()); 190 191 // from Query class 192 assertEquals(get.getFilter(), copyGet.getFilter()); 193 assertTrue(get.getAuthorizations().toString().equals(copyGet.getAuthorizations().toString())); 194 assertTrue(Bytes.equals(get.getACL(), copyGet.getACL())); 195 assertEquals(get.getConsistency(), copyGet.getConsistency()); 196 assertEquals(get.getReplicaId(), copyGet.getReplicaId()); 197 assertEquals(get.getIsolationLevel(), copyGet.getIsolationLevel()); 198 199 // from Get class 200 assertEquals(get.isCheckExistenceOnly(), copyGet.isCheckExistenceOnly()); 201 assertTrue(get.getTimeRange().equals(copyGet.getTimeRange())); 202 assertEquals(get.getMaxVersions(), copyGet.getMaxVersions()); 203 assertEquals(get.getMaxResultsPerColumnFamily(), copyGet.getMaxResultsPerColumnFamily()); 204 assertEquals(get.getRowOffsetPerColumnFamily(), copyGet.getRowOffsetPerColumnFamily()); 205 assertEquals(get.getCacheBlocks(), copyGet.getCacheBlocks()); 206 assertEquals(get.getId(), copyGet.getId()); 207 } 208 209 @Test 210 public void testDynamicFilter() throws Exception { 211 Configuration conf = HBaseConfiguration.create(); 212 String localPath = conf.get("hbase.local.dir") 213 + File.separator + "jars" + File.separator; 214 File jarFile = new File(localPath, "MockFilter.jar"); 215 jarFile.delete(); 216 assertFalse("Should be deleted: " + jarFile.getPath(), jarFile.exists()); 217 218 ClientProtos.Get getProto1 = 219 ClientProtos.Get.parseFrom(Base64.getDecoder().decode(PB_GET)); 220 ClientProtos.Get getProto2 = 221 ClientProtos.Get.parseFrom(Base64.getDecoder().decode(PB_GET_WITH_FILTER_LIST)); 222 try { 223 ProtobufUtil.toGet(getProto1); 224 fail("Should not be able to load the filter class"); 225 } catch (IOException ioe) { 226 assertTrue(ioe.getCause() instanceof ClassNotFoundException); 227 } 228 try { 229 ProtobufUtil.toGet(getProto2); 230 fail("Should not be able to load the filter class"); 231 } catch (IOException ioe) { 232 assertTrue(ioe.getCause() instanceof InvocationTargetException); 233 InvocationTargetException ite = (InvocationTargetException)ioe.getCause(); 234 assertTrue(ite.getTargetException() 235 instanceof DeserializationException); 236 } 237 FileOutputStream fos = new FileOutputStream(jarFile); 238 fos.write(Base64.getDecoder().decode(MOCK_FILTER_JAR)); 239 fos.close(); 240 241 Get get1 = ProtobufUtil.toGet(getProto1); 242 assertEquals("test.MockFilter", get1.getFilter().getClass().getName()); 243 244 Get get2 = ProtobufUtil.toGet(getProto2); 245 assertTrue(get2.getFilter() instanceof FilterList); 246 List<Filter> filters = ((FilterList)get2.getFilter()).getFilters(); 247 assertEquals(3, filters.size()); 248 assertEquals("test.MockFilter", filters.get(0).getClass().getName()); 249 assertEquals("my.MockFilter", filters.get(1).getClass().getName()); 250 assertTrue(filters.get(2) instanceof KeyOnlyFilter); 251 } 252 253 @Test 254 public void testGetRowConstructor() { 255 byte[] row1 = Bytes.toBytes("testRow"); 256 byte[] row2 = Bytes.toBytes("testtestRow"); 257 ByteBuffer rowBuffer = ByteBuffer.allocate(16); 258 rowBuffer = ByteBuffer.wrap(row1); 259 Get get1 = new Get(rowBuffer); 260 Get get2 = new Get(row2, 4, 7); 261 Assert.assertArrayEquals(get1.getRow(), get2.getRow()); 262 } 263}