1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.client;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertTrue;
23
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.List;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.hbase.Cell;
30 import org.apache.hadoop.hbase.CellUtil;
31 import org.apache.hadoop.hbase.DoNotRetryIOException;
32 import org.apache.hadoop.hbase.HBaseTestingUtility;
33 import org.apache.hadoop.hbase.HColumnDescriptor;
34 import org.apache.hadoop.hbase.HConstants;
35 import org.apache.hadoop.hbase.HTableDescriptor;
36 import org.apache.hadoop.hbase.TableName;
37 import org.apache.hadoop.hbase.filter.BinaryComparator;
38 import org.apache.hadoop.hbase.ipc.PayloadCarryingRpcController;
39 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
40 import org.apache.hadoop.hbase.protobuf.RequestConverter;
41 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
42 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
43 import org.apache.hadoop.hbase.regionserver.HRegion;
44 import org.apache.hadoop.hbase.regionserver.HRegionServer;
45 import org.apache.hadoop.hbase.testclassification.ClientTests;
46 import org.apache.hadoop.hbase.testclassification.MediumTests;
47 import org.apache.hadoop.hbase.util.Bytes;
48 import org.junit.After;
49 import org.junit.AfterClass;
50 import org.junit.Before;
51 import org.junit.BeforeClass;
52 import org.junit.Test;
53 import org.junit.experimental.categories.Category;
54 import org.mockito.Mockito;
55
56
57
58
59 @Category({ MediumTests.class, ClientTests.class })
60 public class TestMalformedCellFromClient {
61 private static final Log LOG = LogFactory.getLog(TestMalformedCellFromClient.class);
62 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
63 private static final byte[] FAMILY = Bytes.toBytes("testFamily");
64 private static final TableName TABLE_NAME = TableName.valueOf("TestMalformedCellFromClient");
65
66 @BeforeClass
67 public static void setUpBeforeClass() throws Exception {
68
69 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 1);
70 TEST_UTIL.startMiniCluster(1);
71 }
72
73 @Before
74 public void before() throws Exception {
75 HTableDescriptor desc =
76 new HTableDescriptor(TABLE_NAME).addFamily(new HColumnDescriptor(FAMILY));
77 TEST_UTIL.getConnection().getAdmin().createTable(desc);
78 }
79
80 @After
81 public void tearDown() throws Exception {
82 for (HTableDescriptor htd : TEST_UTIL.getHBaseAdmin().listTables()) {
83 TEST_UTIL.deleteTable(htd.getTableName());
84 }
85 }
86
87 @AfterClass
88 public static void tearDownAfterClass() throws Exception {
89 TEST_UTIL.shutdownMiniCluster();
90 }
91
92
93
94
95
96
97 @Test
98 public void testAtomicOperations() throws Exception {
99 RowMutations rm = new RowMutations(Bytes.toBytes("fail"));
100 rm.add(new Put(rm.getRow()).addColumn(FAMILY, null, new byte[10]));
101 rm.add(new Put(rm.getRow()).addColumn(FAMILY, null, new byte[10]));
102 Put put = new Put(Bytes.toBytes("good")).addColumn(FAMILY, null, new byte[10]);
103
104
105 HRegion r = TEST_UTIL.getMiniHBaseCluster().getRegions(TABLE_NAME).get(0);
106 ClientProtos.MultiRequest request =
107 ClientProtos.MultiRequest.newBuilder(createRequest(rm, r.getRegionInfo().getRegionName()))
108 .addRegionAction(ClientProtos.RegionAction.newBuilder().setRegion(RequestConverter
109 .buildRegionSpecifier(HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME,
110 r.getRegionInfo().getRegionName())).addAction(ClientProtos.Action.newBuilder()
111 .setMutation(
112 ProtobufUtil.toMutationNoData(ClientProtos.MutationProto.MutationType.PUT, put))))
113 .build();
114
115 List<Cell> cells = new ArrayList<>();
116 for (Mutation m : rm.getMutations()) {
117 cells.addAll(m.getCellList(FAMILY));
118 }
119 cells.addAll(put.getCellList(FAMILY));
120 assertEquals(3, cells.size());
121 PayloadCarryingRpcController controller = Mockito.mock(PayloadCarryingRpcController.class);
122 Mockito.when(controller.cellScanner()).thenReturn(CellUtil.createCellScanner(cells));
123 HRegionServer rs = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0);
124 ClientProtos.MultiResponse response = rs.getRSRpcServices().multi(controller, request);
125 assertEquals(2, response.getRegionActionResultCount());
126 assertTrue(response.getRegionActionResultList().get(0).hasException());
127 assertFalse(response.getRegionActionResultList().get(1).hasException());
128 assertEquals(1, response.getRegionActionResultList().get(1).getResultOrExceptionCount());
129 assertTrue(
130 response.getRegionActionResultList().get(1).getResultOrExceptionList().get(0).hasResult());
131 try (Table table = TEST_UTIL.getConnection().getTable(TABLE_NAME)) {
132 Result result = table.get(new Get(Bytes.toBytes("good")));
133 assertEquals(1, result.size());
134 Cell cell = result.getColumnLatestCell(FAMILY, null);
135 assertTrue(Bytes.equals(CellUtil.cloneValue(cell), new byte[10]));
136 }
137 }
138
139 private static ClientProtos.MultiRequest createRequest(RowMutations rm, byte[] regionName)
140 throws IOException {
141 ClientProtos.RegionAction.Builder builder = RequestConverter
142 .getRegionActionBuilderWithRegion(ClientProtos.RegionAction.newBuilder(), regionName);
143 builder.setAtomic(true);
144 ClientProtos.Action.Builder actionBuilder = ClientProtos.Action.newBuilder();
145 ClientProtos.MutationProto.Builder mutationBuilder = ClientProtos.MutationProto.newBuilder();
146 ClientProtos.Condition condition = RequestConverter
147 .buildCondition(rm.getRow(), FAMILY, FAMILY, new BinaryComparator(new byte[10]),
148 HBaseProtos.CompareType.EQUAL);
149 for (Mutation mutation : rm.getMutations()) {
150 ClientProtos.MutationProto.MutationType mutateType = null;
151 if (mutation instanceof Put) {
152 mutateType = ClientProtos.MutationProto.MutationType.PUT;
153 } else if (mutation instanceof Delete) {
154 mutateType = ClientProtos.MutationProto.MutationType.DELETE;
155 } else {
156 throw new DoNotRetryIOException(
157 "RowMutations supports only put and delete, not " + mutation.getClass().getName());
158 }
159 mutationBuilder.clear();
160 ClientProtos.MutationProto mp =
161 ProtobufUtil.toMutationNoData(mutateType, mutation, mutationBuilder);
162 actionBuilder.clear();
163 actionBuilder.setMutation(mp);
164
165 actionBuilder.setGet(ProtobufUtil.toGet(new Get(rm.getRow())));
166 builder.addAction(actionBuilder.build());
167 }
168 ClientProtos.MultiRequest request =
169 ClientProtos.MultiRequest.newBuilder().addRegionAction(builder.build())
170 .setCondition(condition).build();
171 return request;
172 }
173 }