View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional information regarding
4    * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with the License. You may obtain a
6    * copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
7    * law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
8    * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
9    * for the specific language governing permissions and limitations under the License.
10   */
11  package org.apache.hadoop.hbase.client.replication;
12  
13  import static org.junit.Assert.assertEquals;
14  import static org.junit.Assert.assertFalse;
15  import static org.junit.Assert.assertTrue;
16  import static org.junit.Assert.fail;
17  
18  import java.util.Collection;
19  import java.util.HashMap;
20  import java.util.Map;
21  import java.util.UUID;
22  
23  import org.apache.hadoop.hbase.HColumnDescriptor;
24  import org.apache.hadoop.hbase.HConstants;
25  import org.apache.hadoop.hbase.HTableDescriptor;
26  import org.apache.hadoop.hbase.TableName;
27  import org.apache.hadoop.hbase.TableNotFoundException;
28  import org.apache.hadoop.hbase.client.Admin;
29  import org.apache.hadoop.hbase.client.Connection;
30  import org.apache.hadoop.hbase.client.ConnectionFactory;
31  import org.apache.hadoop.hbase.replication.BaseReplicationEndpoint;
32  import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
33  import org.apache.hadoop.hbase.replication.TestReplicationBase;
34  import org.apache.hadoop.hbase.testclassification.MediumTests;
35  import org.junit.AfterClass;
36  import org.junit.BeforeClass;
37  import org.junit.Test;
38  import org.junit.experimental.categories.Category;
39  
40  /**
41   * Unit testing of ReplicationAdmin with clusters
42   */
43  @Category({ MediumTests.class })
44  public class TestReplicationAdminWithClusters extends TestReplicationBase {
45  
46    static Connection connection1;
47    static Connection connection2;
48    static Admin admin1;
49    static Admin admin2;
50    static ReplicationAdmin adminExt;
51  
52    @BeforeClass
53    public static void setUpBeforeClass() throws Exception {
54      TestReplicationBase.setUpBeforeClass();
55      connection1 = ConnectionFactory.createConnection(conf1);
56      connection2 = ConnectionFactory.createConnection(conf2);
57      admin1 = connection1.getAdmin();
58      admin2 = connection2.getAdmin();
59      adminExt = new ReplicationAdmin(conf1);
60    }
61  
62    @AfterClass
63    public static void tearDownAfterClass() throws Exception {
64      admin1.close();
65      admin2.close();
66      adminExt.close();
67      connection1.close();
68      connection2.close();
69      TestReplicationBase.tearDownAfterClass();
70    }
71  
72    @Test(timeout = 300000)
73    public void disableNotFullReplication() throws Exception {
74      HTableDescriptor table = admin2.getTableDescriptor(tableName);
75      HColumnDescriptor f = new HColumnDescriptor("notReplicatedFamily");
76      table.addFamily(f);
77      admin1.disableTable(tableName);
78      admin1.modifyTable(tableName, table);
79      admin1.enableTable(tableName);
80  
81  
82      admin.disableTableRep(tableName);
83      table = admin1.getTableDescriptor(tableName);
84      for (HColumnDescriptor fam : table.getColumnFamilies()) {
85        assertEquals(fam.getScope(), HConstants.REPLICATION_SCOPE_LOCAL);
86      }
87    }
88  
89    @Test(timeout = 300000)
90    public void testEnableReplicationWhenSlaveClusterDoesntHaveTable() throws Exception {
91      admin.disableTableRep(tableName);
92      admin2.disableTable(tableName);
93      admin2.deleteTable(tableName);
94      assertFalse(admin2.tableExists(tableName));
95      adminExt.enableTableRep(tableName);
96      assertTrue(admin2.tableExists(tableName));
97    }
98  
99    @Test(timeout = 300000)
100   public void testEnableReplicationWhenReplicationNotEnabled() throws Exception {
101     HTableDescriptor table = admin1.getTableDescriptor(tableName);
102     for (HColumnDescriptor fam : table.getColumnFamilies()) {
103       fam.setScope(HConstants.REPLICATION_SCOPE_LOCAL);
104     }
105     admin1.disableTable(tableName);
106     admin1.modifyTable(tableName, table);
107     admin1.enableTable(tableName);
108 
109     admin2.disableTable(tableName);
110     admin2.modifyTable(tableName, table);
111     admin2.enableTable(tableName);
112 
113     adminExt.enableTableRep(tableName);
114     table = admin1.getTableDescriptor(tableName);
115     for (HColumnDescriptor fam : table.getColumnFamilies()) {
116       assertEquals(fam.getScope(), HConstants.REPLICATION_SCOPE_GLOBAL);
117     }
118   }
119 
120   @Test(timeout = 300000)
121   public void testEnableReplicationWhenTableDescriptorIsNotSameInClusters() throws Exception {
122     HTableDescriptor table = admin2.getTableDescriptor(tableName);
123     HColumnDescriptor f = new HColumnDescriptor("newFamily");
124     table.addFamily(f);
125     admin2.disableTable(tableName);
126     admin2.modifyTable(tableName, table);
127     admin2.enableTable(tableName);
128 
129     try {
130       adminExt.enableTableRep(tableName);
131       fail("Exception should be thrown if table descriptors in the clusters are not same.");
132     } catch (RuntimeException ignored) {
133 
134     }
135     admin1.disableTable(tableName);
136     admin1.modifyTable(tableName, table);
137     admin1.enableTable(tableName);
138     adminExt.enableTableRep(tableName);
139     table = admin1.getTableDescriptor(tableName);
140     for (HColumnDescriptor fam : table.getColumnFamilies()) {
141       assertEquals(fam.getScope(), HConstants.REPLICATION_SCOPE_GLOBAL);
142     }
143   }
144 
145   @Test(timeout = 300000)
146   public void testDisableAndEnableReplication() throws Exception {
147     adminExt.disableTableRep(tableName);
148     HTableDescriptor table = admin1.getTableDescriptor(tableName);
149     for (HColumnDescriptor fam : table.getColumnFamilies()) {
150       assertEquals(fam.getScope(), HConstants.REPLICATION_SCOPE_LOCAL);
151     }
152     adminExt.enableTableRep(tableName);
153     table = admin1.getTableDescriptor(tableName);
154     for (HColumnDescriptor fam : table.getColumnFamilies()) {
155       assertEquals(fam.getScope(), HConstants.REPLICATION_SCOPE_GLOBAL);
156     }
157   }
158 
159   @Test(timeout = 300000, expected = TableNotFoundException.class)
160   public void testDisableReplicationForNonExistingTable() throws Exception {
161     adminExt.disableTableRep(TableName.valueOf("nonExistingTable"));
162   }
163 
164   @Test(timeout = 300000, expected = TableNotFoundException.class)
165   public void testEnableReplicationForNonExistingTable() throws Exception {
166     adminExt.enableTableRep(TableName.valueOf("nonExistingTable"));
167   }
168 
169   @Test(timeout = 300000, expected = IllegalArgumentException.class)
170   public void testDisableReplicationWhenTableNameAsNull() throws Exception {
171     adminExt.disableTableRep(null);
172   }
173 
174   @Test(timeout = 300000, expected = IllegalArgumentException.class)
175   public void testEnableReplicationWhenTableNameAsNull() throws Exception {
176     adminExt.enableTableRep(null);
177   }
178   
179   /*
180    * Test enable table replication should create table only in user explicit specified table-cfs.
181    * HBASE-14717
182    */
183   @Test(timeout = 300000)
184   public void testEnableReplicationForExplicitSetTableCfs() throws Exception {
185     TableName tn = TableName.valueOf("testEnableReplicationForSetTableCfs");
186     String peerId = "2";
187     if (admin2.isTableAvailable(tableName)) {
188       admin2.disableTable(tableName);
189       admin2.deleteTable(tableName);
190     }
191     assertFalse("Table should not exists in the peer cluster", admin2.isTableAvailable(tableName));
192 
193     Map<TableName, ? extends Collection<String>> tableCfs =
194         new HashMap<TableName, Collection<String>>();
195     tableCfs.put(tn, null);
196     try {
197       adminExt.setPeerTableCFs(peerId, tableCfs);
198       adminExt.enableTableRep(tableName);
199       assertFalse("Table should not be created if user has set table cfs explicitly for the "
200           + "peer and this is not part of that collection",
201         admin2.isTableAvailable(tableName));
202 
203       tableCfs.put(tableName, null);
204       adminExt.setPeerTableCFs(peerId, tableCfs);
205       adminExt.enableTableRep(tableName);
206       assertTrue(
207         "Table should be created if user has explicitly added table into table cfs collection",
208         admin2.isTableAvailable(tableName));
209     } finally {
210       adminExt.removePeerTableCFs(peerId, adminExt.getPeerTableCFs(peerId));
211       adminExt.disableTableRep(tableName);
212     }
213   }
214 
215   @Test(timeout=300000)
216   public void testReplicationPeerConfigUpdateCallback() throws Exception {
217     String peerId = "1";
218     ReplicationPeerConfig rpc = new ReplicationPeerConfig();
219     rpc.setClusterKey(utility2.getClusterKey());
220     rpc.setReplicationEndpointImpl(TestUpdatableReplicationEndpoint.class.getName());
221     rpc.getConfiguration().put("key1", "value1");
222     admin.addPeer(peerId, rpc, null);
223     admin.peerAdded(peerId);
224     rpc.getConfiguration().put("key1", "value2");
225     admin.updatePeerConfig(peerId, rpc);
226     if (!TestUpdatableReplicationEndpoint.hasCalledBack()) {
227       synchronized(TestUpdatableReplicationEndpoint.class) {
228         TestUpdatableReplicationEndpoint.class.wait(2000L);
229       }
230     }
231     assertEquals(true, TestUpdatableReplicationEndpoint.hasCalledBack());
232   }
233 
234   public static class TestUpdatableReplicationEndpoint extends BaseReplicationEndpoint {
235     private static boolean calledBack = false;
236     public static boolean hasCalledBack(){
237       return calledBack;
238     }
239     @Override
240     public synchronized void peerConfigUpdated(ReplicationPeerConfig rpc){
241       calledBack = true;
242       notifyAll();
243     }
244 
245     @Override
246     protected void doStart() {
247       notifyStarted();
248     }
249 
250     @Override
251     protected void doStop() {
252      notifyStopped();
253     }
254 
255     @Override
256     public UUID getPeerUUID() {
257      return UUID.randomUUID();
258     }
259 
260     @Override
261     public boolean replicate(ReplicateContext replicateContext) {
262      return false;
263     }
264   }
265 }