Author: jdcryans
Date: Fri Aug  9 20:45:30 2013
New Revision: 1512489

URL: http://svn.apache.org/r1512489
Log:
HBASE-8663  a HBase Shell command to list the tables replicated from
            current cluster (Demai Ni via JD)

Added:
    
hbase/branches/0.95/hbase-server/src/main/ruby/shell/commands/list_replicated_tables.rb
Modified:
    
hbase/branches/0.95/hbase-client/src/main/java/org/apache/hadoop/hbase/client/replication/ReplicationAdmin.java
    hbase/branches/0.95/hbase-server/src/main/ruby/hbase/replication_admin.rb
    hbase/branches/0.95/hbase-server/src/main/ruby/shell.rb
    
hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestReplicationSmallTests.java

Modified: 
hbase/branches/0.95/hbase-client/src/main/java/org/apache/hadoop/hbase/client/replication/ReplicationAdmin.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-client/src/main/java/org/apache/hadoop/hbase/client/replication/ReplicationAdmin.java?rev=1512489&r1=1512488&r2=1512489&view=diff
==============================================================================
--- 
hbase/branches/0.95/hbase-client/src/main/java/org/apache/hadoop/hbase/client/replication/ReplicationAdmin.java
 (original)
+++ 
hbase/branches/0.95/hbase-client/src/main/java/org/apache/hadoop/hbase/client/replication/ReplicationAdmin.java
 Fri Aug  9 20:45:30 2013
@@ -30,10 +30,16 @@ import org.apache.hadoop.hbase.replicati
 import org.apache.hadoop.hbase.replication.ReplicationQueuesClient;
 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
 import org.apache.zookeeper.KeeperException;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.HColumnDescriptor;
 
 import java.io.Closeable;
 import java.io.IOException;
 import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.lang.Integer;
 
 /**
  * <p>
@@ -61,6 +67,15 @@ import java.util.Map;
 public class ReplicationAdmin implements Closeable {
   private static final Log LOG = LogFactory.getLog(ReplicationAdmin.class);
 
+  public static final String TNAME = "tableName";
+  public static final String CFNAME = "columnFamlyName";
+
+  // only Global for now, can add other type
+  // such as, 1) no global replication, or 2) the table is replicated to this 
cluster, etc.
+  public static final String REPLICATIONTYPE = "replicationType";
+  public static final String REPLICATIONGLOBAL = Integer
+      .toString(HConstants.REPLICATION_SCOPE_GLOBAL);
+
   private final HConnection connection;
   private final ReplicationQueuesClient replicationQueuesClient;
   private final ReplicationPeers replicationPeers;
@@ -166,4 +181,38 @@ public class ReplicationAdmin implements
       this.connection.close();
     }
   }
+
+  
+  /**
+   * Find all column families that are replicated from this cluster
+   * @return the full list of the replicated column families of this cluster 
as:
+   *        tableName, family name, replicationType
+   *
+   * Currently replicationType is Global. In the future, more replication
+   * types may be extended here. For example
+   *  1) the replication may only apply to selected peers instead of all peers
+   *  2) the replicationType may indicate the host Cluster servers as Slave
+   *     for the table:columnFam.         
+   */
+  public List<HashMap<String, String>> listReplicated() throws IOException {
+    List<HashMap<String, String>> replicationColFams = new 
ArrayList<HashMap<String, String>>();
+    HTableDescriptor[] tables = this.connection.listTables();
+
+    for (HTableDescriptor table : tables) {
+      HColumnDescriptor[] columns = table.getColumnFamilies();
+      String tableName = table.getNameAsString();
+      for (HColumnDescriptor column : columns) {
+        if (column.getScope() != HConstants.REPLICATION_SCOPE_LOCAL) {
+          // At this moment, the columfam is replicated to all peers
+          HashMap<String, String> replicationEntry = new HashMap<String, 
String>();
+          replicationEntry.put(TNAME, tableName);
+          replicationEntry.put(CFNAME, column.getNameAsString());
+          replicationEntry.put(REPLICATIONTYPE, REPLICATIONGLOBAL);
+          replicationColFams.add(replicationEntry);
+        }
+      }
+    }
+
+    return replicationColFams;
+  } 
 }

Modified: 
hbase/branches/0.95/hbase-server/src/main/ruby/hbase/replication_admin.rb
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/ruby/hbase/replication_admin.rb?rev=1512489&r1=1512488&r2=1512489&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/ruby/hbase/replication_admin.rb 
(original)
+++ hbase/branches/0.95/hbase-server/src/main/ruby/hbase/replication_admin.rb 
Fri Aug  9 20:45:30 2013
@@ -42,6 +42,13 @@ module Hbase
       @replication_admin.removePeer(id)
     end
 
+
+    
#---------------------------------------------------------------------------------------------
+    # Show replcated tables/column families, and their ReplicationType
+    def list_replicated_tables
+       @replication_admin.listReplicated()
+    end
+
     
#----------------------------------------------------------------------------------------------
     # List all peer clusters
     def list_peers

Modified: hbase/branches/0.95/hbase-server/src/main/ruby/shell.rb
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/ruby/shell.rb?rev=1512489&r1=1512488&r2=1512489&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/ruby/shell.rb (original)
+++ hbase/branches/0.95/hbase-server/src/main/ruby/shell.rb Fri Aug  9 20:45:30 
2013
@@ -317,6 +317,7 @@ Shell.load_command_group(
     list_peers
     enable_peer
     disable_peer
+    list_replicated_tables
   ]
 )
 

