1   /*
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.rest.client;
22  
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.hadoop.hbase.HBaseTestingUtility;
30  import org.apache.hadoop.hbase.HColumnDescriptor;
31  import org.apache.hadoop.hbase.HTableDescriptor;
32  import org.apache.hadoop.hbase.KeyValue;
33  import org.apache.hadoop.hbase.client.Delete;
34  import org.apache.hadoop.hbase.client.Get;
35  import org.apache.hadoop.hbase.client.HBaseAdmin;
36  import org.apache.hadoop.hbase.client.HTable;
37  import org.apache.hadoop.hbase.client.Put;
38  import org.apache.hadoop.hbase.client.Result;
39  import org.apache.hadoop.hbase.client.ResultScanner;
40  import org.apache.hadoop.hbase.client.Scan;
41  import org.apache.hadoop.hbase.rest.HBaseRESTTestingUtility;
42  import org.apache.hadoop.hbase.rest.client.Client;
43  import org.apache.hadoop.hbase.rest.client.Cluster;
44  import org.apache.hadoop.hbase.rest.client.RemoteHTable;
45  import org.apache.hadoop.hbase.util.Bytes;
46  
47  import static org.junit.Assert.*;
48  import org.junit.AfterClass;
49  import org.junit.BeforeClass;
50  import org.junit.Test;
51  
52  public class TestRemoteTable {
53    private static final Log LOG = LogFactory.getLog(TestRemoteTable.class);
54    private static final String TABLE = "TestRemoteTable";
55    private static final byte[] ROW_1 = Bytes.toBytes("testrow1");
56    private static final byte[] ROW_2 = Bytes.toBytes("testrow2");
57    private static final byte[] ROW_3 = Bytes.toBytes("testrow3");
58    private static final byte[] ROW_4 = Bytes.toBytes("testrow4");
59    private static final byte[] COLUMN_1 = Bytes.toBytes("a");
60    private static final byte[] COLUMN_2 = Bytes.toBytes("b");
61    private static final byte[] COLUMN_3 = Bytes.toBytes("c");
62    private static final byte[] QUALIFIER_1 = Bytes.toBytes("1");
63    private static final byte[] QUALIFIER_2 = Bytes.toBytes("2");
64    private static final byte[] VALUE_1 = Bytes.toBytes("testvalue1");
65    private static final byte[] VALUE_2 = Bytes.toBytes("testvalue2");
66  
67    private static final long ONE_HOUR = 60 * 60 * 1000;
68    private static final long TS_2 = System.currentTimeMillis();
69    private static final long TS_1 = TS_2 - ONE_HOUR;
70  
71    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
72    private static final HBaseRESTTestingUtility REST_TEST_UTIL = 
73      new HBaseRESTTestingUtility();
74    private static RemoteHTable remoteTable;
75  
76    @BeforeClass
77    public static void setUpBeforeClass() throws Exception {
78      TEST_UTIL.startMiniCluster(3);
79      REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration());
80      HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
81      LOG.info("Admin Connection=" + admin.getConnection() + ", " + 
82        admin.getConnection().getZooKeeperWatcher());
83      if (!admin.tableExists(TABLE)) {
84        HTableDescriptor htd = new HTableDescriptor(TABLE);
85        htd.addFamily(new HColumnDescriptor(COLUMN_1));
86        htd.addFamily(new HColumnDescriptor(COLUMN_2));
87        htd.addFamily(new HColumnDescriptor(COLUMN_3));
88        admin.createTable(htd);
89        HTable table = new HTable(TEST_UTIL.getConfiguration(), TABLE);
90        LOG.info("Table connection=" + table.getConnection() + ", " +
91          admin.getConnection().getZooKeeperWatcher());
92        Put put = new Put(ROW_1);
93        put.add(COLUMN_1, QUALIFIER_1, TS_2, VALUE_1);
94        table.put(put);
95        put = new Put(ROW_2);
96        put.add(COLUMN_1, QUALIFIER_1, TS_1, VALUE_1);
97        put.add(COLUMN_1, QUALIFIER_1, TS_2, VALUE_2);
98        put.add(COLUMN_2, QUALIFIER_2, TS_2, VALUE_2);
99        table.put(put);
100       table.flushCommits();
101     }
102     remoteTable = new RemoteHTable(
103       new Client(new Cluster().add("localhost", 
104           REST_TEST_UTIL.getServletPort())),
105         TEST_UTIL.getConfiguration(), TABLE, null);
106   }
107 
108   @AfterClass
109   public static void tearDownAfterClass() throws Exception {
110     remoteTable.close();
111     REST_TEST_UTIL.shutdownServletContainer();
112     TEST_UTIL.shutdownMiniCluster();
113   }
114 
115   @Test
116   public void testGetTableDescriptor() throws IOException {
117     HTableDescriptor local = new HTable(TEST_UTIL.getConfiguration(),
118       TABLE).getTableDescriptor();
119     assertEquals(remoteTable.getTableDescriptor(), local);
120   }
121 
122   @Test
123   public void testGet() throws IOException {
124     Get get = new Get(ROW_1);
125     Result result = remoteTable.get(get);
126     byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1);
127     byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2);
128     assertNotNull(value1);
129     assertTrue(Bytes.equals(VALUE_1, value1));
130     assertNull(value2);
131 
132     get = new Get(ROW_1);
133     get.addFamily(COLUMN_3);
134     result = remoteTable.get(get);
135     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
136     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
137     assertNull(value1);
138     assertNull(value2);
139 
140     get = new Get(ROW_1);
141     get.addColumn(COLUMN_1, QUALIFIER_1);
142     get.addColumn(COLUMN_2, QUALIFIER_2);
143     result = remoteTable.get(get);
144     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
145     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
146     assertNotNull(value1);
147     assertTrue(Bytes.equals(VALUE_1, value1));
148     assertNull(value2);
149 
150     get = new Get(ROW_2);
151     result = remoteTable.get(get);    
152     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
153     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
154     assertNotNull(value1);
155     assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
156     assertNotNull(value2);
157     assertTrue(Bytes.equals(VALUE_2, value2));
158 
159     get = new Get(ROW_2);
160     get.addFamily(COLUMN_1);
161     result = remoteTable.get(get);    
162     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
163     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
164     assertNotNull(value1);
165     assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
166     assertNull(value2);
167 
168     get = new Get(ROW_2);
169     get.addColumn(COLUMN_1, QUALIFIER_1);
170     get.addColumn(COLUMN_2, QUALIFIER_2);
171     result = remoteTable.get(get);    
172     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
173     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
174     assertNotNull(value1);
175     assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
176     assertNotNull(value2);
177     assertTrue(Bytes.equals(VALUE_2, value2));
178 
179     // test timestamp
180 
181     get = new Get(ROW_2);
182     get.addFamily(COLUMN_1);
183     get.addFamily(COLUMN_2);
184     get.setTimeStamp(TS_1);
185     result = remoteTable.get(get);    
186     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
187     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
188     assertNotNull(value1);
189     assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1
190     assertNull(value2);
191 
192     // test timerange
193 
194     get = new Get(ROW_2);
195     get.addFamily(COLUMN_1);
196     get.addFamily(COLUMN_2);
197     get.setTimeRange(0, TS_1 + 1);
198     result = remoteTable.get(get);    
199     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
200     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
201     assertNotNull(value1);
202     assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1
203     assertNull(value2);
204 
205     // test maxVersions
206 
207     get = new Get(ROW_2);
208     get.addFamily(COLUMN_1);
209     get.setMaxVersions(2);
210     result = remoteTable.get(get);
211     int count = 0;
212     for (KeyValue kv: result.list()) {
213       if (Bytes.equals(COLUMN_1, kv.getFamily()) && TS_1 == kv.getTimestamp()) {
214         assertTrue(Bytes.equals(VALUE_1, kv.getValue())); // @TS_1
215         count++;
216       }
217       if (Bytes.equals(COLUMN_1, kv.getFamily()) && TS_2 == kv.getTimestamp()) {
218         assertTrue(Bytes.equals(VALUE_2, kv.getValue())); // @TS_2
219         count++;
220       }
221     }
222     assertEquals(2, count);
223   }
224 
225   @Test
226   public void testPut() throws IOException {
227     Put put = new Put(ROW_3);
228     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
229     remoteTable.put(put);
230 
231     Get get = new Get(ROW_3);
232     get.addFamily(COLUMN_1);
233     Result result = remoteTable.get(get);
234     byte[] value = result.getValue(COLUMN_1, QUALIFIER_1);
235     assertNotNull(value);
236     assertTrue(Bytes.equals(VALUE_1, value));
237 
238     // multiput
239 
240     List<Put> puts = new ArrayList<Put>();
241     put = new Put(ROW_3);
242     put.add(COLUMN_2, QUALIFIER_2, VALUE_2);
243     puts.add(put);
244     put = new Put(ROW_4);
245     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
246     puts.add(put);
247     put = new Put(ROW_4);
248     put.add(COLUMN_2, QUALIFIER_2, VALUE_2);
249     puts.add(put);
250     remoteTable.put(puts);
251 
252     get = new Get(ROW_3);
253     get.addFamily(COLUMN_2);
254     result = remoteTable.get(get);
255     value = result.getValue(COLUMN_2, QUALIFIER_2);
256     assertNotNull(value);
257     assertTrue(Bytes.equals(VALUE_2, value));
258     get = new Get(ROW_4);
259     result = remoteTable.get(get);
260     value = result.getValue(COLUMN_1, QUALIFIER_1);
261     assertNotNull(value);
262     assertTrue(Bytes.equals(VALUE_1, value));
263     value = result.getValue(COLUMN_2, QUALIFIER_2);
264     assertNotNull(value);
265     assertTrue(Bytes.equals(VALUE_2, value));
266   }
267 
268   public void testDelete() throws IOException {
269     Put put = new Put(ROW_3);
270     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
271     put.add(COLUMN_2, QUALIFIER_2, VALUE_2);
272     remoteTable.put(put);
273 
274     Get get = new Get(ROW_3);
275     get.addFamily(COLUMN_1);
276     get.addFamily(COLUMN_2);
277     Result result = remoteTable.get(get);
278     byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1);
279     byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2);
280     assertNotNull(value1);
281     assertTrue(Bytes.equals(VALUE_1, value1));
282     assertNotNull(value2);
283     assertTrue(Bytes.equals(VALUE_2, value2));
284 
285     Delete delete = new Delete(ROW_3);
286     delete.deleteColumn(COLUMN_2, QUALIFIER_2);
287     remoteTable.delete(delete);
288     
289     get = new Get(ROW_3);
290     get.addFamily(COLUMN_1);
291     get.addFamily(COLUMN_2);
292     result = remoteTable.get(get);
293     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
294     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
295     assertNotNull(value1);
296     assertTrue(Bytes.equals(VALUE_1, value1));
297     assertNull(value2);
298 
299     delete = new Delete(ROW_3);
300     remoteTable.delete(delete);
301 
302     get = new Get(ROW_3);
303     get.addFamily(COLUMN_1);
304     get.addFamily(COLUMN_2);
305     result = remoteTable.get(get);
306     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
307     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
308     assertNull(value1);
309     assertNull(value2);
310   }
311 
312   public void testScanner() throws IOException {
313     List<Put> puts = new ArrayList<Put>();
314     Put put = new Put(ROW_1);
315     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
316     puts.add(put);
317     put = new Put(ROW_2);
318     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
319     puts.add(put);
320     put = new Put(ROW_3);
321     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
322     puts.add(put);
323     put = new Put(ROW_4);
324     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
325     puts.add(put);
326     remoteTable.put(puts);
327 
328     ResultScanner scanner = remoteTable.getScanner(new Scan());
329 
330     Result[] results = scanner.next(1);
331     assertNotNull(results);
332     assertEquals(1, results.length);
333     assertTrue(Bytes.equals(ROW_1, results[0].getRow()));
334 
335     results = scanner.next(3);
336     assertNotNull(results);
337     assertEquals(3, results.length);
338     assertTrue(Bytes.equals(ROW_2, results[0].getRow()));
339     assertTrue(Bytes.equals(ROW_3, results[1].getRow()));
340     assertTrue(Bytes.equals(ROW_4, results[2].getRow()));
341 
342     results = scanner.next(1);
343     assertNull(results);
344 
345     scanner.close();
346   }
347 }