1   /** 
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.avro;
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.nio.ByteBuffer;
25  
26  import org.apache.avro.Schema;
27  import org.apache.avro.generic.GenericArray;
28  import org.apache.avro.generic.GenericData;
29  import org.apache.hadoop.hbase.HBaseTestingUtility;
30  import org.apache.hadoop.hbase.avro.generated.AColumn;
31  import org.apache.hadoop.hbase.avro.generated.AColumnValue;
32  import org.apache.hadoop.hbase.avro.generated.AFamilyDescriptor;
33  import org.apache.hadoop.hbase.avro.generated.AGet;
34  import org.apache.hadoop.hbase.avro.generated.APut;
35  import org.apache.hadoop.hbase.avro.generated.ATableDescriptor;
36  import org.apache.hadoop.hbase.util.Bytes;
37  import org.apache.hadoop.hbase.util.Threads;
38  import org.junit.After;
39  import org.junit.AfterClass;
40  import org.junit.Before;
41  import org.junit.BeforeClass;
42  import org.junit.Test;
43  
44  /**
45   * Unit testing for AvroServer.HBaseImpl, a part of the
46   * org.apache.hadoop.hbase.avro package.
47   */
48  public class TestAvroServer {
49    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
50  
51    // Static names for tables, columns, rows, and values
52    // TODO(hammer): Better style to define these in test method?
53    private static ByteBuffer tableAname = ByteBuffer.wrap(Bytes.toBytes("tableA"));
54    private static ByteBuffer tableBname = ByteBuffer.wrap(Bytes.toBytes("tableB"));
55    private static ByteBuffer familyAname = ByteBuffer.wrap(Bytes.toBytes("FamilyA"));
56    private static ByteBuffer qualifierAname = ByteBuffer.wrap(Bytes.toBytes("QualifierA"));
57    private static ByteBuffer rowAname = ByteBuffer.wrap(Bytes.toBytes("RowA"));
58    private static ByteBuffer valueA = ByteBuffer.wrap(Bytes.toBytes("ValueA"));
59  
60    /**
61     * @throws java.lang.Exception
62     */
63    @BeforeClass
64    public static void setUpBeforeClass() throws Exception {
65      TEST_UTIL.startMiniCluster();
66    }
67  
68    /**
69     * @throws java.lang.Exception
70     */
71    @AfterClass
72    public static void tearDownAfterClass() throws Exception {
73      TEST_UTIL.shutdownMiniCluster();
74    }
75  
76    /**
77     * @throws java.lang.Exception
78     */
79    @Before
80    public void setUp() throws Exception {
81      // Nothing to do.
82    }
83  
84    /**
85     * @throws java.lang.Exception
86     */
87    @After
88    public void tearDown() throws Exception {
89      // Nothing to do.
90    }
91  
92    /**
93     * Tests for creating, enabling, disabling, modifying, and deleting tables.
94     *
95     * @throws Exception
96     */
97    @Test (timeout=300000)
98    public void testTableAdminAndMetadata() throws Exception {
99      AvroServer.HBaseImpl impl =
100       new AvroServer.HBaseImpl(TEST_UTIL.getConfiguration());
101 
102     assertEquals(impl.listTables().size(), 0);
103 
104     ATableDescriptor tableA = new ATableDescriptor();
105     tableA.name = tableAname;
106     impl.createTable(tableA);
107     assertEquals(impl.listTables().size(), 1);
108     assertTrue(impl.isTableEnabled(tableAname));
109     assertTrue(impl.tableExists(tableAname));
110 
111     ATableDescriptor tableB = new ATableDescriptor();
112     tableB.name = tableBname;
113     impl.createTable(tableB);
114     assertEquals(impl.listTables().size(), 2);
115 
116     impl.disableTable(tableBname);
117     assertFalse(impl.isTableEnabled(tableBname));
118 
119     impl.deleteTable(tableBname);
120     assertEquals(impl.listTables().size(), 1);
121 
122     impl.disableTable(tableAname);
123     assertFalse(impl.isTableEnabled(tableAname));
124 
125     long oldMaxFileSize = impl.describeTable(tableAname).maxFileSize;
126     tableA.maxFileSize = 123456L;
127     impl.modifyTable(tableAname, tableA);
128   
129     // It can take a while for the change to take effect.  Wait here a while.
130     while(impl.describeTable(tableAname).maxFileSize == oldMaxFileSize) {
131       Threads.sleep(100);
132     }
133 
134     assertTrue(impl.describeTable(tableAname).maxFileSize == 123456L);
135     assertEquals(123456L, (long) impl.describeTable(tableAname).maxFileSize);
136 /* DISABLED FOR NOW TILL WE HAVE BETTER DISABLE/ENABLE
137     impl.enableTable(tableAname);
138     assertTrue(impl.isTableEnabled(tableAname));
139     
140     impl.disableTable(tableAname);
141     */
142     impl.deleteTable(tableAname);
143   }
144 
145   /**
146    * Tests for creating, modifying, and deleting column families.
147    *
148    * @throws Exception
149    */
150   @Test
151   public void testFamilyAdminAndMetadata() throws Exception {
152     AvroServer.HBaseImpl impl =
153       new AvroServer.HBaseImpl(TEST_UTIL.getConfiguration());
154 
155     ATableDescriptor tableA = new ATableDescriptor();
156     tableA.name = tableAname;
157     AFamilyDescriptor familyA = new AFamilyDescriptor();
158     familyA.name = familyAname;
159     Schema familyArraySchema = Schema.createArray(AFamilyDescriptor.SCHEMA$);
160     GenericArray<AFamilyDescriptor> families = new GenericData.Array<AFamilyDescriptor>(1, familyArraySchema);
161     families.add(familyA);
162     tableA.families = families;
163     impl.createTable(tableA);
164     assertEquals(impl.describeTable(tableAname).families.size(), 1);
165 
166     impl.disableTable(tableAname);
167     assertFalse(impl.isTableEnabled(tableAname));
168 
169     familyA.maxVersions = 123456;
170     impl.modifyFamily(tableAname, familyAname, familyA);
171     assertEquals((int) impl.describeFamily(tableAname, familyAname).maxVersions, 123456);
172 
173     impl.deleteFamily(tableAname, familyAname);
174     assertEquals(impl.describeTable(tableAname).families.size(), 0);
175 
176     impl.deleteTable(tableAname);
177   }
178 
179   /**
180    * Tests for adding, reading, and deleting data.
181    *
182    * @throws Exception
183    */
184   @Test
185   public void testDML() throws Exception {
186     AvroServer.HBaseImpl impl =
187       new AvroServer.HBaseImpl(TEST_UTIL.getConfiguration());
188 
189     ATableDescriptor tableA = new ATableDescriptor();
190     tableA.name = tableAname;
191     AFamilyDescriptor familyA = new AFamilyDescriptor();
192     familyA.name = familyAname;
193     Schema familyArraySchema = Schema.createArray(AFamilyDescriptor.SCHEMA$);
194     GenericArray<AFamilyDescriptor> families = new GenericData.Array<AFamilyDescriptor>(1, familyArraySchema);
195     families.add(familyA);
196     tableA.families = families;
197     impl.createTable(tableA);
198     assertEquals(impl.describeTable(tableAname).families.size(), 1);
199 
200     AGet getA = new AGet();
201     getA.row = rowAname;
202     Schema columnsSchema = Schema.createArray(AColumn.SCHEMA$);
203     GenericArray<AColumn> columns = new GenericData.Array<AColumn>(1, columnsSchema);
204     AColumn column = new AColumn();
205     column.family = familyAname;
206     column.qualifier = qualifierAname;
207     columns.add(column);
208     getA.columns = columns;
209    
210     assertFalse(impl.exists(tableAname, getA));
211 
212     APut putA = new APut();
213     putA.row = rowAname;
214     Schema columnValuesSchema = Schema.createArray(AColumnValue.SCHEMA$);
215     GenericArray<AColumnValue> columnValues = new GenericData.Array<AColumnValue>(1, columnValuesSchema);
216     AColumnValue acv = new AColumnValue();
217     acv.family = familyAname;
218     acv.qualifier = qualifierAname;
219     acv.value = valueA;
220     columnValues.add(acv);
221     putA.columnValues = columnValues;
222 
223     impl.put(tableAname, putA);
224     assertTrue(impl.exists(tableAname, getA));
225 
226     assertEquals(impl.get(tableAname, getA).entries.size(), 1);
227 
228     impl.disableTable(tableAname);
229     impl.deleteTable(tableAname);
230   }
231 }