1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.coprocessor;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertTrue;
23
24 import java.util.Collections;
25 import java.util.Map;
26 import java.util.TreeMap;
27
28 import org.apache.hadoop.hbase.client.Admin;
29 import org.apache.hadoop.hbase.client.Table;
30 import org.apache.hadoop.hbase.util.ByteStringer;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.hadoop.conf.Configuration;
34 import org.apache.hadoop.hbase.HBaseTestingUtility;
35 import org.apache.hadoop.hbase.HColumnDescriptor;
36 import org.apache.hadoop.hbase.HTableDescriptor;
37 import org.apache.hadoop.hbase.testclassification.MediumTests;
38 import org.apache.hadoop.hbase.TableName;
39 import org.apache.hadoop.hbase.client.HBaseAdmin;
40 import org.apache.hadoop.hbase.client.HTable;
41 import org.apache.hadoop.hbase.client.Put;
42 import org.apache.hadoop.hbase.client.coprocessor.Batch;
43 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ColumnAggregationProtos;
44 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ColumnAggregationProtos.SumResponse;
45 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ColumnAggregationWithErrorsProtos;
46 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ColumnAggregationWithErrorsProtos.ColumnAggregationWithErrorsSumRequest;
47 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ColumnAggregationWithErrorsProtos.ColumnAggregationWithErrorsSumResponse;
48 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ColumnAggregationWithNullResponseProtos;
49 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ColumnAggregationWithNullResponseProtos.ColumnAggregationServiceNullResponse;
50 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ColumnAggregationWithNullResponseProtos.ColumnAggregationNullResponseSumRequest;
51 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ColumnAggregationWithNullResponseProtos.ColumnAggregationNullResponseSumResponse;
52 import org.apache.hadoop.hbase.util.Bytes;
53 import org.junit.AfterClass;
54 import org.junit.BeforeClass;
55 import org.junit.Test;
56 import org.junit.experimental.categories.Category;
57
58 import com.google.protobuf.ServiceException;
59
60
61
62
63 @Category(MediumTests.class)
64 public class TestBatchCoprocessorEndpoint {
65 private static final Log LOG = LogFactory.getLog(TestBatchCoprocessorEndpoint.class);
66
67 private static final TableName TEST_TABLE =
68 TableName.valueOf("TestTable");
69 private static final byte[] TEST_FAMILY = Bytes.toBytes("TestFamily");
70 private static final byte[] TEST_QUALIFIER = Bytes.toBytes("TestQualifier");
71 private static byte[] ROW = Bytes.toBytes("testRow");
72
73 private static final int ROWSIZE = 20;
74 private static final int rowSeperator1 = 5;
75 private static final int rowSeperator2 = 12;
76 private static byte[][] ROWS = makeN(ROW, ROWSIZE);
77
78 private static HBaseTestingUtility util = new HBaseTestingUtility();
79
80 @BeforeClass
81 public static void setupBeforeClass() throws Exception {
82
83 Configuration conf = util.getConfiguration();
84 conf.setStrings(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
85 org.apache.hadoop.hbase.coprocessor.ColumnAggregationEndpoint.class.getName(),
86 ProtobufCoprocessorService.class.getName(),
87 ColumnAggregationEndpointWithErrors.class.getName(),
88 ColumnAggregationEndpointNullResponse.class.getName());
89 conf.setStrings(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
90 ProtobufCoprocessorService.class.getName());
91 util.startMiniCluster(2);
92 Admin admin = new HBaseAdmin(conf);
93 HTableDescriptor desc = new HTableDescriptor(TEST_TABLE);
94 desc.addFamily(new HColumnDescriptor(TEST_FAMILY));
95 admin.createTable(desc, new byte[][]{ROWS[rowSeperator1], ROWS[rowSeperator2]});
96 util.waitUntilAllRegionsAssigned(TEST_TABLE);
97 admin.close();
98
99 Table table = new HTable(conf, TEST_TABLE);
100 for (int i = 0; i < ROWSIZE; i++) {
101 Put put = new Put(ROWS[i]);
102 put.add(TEST_FAMILY, TEST_QUALIFIER, Bytes.toBytes(i));
103 table.put(put);
104 }
105 table.close();
106 }
107
108 @AfterClass
109 public static void tearDownAfterClass() throws Exception {
110 util.shutdownMiniCluster();
111 }
112
113 @Test
114 public void testAggregationNullResponse() throws Throwable {
115 Table table = new HTable(util.getConfiguration(), TEST_TABLE);
116 ColumnAggregationNullResponseSumRequest.Builder builder =
117 ColumnAggregationNullResponseSumRequest
118 .newBuilder();
119 builder.setFamily(ByteStringer.wrap(TEST_FAMILY));
120 if (TEST_QUALIFIER != null && TEST_QUALIFIER.length > 0) {
121 builder.setQualifier(ByteStringer.wrap(TEST_QUALIFIER));
122 }
123 Map<byte[], ColumnAggregationNullResponseSumResponse> results =
124 table.batchCoprocessorService(
125 ColumnAggregationServiceNullResponse.getDescriptor().findMethodByName("sum"),
126 builder.build(), ROWS[0], ROWS[ROWS.length - 1],
127 ColumnAggregationNullResponseSumResponse.getDefaultInstance());
128
129 int sumResult = 0;
130 int expectedResult = 0;
131 for (Map.Entry<byte[], ColumnAggregationNullResponseSumResponse> e :
132 results.entrySet()) {
133 LOG.info("Got value " + e.getValue().getSum() + " for region "
134 + Bytes.toStringBinary(e.getKey()));
135 sumResult += e.getValue().getSum();
136 }
137 for (int i = 0; i < rowSeperator2; i++) {
138 expectedResult += i;
139 }
140 assertEquals("Invalid result", expectedResult, sumResult);
141 table.close();
142 }
143
144 private static byte[][] makeN(byte[] base, int n) {
145 byte[][] ret = new byte[n][];
146 for (int i = 0; i < n; i++) {
147 ret[i] = Bytes.add(base, Bytes.toBytes(String.format("%02d", i)));
148 }
149 return ret;
150 }
151
152 private Map<byte[], SumResponse> sum(final Table table, final byte[] family,
153 final byte[] qualifier, final byte[] start, final byte[] end) throws ServiceException,
154 Throwable {
155 ColumnAggregationProtos.SumRequest.Builder builder = ColumnAggregationProtos.SumRequest
156 .newBuilder();
157 builder.setFamily(ByteStringer.wrap(family));
158 if (qualifier != null && qualifier.length > 0) {
159 builder.setQualifier(ByteStringer.wrap(qualifier));
160 }
161 return table.batchCoprocessorService(
162 ColumnAggregationProtos.ColumnAggregationService.getDescriptor().findMethodByName("sum"),
163 builder.build(), start, end, ColumnAggregationProtos.SumResponse.getDefaultInstance());
164 }
165
166 @Test
167 public void testAggregationWithReturnValue() throws Throwable {
168 Table table = new HTable(util.getConfiguration(), TEST_TABLE);
169 Map<byte[], SumResponse> results = sum(table, TEST_FAMILY, TEST_QUALIFIER, ROWS[0],
170 ROWS[ROWS.length - 1]);
171 int sumResult = 0;
172 int expectedResult = 0;
173 for (Map.Entry<byte[], SumResponse> e : results.entrySet()) {
174 LOG.info("Got value " + e.getValue().getSum() + " for region "
175 + Bytes.toStringBinary(e.getKey()));
176 sumResult += e.getValue().getSum();
177 }
178 for (int i = 0; i < ROWSIZE; i++) {
179 expectedResult += i;
180 }
181 assertEquals("Invalid result", expectedResult, sumResult);
182
183 results.clear();
184
185
186 results = sum(table, TEST_FAMILY, TEST_QUALIFIER, ROWS[rowSeperator1],
187 ROWS[ROWS.length - 1]);
188 sumResult = 0;
189 expectedResult = 0;
190 for (Map.Entry<byte[], SumResponse> e : results.entrySet()) {
191 LOG.info("Got value " + e.getValue().getSum() + " for region "
192 + Bytes.toStringBinary(e.getKey()));
193 sumResult += e.getValue().getSum();
194 }
195 for (int i = rowSeperator1; i < ROWSIZE; i++) {
196 expectedResult += i;
197 }
198 assertEquals("Invalid result", expectedResult, sumResult);
199 table.close();
200 }
201
202 @Test
203 public void testAggregation() throws Throwable {
204 Table table = new HTable(util.getConfiguration(), TEST_TABLE);
205 Map<byte[], SumResponse> results = sum(table, TEST_FAMILY, TEST_QUALIFIER,
206 ROWS[0], ROWS[ROWS.length - 1]);
207 int sumResult = 0;
208 int expectedResult = 0;
209 for (Map.Entry<byte[], SumResponse> e : results.entrySet()) {
210 LOG.info("Got value " + e.getValue().getSum() + " for region "
211 + Bytes.toStringBinary(e.getKey()));
212 sumResult += e.getValue().getSum();
213 }
214 for (int i = 0; i < ROWSIZE; i++) {
215 expectedResult += i;
216 }
217 assertEquals("Invalid result", expectedResult, sumResult);
218
219
220 results = sum(table, TEST_FAMILY, TEST_QUALIFIER, ROWS[rowSeperator1], ROWS[ROWS.length - 1]);
221 sumResult = 0;
222 expectedResult = 0;
223 for (Map.Entry<byte[], SumResponse> e : results.entrySet()) {
224 LOG.info("Got value " + e.getValue().getSum() + " for region "
225 + Bytes.toStringBinary(e.getKey()));
226 sumResult += e.getValue().getSum();
227 }
228 for (int i = rowSeperator1; i < ROWSIZE; i++) {
229 expectedResult += i;
230 }
231 assertEquals("Invalid result", expectedResult, sumResult);
232 table.close();
233 }
234
235 @Test
236 public void testAggregationWithErrors() throws Throwable {
237 Table table = new HTable(util.getConfiguration(), TEST_TABLE);
238 final Map<byte[], ColumnAggregationWithErrorsSumResponse> results =
239 Collections.synchronizedMap(
240 new TreeMap<byte[], ColumnAggregationWithErrorsSumResponse>(
241 Bytes.BYTES_COMPARATOR
242 ));
243 ColumnAggregationWithErrorsSumRequest.Builder builder =
244 ColumnAggregationWithErrorsSumRequest
245 .newBuilder();
246 builder.setFamily(ByteStringer.wrap(TEST_FAMILY));
247 if (TEST_QUALIFIER != null && TEST_QUALIFIER.length > 0) {
248 builder.setQualifier(ByteStringer.wrap(TEST_QUALIFIER));
249 }
250
251 boolean hasError = false;
252 try {
253 table.batchCoprocessorService(
254 ColumnAggregationWithErrorsProtos.ColumnAggregationServiceWithErrors.getDescriptor()
255 .findMethodByName("sum"),
256 builder.build(), ROWS[0], ROWS[ROWS.length - 1],
257 ColumnAggregationWithErrorsSumResponse.getDefaultInstance(),
258 new Batch.Callback<ColumnAggregationWithErrorsSumResponse>() {
259
260 @Override
261 public void update(byte[] region, byte[] row,
262 ColumnAggregationWithErrorsSumResponse result) {
263 results.put(region, result);
264 }
265 });
266 } catch (Throwable t) {
267 LOG.info("Exceptions in coprocessor service", t);
268 hasError = true;
269 }
270
271 int sumResult = 0;
272 int expectedResult = 0;
273 for (Map.Entry<byte[], ColumnAggregationWithErrorsSumResponse> e : results.entrySet()) {
274 LOG.info("Got value " + e.getValue().getSum() + " for region "
275 + Bytes.toStringBinary(e.getKey()));
276 sumResult += e.getValue().getSum();
277 }
278 for (int i = 0; i < rowSeperator2; i++) {
279 expectedResult += i;
280 }
281 assertEquals("Invalid result", expectedResult, sumResult);
282 assertTrue(hasError);
283 table.close();
284 }
285 }