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.*;
30  import org.apache.hadoop.hbase.client.Delete;
31  import org.apache.hadoop.hbase.client.Get;
32  import org.apache.hadoop.hbase.client.HBaseAdmin;
33  import org.apache.hadoop.hbase.client.HTable;
34  import org.apache.hadoop.hbase.client.Put;
35  import org.apache.hadoop.hbase.client.Result;
36  import org.apache.hadoop.hbase.client.ResultScanner;
37  import org.apache.hadoop.hbase.client.Scan;
38  import org.apache.hadoop.hbase.rest.HBaseRESTTestingUtility;
39  import org.apache.hadoop.hbase.rest.client.Client;
40  import org.apache.hadoop.hbase.rest.client.Cluster;
41  import org.apache.hadoop.hbase.rest.client.RemoteHTable;
42  import org.apache.hadoop.hbase.util.Bytes;
43  
44  import static org.junit.Assert.*;
45  import org.junit.AfterClass;
46  import org.junit.BeforeClass;
47  import org.junit.Test;
48  import org.junit.experimental.categories.Category;
49  
50  @Category(MediumTests.class)
51  public class TestRemoteTable {
52    private static final Log LOG = LogFactory.getLog(TestRemoteTable.class);
53    private static final String TABLE = "TestRemoteTable";
54    private static final byte[] ROW_1 = Bytes.toBytes("testrow1");
55    private static final byte[] ROW_2 = Bytes.toBytes("testrow2");
56    private static final byte[] ROW_3 = Bytes.toBytes("testrow3");
57    private static final byte[] ROW_4 = Bytes.toBytes("testrow4");
58    private static final byte[] COLUMN_1 = Bytes.toBytes("a");
59    private static final byte[] COLUMN_2 = Bytes.toBytes("b");
60    private static final byte[] COLUMN_3 = Bytes.toBytes("c");
61    private static final byte[] QUALIFIER_1 = Bytes.toBytes("1");
62    private static final byte[] QUALIFIER_2 = Bytes.toBytes("2");
63    private static final byte[] VALUE_1 = Bytes.toBytes("testvalue1");
64    private static final byte[] VALUE_2 = Bytes.toBytes("testvalue2");
65  
66    private static final long ONE_HOUR = 60 * 60 * 1000;
67    private static final long TS_2 = System.currentTimeMillis();
68    private static final long TS_1 = TS_2 - ONE_HOUR;
69  
70    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
71    private static final HBaseRESTTestingUtility REST_TEST_UTIL = 
72      new HBaseRESTTestingUtility();
73    private static RemoteHTable remoteTable;
74  
75    @BeforeClass
76    public static void setUpBeforeClass() throws Exception {
77      TEST_UTIL.startMiniCluster();
78      REST_TEST_UTIL.startServletContainer(TEST_UTIL.getConfiguration());
79      HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
80      LOG.info("Admin Connection=" + admin.getConnection() + ", " + 
81        admin.getConnection().getZooKeeperWatcher());
82      if (!admin.tableExists(TABLE)) {
83        HTableDescriptor htd = new HTableDescriptor(TABLE);
84        htd.addFamily(new HColumnDescriptor(COLUMN_1));
85        htd.addFamily(new HColumnDescriptor(COLUMN_2));
86        htd.addFamily(new HColumnDescriptor(COLUMN_3));
87        admin.createTable(htd);
88        HTable table = new HTable(TEST_UTIL.getConfiguration(), TABLE);
89        LOG.info("Table connection=" + table.getConnection() + ", " +
90          admin.getConnection().getZooKeeperWatcher());
91        Put put = new Put(ROW_1);
92        put.add(COLUMN_1, QUALIFIER_1, TS_2, VALUE_1);
93        table.put(put);
94        put = new Put(ROW_2);
95        put.add(COLUMN_1, QUALIFIER_1, TS_1, VALUE_1);
96        put.add(COLUMN_1, QUALIFIER_1, TS_2, VALUE_2);
97        put.add(COLUMN_2, QUALIFIER_2, TS_2, VALUE_2);
98        table.put(put);
99        table.flushCommits();
100     }
101     remoteTable = new RemoteHTable(
102       new Client(new Cluster().add("localhost", 
103           REST_TEST_UTIL.getServletPort())),
104         TEST_UTIL.getConfiguration(), TABLE);
105   }
106 
107   @AfterClass
108   public static void tearDownAfterClass() throws Exception {
109     remoteTable.close();
110     REST_TEST_UTIL.shutdownServletContainer();
111     TEST_UTIL.shutdownMiniCluster();
112   }
113 
114   @Test
115   public void testGetTableDescriptor() throws IOException {
116     HTableDescriptor local = new HTable(TEST_UTIL.getConfiguration(),
117       TABLE).getTableDescriptor();
118     assertEquals(remoteTable.getTableDescriptor(), local);
119   }
120 
121   @Test
122   public void testGet() throws IOException {
123     Get get = new Get(ROW_1);
124     Result result = remoteTable.get(get);
125     byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1);
126     byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2);
127     assertNotNull(value1);
128     assertTrue(Bytes.equals(VALUE_1, value1));
129     assertNull(value2);
130 
131     get = new Get(ROW_1);
132     get.addFamily(COLUMN_3);
133     result = remoteTable.get(get);
134     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
135     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
136     assertNull(value1);
137     assertNull(value2);
138 
139     get = new Get(ROW_1);
140     get.addColumn(COLUMN_1, QUALIFIER_1);
141     get.addColumn(COLUMN_2, QUALIFIER_2);
142     result = remoteTable.get(get);
143     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
144     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
145     assertNotNull(value1);
146     assertTrue(Bytes.equals(VALUE_1, value1));
147     assertNull(value2);
148 
149     get = new Get(ROW_2);
150     result = remoteTable.get(get);    
151     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
152     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
153     assertNotNull(value1);
154     assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
155     assertNotNull(value2);
156     assertTrue(Bytes.equals(VALUE_2, value2));
157 
158     get = new Get(ROW_2);
159     get.addFamily(COLUMN_1);
160     result = remoteTable.get(get);    
161     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
162     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
163     assertNotNull(value1);
164     assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
165     assertNull(value2);
166 
167     get = new Get(ROW_2);
168     get.addColumn(COLUMN_1, QUALIFIER_1);
169     get.addColumn(COLUMN_2, QUALIFIER_2);
170     result = remoteTable.get(get);    
171     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
172     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
173     assertNotNull(value1);
174     assertTrue(Bytes.equals(VALUE_2, value1)); // @TS_2
175     assertNotNull(value2);
176     assertTrue(Bytes.equals(VALUE_2, value2));
177 
178     // test timestamp
179 
180     get = new Get(ROW_2);
181     get.addFamily(COLUMN_1);
182     get.addFamily(COLUMN_2);
183     get.setTimeStamp(TS_1);
184     result = remoteTable.get(get);    
185     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
186     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
187     assertNotNull(value1);
188     assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1
189     assertNull(value2);
190 
191     // test timerange
192 
193     get = new Get(ROW_2);
194     get.addFamily(COLUMN_1);
195     get.addFamily(COLUMN_2);
196     get.setTimeRange(0, TS_1 + 1);
197     result = remoteTable.get(get);    
198     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
199     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
200     assertNotNull(value1);
201     assertTrue(Bytes.equals(VALUE_1, value1)); // @TS_1
202     assertNull(value2);
203 
204     // test maxVersions
205 
206     get = new Get(ROW_2);
207     get.addFamily(COLUMN_1);
208     get.setMaxVersions(2);
209     result = remoteTable.get(get);
210     int count = 0;
211     for (KeyValue kv: result.list()) {
212       if (Bytes.equals(COLUMN_1, kv.getFamily()) && TS_1 == kv.getTimestamp()) {
213         assertTrue(Bytes.equals(VALUE_1, kv.getValue())); // @TS_1
214         count++;
215       }
216       if (Bytes.equals(COLUMN_1, kv.getFamily()) && TS_2 == kv.getTimestamp()) {
217         assertTrue(Bytes.equals(VALUE_2, kv.getValue())); // @TS_2
218         count++;
219       }
220     }
221     assertEquals(2, count);
222   }
223 
224   @Test
225   public void testMultiGet() throws Exception {
226     ArrayList<Get> gets = new ArrayList<Get>();
227     gets.add(new Get(ROW_1));
228     gets.add(new Get(ROW_2));
229     Result[] results = remoteTable.get(gets);
230     assertNotNull(results);
231     assertEquals(2, results.length);
232     assertEquals(1, results[0].size());
233     assertEquals(2, results[1].size());
234 
235     //Test Versions
236     gets = new ArrayList<Get>();
237     Get g = new Get(ROW_1);
238     g.setMaxVersions(3);
239     gets.add(g);
240     gets.add(new Get(ROW_2));
241     results = remoteTable.get(gets);
242     assertNotNull(results);
243     assertEquals(2, results.length);
244     assertEquals(1, results[0].size());
245     assertEquals(3, results[1].size());
246 
247     //404
248     gets = new ArrayList<Get>();
249     gets.add(new Get(Bytes.toBytes("RESALLYREALLYNOTTHERE")));
250     results = remoteTable.get(gets);
251     assertNotNull(results);
252     assertEquals(0, results.length);
253 
254     gets = new ArrayList<Get>();
255     gets.add(new Get(Bytes.toBytes("RESALLYREALLYNOTTHERE")));
256     gets.add(new Get(ROW_1));
257     gets.add(new Get(ROW_2));
258     results = remoteTable.get(gets);
259     assertNotNull(results);
260     assertEquals(0, results.length);
261   }
262 
263   @Test
264   public void testPut() throws IOException {
265     Put put = new Put(ROW_3);
266     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
267     remoteTable.put(put);
268 
269     Get get = new Get(ROW_3);
270     get.addFamily(COLUMN_1);
271     Result result = remoteTable.get(get);
272     byte[] value = result.getValue(COLUMN_1, QUALIFIER_1);
273     assertNotNull(value);
274     assertTrue(Bytes.equals(VALUE_1, value));
275 
276     // multiput
277 
278     List<Put> puts = new ArrayList<Put>();
279     put = new Put(ROW_3);
280     put.add(COLUMN_2, QUALIFIER_2, VALUE_2);
281     puts.add(put);
282     put = new Put(ROW_4);
283     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
284     puts.add(put);
285     put = new Put(ROW_4);
286     put.add(COLUMN_2, QUALIFIER_2, VALUE_2);
287     puts.add(put);
288     remoteTable.put(puts);
289 
290     get = new Get(ROW_3);
291     get.addFamily(COLUMN_2);
292     result = remoteTable.get(get);
293     value = result.getValue(COLUMN_2, QUALIFIER_2);
294     assertNotNull(value);
295     assertTrue(Bytes.equals(VALUE_2, value));
296     get = new Get(ROW_4);
297     result = remoteTable.get(get);
298     value = result.getValue(COLUMN_1, QUALIFIER_1);
299     assertNotNull(value);
300     assertTrue(Bytes.equals(VALUE_1, value));
301     value = result.getValue(COLUMN_2, QUALIFIER_2);
302     assertNotNull(value);
303     assertTrue(Bytes.equals(VALUE_2, value));
304   }
305 
306   public void testDelete() throws IOException {
307     Put put = new Put(ROW_3);
308     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
309     put.add(COLUMN_2, QUALIFIER_2, VALUE_2);
310     remoteTable.put(put);
311 
312     Get get = new Get(ROW_3);
313     get.addFamily(COLUMN_1);
314     get.addFamily(COLUMN_2);
315     Result result = remoteTable.get(get);
316     byte[] value1 = result.getValue(COLUMN_1, QUALIFIER_1);
317     byte[] value2 = result.getValue(COLUMN_2, QUALIFIER_2);
318     assertNotNull(value1);
319     assertTrue(Bytes.equals(VALUE_1, value1));
320     assertNotNull(value2);
321     assertTrue(Bytes.equals(VALUE_2, value2));
322 
323     Delete delete = new Delete(ROW_3);
324     delete.deleteColumn(COLUMN_2, QUALIFIER_2);
325     remoteTable.delete(delete);
326     
327     get = new Get(ROW_3);
328     get.addFamily(COLUMN_1);
329     get.addFamily(COLUMN_2);
330     result = remoteTable.get(get);
331     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
332     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
333     assertNotNull(value1);
334     assertTrue(Bytes.equals(VALUE_1, value1));
335     assertNull(value2);
336 
337     delete = new Delete(ROW_3);
338     remoteTable.delete(delete);
339 
340     get = new Get(ROW_3);
341     get.addFamily(COLUMN_1);
342     get.addFamily(COLUMN_2);
343     result = remoteTable.get(get);
344     value1 = result.getValue(COLUMN_1, QUALIFIER_1);
345     value2 = result.getValue(COLUMN_2, QUALIFIER_2);
346     assertNull(value1);
347     assertNull(value2);
348   }
349 
350   public void testScanner() throws IOException {
351     List<Put> puts = new ArrayList<Put>();
352     Put put = new Put(ROW_1);
353     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
354     puts.add(put);
355     put = new Put(ROW_2);
356     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
357     puts.add(put);
358     put = new Put(ROW_3);
359     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
360     puts.add(put);
361     put = new Put(ROW_4);
362     put.add(COLUMN_1, QUALIFIER_1, VALUE_1);
363     puts.add(put);
364     remoteTable.put(puts);
365 
366     ResultScanner scanner = remoteTable.getScanner(new Scan());
367 
368     Result[] results = scanner.next(1);
369     assertNotNull(results);
370     assertEquals(1, results.length);
371     assertTrue(Bytes.equals(ROW_1, results[0].getRow()));
372 
373     results = scanner.next(3);
374     assertNotNull(results);
375     assertEquals(3, results.length);
376     assertTrue(Bytes.equals(ROW_2, results[0].getRow()));
377     assertTrue(Bytes.equals(ROW_3, results[1].getRow()));
378     assertTrue(Bytes.equals(ROW_4, results[2].getRow()));
379 
380     results = scanner.next(1);
381     assertNull(results);
382 
383     scanner.close();
384   }
385 
386   @org.junit.Rule
387   public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
388     new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
389 }
390