Added: 
hbase/branches/0.95/hbase-server/src/main/ruby/shell/commands/list_replicated_tables.rb
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/ruby/shell/commands/list_replicated_tables.rb?rev=1512489&view=auto
==============================================================================
--- 
hbase/branches/0.95/hbase-server/src/main/ruby/shell/commands/list_replicated_tables.rb
 (added)
+++ 
hbase/branches/0.95/hbase-server/src/main/ruby/shell/commands/list_replicated_tables.rb
 Fri Aug  9 20:45:30 2013
@@ -0,0 +1,52 @@
+#
+# Copyright The Apache Software Foundation
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+module Shell
+  module Commands
+    class ListReplicatedTables< Command
+      def help
+        return <<-EOF
+List all the tables and column families replicated from this cluster
+
+  hbase> list_replicated_tables
+  hbase> list_replicated_tables 'abc.*'
+EOF
+      end
+
+      def command(regex = ".*")
+        now = Time.now
+
+        formatter.header([ "TABLE:COLUMNFAMILY", "ReplicationType" ], [ 32 ])
+        list = replication_admin.list_replicated_tables
+        regex = /#{regex}/ unless regex.is_a?(Regexp)
+        list = list.select {|s| 
regex.match(s.get(org.apache.hadoop.hbase.client.replication.ReplicationAdmin::TNAME))}
+        list.each do |e|
+          if 
e.get(org.apache.hadoop.hbase.client.replication.ReplicationAdmin::REPLICATIONTYPE)
 == 
org.apache.hadoop.hbase.client.replication.ReplicationAdmin::REPLICATIONGLOBAL
+             replicateType = "GLOBAL"
+          else
+             replicateType = "unknown"
+          end
+          
formatter.row([e.get(org.apache.hadoop.hbase.client.replication.ReplicationAdmin::TNAME)
 + ":" + 
e.get(org.apache.hadoop.hbase.client.replication.ReplicationAdmin::CFNAME), 
replicateType], true, [32])
+        end
+        formatter.footer(now)
+      end
+    end
+  end
+end

Modified: 
hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestReplicationSmallTests.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestReplicationSmallTests.java?rev=1512489&r1=1512488&r2=1512489&view=diff
==============================================================================
--- 
hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestReplicationSmallTests.java
 (original)
+++ 
hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestReplicationSmallTests.java
 Fri Aug  9 20:45:30 2013
@@ -18,11 +18,19 @@
 
 package org.apache.hadoop.hbase.replication;
 
+import java.util.HashMap;
+import java.util.List;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.LargeTests;
+import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.*;
+import org.apache.hadoop.hbase.client.replication.ReplicationAdmin;
 import org.apache.hadoop.hbase.mapreduce.replication.VerifyReplication;
 import org.apache.hadoop.hbase.protobuf.generated.WALProtos;
 import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
@@ -39,6 +47,7 @@ import org.junit.experimental.categories
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
+import static org.junit.Assert.assertTrue;
 
 @Category(LargeTests.class)
 public class TestReplicationSmallTests extends TestReplicationBase {
@@ -477,5 +486,59 @@ public class TestReplicationSmallTests e
     WALEdit edit = WALEdit.createCompaction(compactionDescriptor);
     Replication.scopeWALEdits(htable1.getTableDescriptor(), new HLogKey(), 
edit);
   }
+  
+  /**
+   * Test for HBASE-8663
+   * Create two new Tables with colfamilies enabled for replication then run
+   * ReplicationAdmin.listReplicated(). Finally verify the table:colfamilies. 
Note:
+   * TestReplicationAdmin is a better place for this testing but it would need 
mocks.
+   * @throws Exception
+   */
+  @Test(timeout = 300000)
+  public void testVerifyListReplicatedTable() throws Exception {
+       LOG.info("testVerifyListReplicatedTable");
+
+    final String tName = "VerifyListReplicated_";
+    final String colFam = "cf1";
+    final int numOfTables = 3;
+
+    HBaseAdmin hadmin = new HBaseAdmin(conf1);
+
+    // Create Tables
+    for (int i = 0; i < numOfTables; i++) {
+      HTableDescriptor ht = new HTableDescriptor(TableName.valueOf(tName + i));
+      HColumnDescriptor cfd = new HColumnDescriptor(colFam);
+      cfd.setScope(HConstants.REPLICATION_SCOPE_GLOBAL);
+      ht.addFamily(cfd);
+      hadmin.createTable(ht);
+    }
+
+    // verify the result
+    List<HashMap<String, String>> replicationColFams = admin.listReplicated();
+    int[] match = new int[numOfTables]; // array of 3 with init value of zero
+
+    for (int i = 0; i < replicationColFams.size(); i++) {
+      HashMap<String, String> replicationEntry = replicationColFams.get(i);
+      String tn = replicationEntry.get(ReplicationAdmin.TNAME);
+      if ((tn.startsWith(tName)) && 
replicationEntry.get(ReplicationAdmin.CFNAME).equals(colFam)) {
+        int m = Integer.parseInt(tn.substring(tn.length() - 1)); // get the 
last digit
+        match[m]++; // should only increase once
+      }
+    }
+
+    // check the matching result
+    for (int i = 0; i < match.length; i++) {
+      assertTrue("listReplicated() does not match table " + i, (match[i] == 
1));
+    }
+
+    // drop tables
+    for (int i = 0; i < numOfTables; i++) {
+      String ht = tName + i;
+      hadmin.disableTable(ht);
+      hadmin.deleteTable(ht);
+    }
+
+    hadmin.close();
+  }
 
 }


Reply via email to