View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.coprocessor;
20  
21  import static org.junit.Assert.assertEquals;
22  
23  import java.io.IOException;
24  import java.util.Map;
25  
26  import org.apache.hadoop.hbase.client.HBaseAdmin;
27  import org.apache.hadoop.hbase.client.HTable;
28  import org.apache.hadoop.hbase.testclassification.MediumTests;
29  import org.apache.hadoop.hbase.util.ByteStringer;
30  import org.apache.hadoop.hbase.HBaseTestingUtility;
31  import org.apache.hadoop.hbase.HColumnDescriptor;
32  import org.apache.hadoop.hbase.HTableDescriptor;
33  import org.apache.hadoop.hbase.TableName;
34  import org.apache.hadoop.hbase.client.Put;
35  import org.apache.hadoop.hbase.client.coprocessor.Batch;
36  import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ColumnAggregationProtos;
37  import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
38  import org.apache.hadoop.hbase.util.Bytes;
39  import org.junit.AfterClass;
40  import org.junit.BeforeClass;
41  import org.junit.Test;
42  import org.junit.experimental.categories.Category;
43  
44  import com.google.protobuf.ServiceException;
45  
46  @Category(MediumTests.class)
47  public class TestCoprocessorTableEndpoint {
48  
49    private static final byte[] TEST_FAMILY = Bytes.toBytes("TestFamily");
50    private static final byte[] TEST_QUALIFIER = Bytes.toBytes("TestQualifier");
51    private static final byte[] ROW = Bytes.toBytes("testRow");
52    private static final int ROWSIZE = 20;
53    private static final int rowSeperator1 = 5;
54    private static final int rowSeperator2 = 12;
55    private static final byte[][] ROWS = makeN(ROW, ROWSIZE);
56  
57    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
58  
59    @BeforeClass
60    public static void setupBeforeClass() throws Exception {
61      TEST_UTIL.startMiniCluster(2);
62    }
63  
64    @AfterClass
65    public static void tearDownAfterClass() throws Exception {
66      TEST_UTIL.shutdownMiniCluster();
67    }
68  
69    @Test
70    public void testCoprocessorTableEndpoint() throws Throwable {    
71      final TableName tableName = TableName.valueOf("testCoprocessorTableEndpoint");
72  
73      HTableDescriptor desc = new HTableDescriptor(tableName);
74      desc.addFamily(new HColumnDescriptor(TEST_FAMILY));
75      desc.addCoprocessor(org.apache.hadoop.hbase.coprocessor.ColumnAggregationEndpoint.class.getName());
76  
77      createTable(desc);
78      verifyTable(tableName);
79    }
80  
81    @Test
82    public void testDynamicCoprocessorTableEndpoint() throws Throwable {    
83      final TableName tableName = TableName.valueOf("testDynamicCoprocessorTableEndpoint");
84  
85      HTableDescriptor desc = new HTableDescriptor(tableName);
86      desc.addFamily(new HColumnDescriptor(TEST_FAMILY));
87  
88      createTable(desc);
89  
90      desc.addCoprocessor(org.apache.hadoop.hbase.coprocessor.ColumnAggregationEndpoint.class.getName());
91      updateTable(desc);
92  
93      verifyTable(tableName);
94    }
95  
96    private static byte[][] makeN(byte[] base, int n) {
97      byte[][] ret = new byte[n][];
98      for (int i = 0; i < n; i++) {
99        ret[i] = Bytes.add(base, Bytes.toBytes(String.format("%02d", i)));
100     }
101     return ret;
102   }
103 
104   private static Map<byte [], Long> sum(final HTable table, final byte [] family,
105     final byte [] qualifier, final byte [] start, final byte [] end)
106       throws ServiceException, Throwable {
107   return table.coprocessorService(ColumnAggregationProtos.ColumnAggregationService.class,
108       start, end,
109     new Batch.Call<ColumnAggregationProtos.ColumnAggregationService, Long>() {
110       @Override
111       public Long call(ColumnAggregationProtos.ColumnAggregationService instance)
112       throws IOException {
113         BlockingRpcCallback<ColumnAggregationProtos.SumResponse> rpcCallback =
114             new BlockingRpcCallback<ColumnAggregationProtos.SumResponse>();
115         ColumnAggregationProtos.SumRequest.Builder builder =
116           ColumnAggregationProtos.SumRequest.newBuilder();
117         builder.setFamily(ByteStringer.wrap(family));
118         if (qualifier != null && qualifier.length > 0) {
119           builder.setQualifier(ByteStringer.wrap(qualifier));
120         }
121         instance.sum(null, builder.build(), rpcCallback);
122         return rpcCallback.get().getSum();
123       }
124     });
125   }
126 
127   private static final void createTable(HTableDescriptor desc) throws Exception {
128     HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
129     admin.createTable(desc, new byte[][]{ROWS[rowSeperator1], ROWS[rowSeperator2]});
130     TEST_UTIL.waitUntilAllRegionsAssigned(desc.getTableName());
131     HTable table = new HTable(TEST_UTIL.getConfiguration(), desc.getTableName());
132     try {
133       for (int i = 0; i < ROWSIZE; i++) {
134         Put put = new Put(ROWS[i]);
135         put.add(TEST_FAMILY, TEST_QUALIFIER, Bytes.toBytes(i));
136         table.put(put);
137       }
138     } finally {
139       table.close();    
140     }
141   }
142 
143   private static void updateTable(HTableDescriptor desc) throws Exception {
144     HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
145     admin.disableTable(desc.getTableName());
146     admin.modifyTable(desc.getTableName(), desc);
147     admin.enableTable(desc.getTableName());
148   }
149 
150   private static final void verifyTable(TableName tableName) throws Throwable {
151     HTable table = new HTable(TEST_UTIL.getConfiguration(), tableName);
152     try {
153       Map<byte[], Long> results = sum(table, TEST_FAMILY, TEST_QUALIFIER, ROWS[0],
154         ROWS[ROWS.length-1]);
155       int sumResult = 0;
156       int expectedResult = 0;
157       for (Map.Entry<byte[], Long> e : results.entrySet()) {
158         sumResult += e.getValue();
159       }
160       for (int i = 0; i < ROWSIZE; i++) {
161         expectedResult += i;
162       }
163       assertEquals("Invalid result", expectedResult, sumResult);
164 
165       // scan: for region 2 and region 3
166       results.clear();
167       results = sum(table, TEST_FAMILY, TEST_QUALIFIER, ROWS[rowSeperator1], ROWS[ROWS.length-1]);
168       sumResult = 0;
169       expectedResult = 0;
170       for (Map.Entry<byte[], Long> e : results.entrySet()) {
171         sumResult += e.getValue();
172       }
173       for (int i = rowSeperator1; i < ROWSIZE; i++) {
174         expectedResult += i;
175       }
176       assertEquals("Invalid result", expectedResult, sumResult);
177     } finally {
178       table.close();
179     }
180   }
181 }