Author: garyh
Date: Thu Sep  8 06:49:35 2011
New Revision: 1166540

URL: http://svn.apache.org/viewvc?rev=1166540&view=rev
Log:
HBASE-4271  Clean up coprocessor handling of table operations

Modified:
    hbase/trunk/CHANGES.txt
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
    
hbase/trunk/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java
    
hbase/trunk/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
    
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
    
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
    
hbase/trunk/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java

Modified: hbase/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1166540&r1=1166539&r2=1166540&view=diff
==============================================================================
--- hbase/trunk/CHANGES.txt (original)
+++ hbase/trunk/CHANGES.txt Thu Sep  8 06:49:35 2011
@@ -243,6 +243,8 @@ Release 0.91.0 - Unreleased
    HBASE-4309  slow query log metrics spewing warnings (Riley Patterson)
    HBASE-4302  Only run Snappy compression tests if Snappy is available
                (Alejandro Abdelnur via todd)
+   HBASE-4271  Clean up coprocessor handling of table operations
+               (Ming Ma via garyh)
 
   IMPROVEMENTS
    HBASE-3290  Max Compaction Size (Nicolas Spiegelberg via Stack)  

Modified: 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java?rev=1166540&r1=1166539&r2=1166540&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java 
(original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java 
Thu Sep  8 06:49:35 2011
@@ -107,10 +107,10 @@ public class HBaseAdmin implements Abort
         break;
       } catch (MasterNotRunningException mnre) {
         HConnectionManager.deleteStaleConnection(this.connection);
-        this.connection = HConnectionManager.getConnection(this.conf);        
+        this.connection = HConnectionManager.getConnection(this.conf);
       } catch (UndeclaredThrowableException ute) {
         HConnectionManager.deleteStaleConnection(this.connection);
-        this.connection = HConnectionManager.getConnection(this.conf);        
+        this.connection = HConnectionManager.getConnection(this.conf);
       }
       try { // Sleep
         Thread.sleep(getPauseTime(tries));
@@ -486,8 +486,23 @@ public class HBaseAdmin implements Abort
           firstMetaServer.getRegionInfo().getRegionName(), scan);
         // Get a batch at a time.
         Result values = server.next(scannerId);
+
+        // let us wait until .META. table is updated and
+        // HMaster removes the table from its HTableDescriptors
         if (values == null) {
-          break;
+          boolean tableExists = false;
+          HTableDescriptor[] htds = getMaster().getHTableDescriptors();
+          if (htds != null && htds.length > 0) {
+            for (HTableDescriptor htd: htds) {
+              if (Bytes.equals(tableName, htd.getName())) {
+                tableExists = true;
+                break;
+              }
+            }
+          }
+          if (!tableExists) {
+            break;
+          }
         }
       } catch (IOException ex) {
         if(tries == numRetries - 1) {           // no more tries left

Modified: 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java?rev=1166540&r1=1166539&r2=1166540&view=diff
==============================================================================
--- 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java
 (original)
+++ 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java
 Thu Sep  8 06:49:35 2011
@@ -32,12 +32,12 @@ import java.io.IOException;
 public class BaseMasterObserver implements MasterObserver {
   @Override
   public void preCreateTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
-      HTableDescriptor desc, byte[][] splitKeys) throws IOException {
+      HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
   }
 
   @Override
   public void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> 
ctx,
-      HRegionInfo[] regions, boolean sync) throws IOException {
+      HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
   }
 
   @Override
@@ -112,17 +112,17 @@ public class BaseMasterObserver implemen
 
   @Override
   public void preAssign(ObserverContext<MasterCoprocessorEnvironment> ctx,
-      byte[] regionName, boolean force) throws IOException {
+      HRegionInfo regionInfo, boolean force) throws IOException {
   }
 
   @Override
   public void postAssign(ObserverContext<MasterCoprocessorEnvironment> ctx,
-      HRegionInfo regionInfo) throws IOException {
+      HRegionInfo regionInfo, boolean force) throws IOException {
   }
 
   @Override
   public void preUnassign(ObserverContext<MasterCoprocessorEnvironment> ctx,
-      byte[] regionName, boolean force) throws IOException {
+      HRegionInfo regionInfo, boolean force) throws IOException {
   }
 
   @Override

Modified: 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java?rev=1166540&r1=1166539&r2=1166540&view=diff
==============================================================================
--- 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
 (original)
+++ 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
 Thu Sep  8 06:49:35 2011
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010 The Apache Software Foundation
+ * Copyright 2011 The Apache Software Foundation
  *
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -33,142 +33,207 @@ public interface MasterObserver extends 
   /**
    * Called before a new table is created by
    * {@link org.apache.hadoop.hbase.master.HMaster}.
+   * It can't bypass the default action, e.g., ctx.bypass() won't have effect.
+   * @param ctx the environment to interact with the framework and master
+   * @param desc the HTableDescriptor for the table
+   * @param regions the initial regions created for the table
+   * @throws IOException
    */
   void preCreateTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
-      HTableDescriptor desc, byte[][] splitKeys) throws IOException;
+      HTableDescriptor desc, HRegionInfo[] regions) throws IOException;
 
   /**
-   * Called after the initial table regions have been created.
+   * Called after the createTable operation has been requested.
    * @param ctx the environment to interact with the framework and master
+   * @param desc the HTableDescriptor for the table
    * @param regions the initial regions created for the table
-   * @param sync whether the client call is waiting for region assignment to
-   * complete before returning
    * @throws IOException
    */
   void postCreateTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
-      HRegionInfo[] regions, boolean sync) throws IOException;
+      HTableDescriptor desc, HRegionInfo[] regions) throws IOException;
 
   /**
    * Called before {@link org.apache.hadoop.hbase.master.HMaster} deletes a
    * table
+   * It can't bypass the default action, e.g., ctx.bypass() won't have effect.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
    */
   void preDeleteTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       byte[] tableName) throws IOException;
 
   /**
-   * Called after the table has been deleted, before returning to the client.
+   * Called after the deleteTable operation has been requested.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
    */
   void postDeleteTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       byte[] tableName) throws IOException;
 
   /**
    * Called prior to modifying a table's properties.
+   * It can't bypass the default action, e.g., ctx.bypass() won't have effect.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
+   * @param htd the HTableDescriptor
    */
   void preModifyTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       final byte[] tableName, HTableDescriptor htd) throws IOException;
 
   /**
-   * Called after {@link org.apache.hadoop.hbase.master.HMaster} has modified
-   * the table's properties in all the table regions.
+   * Called after the modifyTable operation has been requested.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
+   * @param htd the HTableDescriptor
    */
   void postModifyTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       final byte[] tableName, HTableDescriptor htd) throws IOException;
 
   /**
    * Called prior to adding a new column family to the table.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
+   * @param column the HColumnDescriptor
    */
   void preAddColumn(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       byte[] tableName, HColumnDescriptor column) throws IOException;
 
   /**
    * Called after the new column family has been created.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
+   * @param column the HColumnDescriptor
    */
   void postAddColumn(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       byte[] tableName, HColumnDescriptor column) throws IOException;
 
   /**
    * Called prior to modifying a column family's attributes.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
+   * @param descriptor the HColumnDescriptor
    */
   void preModifyColumn(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       byte [] tableName, HColumnDescriptor descriptor) throws IOException;
 
   /**
    * Called after the column family has been updated.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
+   * @param descriptor the HColumnDescriptor
    */
   void postModifyColumn(final ObserverContext<MasterCoprocessorEnvironment> 
ctx,
       byte[] tableName, HColumnDescriptor descriptor) throws IOException;
 
   /**
    * Called prior to deleting the entire column family.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
+   * @param c the column
    */
   void preDeleteColumn(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       final byte [] tableName, final byte[] c) throws IOException;
 
   /**
    * Called after the column family has been deleted.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
+   * @param c the column
    */
   void postDeleteColumn(final ObserverContext<MasterCoprocessorEnvironment> 
ctx,
       final byte [] tableName, final byte[] c) throws IOException;
 
   /**
    * Called prior to enabling a table.
+   * It can't bypass the default action, e.g., ctx.bypass() won't have effect.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
    */
   void preEnableTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       final byte[] tableName) throws IOException;
 
   /**
-   * Called after the table has been enabled.
+   * Called after the enableTable operation has been requested.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
    */
   void postEnableTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       final byte[] tableName) throws IOException;
 
   /**
    * Called prior to disabling a table.
+   * It can't bypass the default action, e.g., ctx.bypass() won't have effect.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
    */
   void preDisableTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       final byte[] tableName) throws IOException;
 
   /**
-   * Called after the table has been disabled.
+   * Called after the disableTable operation has been requested.
+   * @param ctx the environment to interact with the framework and master
+   * @param tableName the name of the table
    */
   void postDisableTable(final ObserverContext<MasterCoprocessorEnvironment> 
ctx,
       final byte[] tableName) throws IOException;
 
   /**
    * Called prior to moving a given region from one region server to another.
+   * @param ctx the environment to interact with the framework and master
+   * @param region the HRegionInfo
+   * @param srcServer the source ServerName
+   * @param destServer the destination ServerName
    */
   void preMove(final ObserverContext<MasterCoprocessorEnvironment> ctx,
-      final HRegionInfo region, final ServerName srcServer, final ServerName 
destServer)
+      final HRegionInfo region, final ServerName srcServer,
+      final ServerName destServer)
     throws UnknownRegionException;
 
   /**
    * Called after the region move has been requested.
+   * @param ctx the environment to interact with the framework and master
+   * @param region the HRegionInfo
+   * @param srcServer the source ServerName
+   * @param destServer the destination ServerName
    */
   void postMove(final ObserverContext<MasterCoprocessorEnvironment> ctx,
-      final HRegionInfo region, final ServerName srcServer, final ServerName 
destServer)
+      final HRegionInfo region, final ServerName srcServer,
+      final ServerName destServer)
     throws UnknownRegionException;
 
   /**
    * Called prior to assigning a specific region.
+   * @param ctx the environment to interact with the framework and master
+   * @param regionInfo the regionInfo of the region
+   * @param force whether to force assignment or not
    */
   void preAssign(final ObserverContext<MasterCoprocessorEnvironment> ctx,
-      final byte [] regionName, final boolean force)
+      final HRegionInfo regionInfo, final boolean force)
   throws IOException;
 
   /**
    * Called after the region assignment has been requested.
+   * @param ctx the environment to interact with the framework and master
+   * @param regionInfo the regionInfo of the region
+   * @param force whether to force assignment or not
    */
   void postAssign(final ObserverContext<MasterCoprocessorEnvironment> ctx,
-      final HRegionInfo regionInfo) throws IOException;
+      final HRegionInfo regionInfo, final boolean force) throws IOException;
 
   /**
    * Called prior to unassigning a given region.
+   * @param ctx the environment to interact with the framework and master
+   * @param regionName the name of the region
+   * @param force whether to force unassignment or not
    */
   void preUnassign(final ObserverContext<MasterCoprocessorEnvironment> ctx,
-      final byte [] regionName, final boolean force) throws IOException;
+      final HRegionInfo regionInfo, final boolean force) throws IOException;
 
   /**
    * Called after the region unassignment has been requested.
+   * @param ctx the environment to interact with the framework and master
+   * @param regionName the name of the region
+   * @param force whether to force unassignment or not
    */
   void postUnassign(final ObserverContext<MasterCoprocessorEnvironment> ctx,
       final HRegionInfo regionInfo, final boolean force) throws IOException;
@@ -176,12 +241,14 @@ public interface MasterObserver extends 
   /**
    * Called prior to requesting rebalancing of the cluster regions, though 
after
    * the initial checks for regions in transition and the balance switch flag.
+   * @param ctx the environment to interact with the framework and master
    */
   void preBalance(final ObserverContext<MasterCoprocessorEnvironment> ctx)
       throws IOException;
 
   /**
    * Called after the balancing plan has been submitted.
+   * @param ctx the environment to interact with the framework and master
    */
   void postBalance(final ObserverContext<MasterCoprocessorEnvironment> ctx)
       throws IOException;
@@ -212,7 +279,7 @@ public interface MasterObserver extends 
 
 
   /**
-   * Called immediatly prior to stopping this
+   * Called immediately prior to stopping this
    * {@link org.apache.hadoop.hbase.master.HMaster} process.
    */
   void preStopMaster(final ObserverContext<MasterCoprocessorEnvironment> ctx)

Modified: 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java?rev=1166540&r1=1166539&r2=1166540&view=diff
==============================================================================
--- 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java 
(original)
+++ 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java 
Thu Sep  8 06:49:35 2011
@@ -2047,10 +2047,12 @@ public class AssignmentManager extends Z
             watcher.assignmentZNode);
       }
       for (String tableName : enablingTables) {
-        // Recover by calling DisableTableHandler
+        // Recover by calling EnableTableHandler
         LOG.info("The table " + tableName
             + " is in ENABLING state.  Hence recovering by moving the table"
             + " to ENABLED state.");
+        // enableTable in sync way during master startup,
+        // no need to invoke coprocessor
         new EnableTableHandler(this.master, tableName.getBytes(),
             catalogTracker, this, true).process();
       }

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/HMaster.java?rev=1166540&r1=1166539&r2=1166540&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/HMaster.java 
(original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/HMaster.java Thu 
Sep  8 06:49:35 2011
@@ -922,7 +922,9 @@ implements HMasterInterface, HMasterRegi
     } else {
       dest = new ServerName(Bytes.toString(destServerName));
       if (this.cpHost != null) {
-        this.cpHost.preMove(p.getFirst(), p.getSecond(), dest);
+        if (this.cpHost.preMove(p.getFirst(), p.getSecond(), dest)) {
+          return;
+        }
       }
       RegionPlan rp = new RegionPlan(p.getFirst(), p.getSecond(), dest);
       LOG.info("Added move plan " + rp + ", running balancer");
@@ -939,18 +941,18 @@ implements HMasterInterface, HMasterRegi
     if (!isMasterRunning()) {
       throw new MasterNotRunningException();
     }
+
+    HRegionInfo [] newRegions = getHRegionInfos(hTableDescriptor, splitKeys);
     if (cpHost != null) {
-      cpHost.preCreateTable(hTableDescriptor, splitKeys);
+      cpHost.preCreateTable(hTableDescriptor, newRegions);
     }
-    HRegionInfo [] newRegions = getHRegionInfos(hTableDescriptor, splitKeys);
 
     this.executorService.submit(new CreateTableHandler(this,
       this.fileSystemManager, this.serverManager, hTableDescriptor, conf,
       newRegions, catalogTracker, assignmentManager));
 
     if (cpHost != null) {
-      // TODO, remove sync parameter from postCreateTable method
-      cpHost.postCreateTable(newRegions, false);
+      cpHost.postCreateTable(hTableDescriptor, newRegions);
     }
   }
 
@@ -986,6 +988,7 @@ implements HMasterInterface, HMasterRegi
       cpHost.preDeleteTable(tableName);
     }
     this.executorService.submit(new DeleteTableHandler(tableName, this, this));
+
     if (cpHost != null) {
       cpHost.postDeleteTable(tableName);
     }
@@ -1006,7 +1009,9 @@ implements HMasterInterface, HMasterRegi
   public void addColumn(byte [] tableName, HColumnDescriptor column)
   throws IOException {
     if (cpHost != null) {
-      cpHost.preAddColumn(tableName, column);
+      if (cpHost.preAddColumn(tableName, column)) {
+        return;
+      }
     }
     new TableAddFamilyHandler(tableName, column, this, this).process();
     if (cpHost != null) {
@@ -1017,7 +1022,9 @@ implements HMasterInterface, HMasterRegi
   public void modifyColumn(byte [] tableName, HColumnDescriptor descriptor)
   throws IOException {
     if (cpHost != null) {
-      cpHost.preModifyColumn(tableName, descriptor);
+      if (cpHost.preModifyColumn(tableName, descriptor)) {
+        return;
+      }
     }
     new TableModifyFamilyHandler(tableName, descriptor, this, this).process();
     if (cpHost != null) {
@@ -1028,7 +1035,9 @@ implements HMasterInterface, HMasterRegi
   public void deleteColumn(final byte [] tableName, final byte [] c)
   throws IOException {
     if (cpHost != null) {
-      cpHost.preDeleteColumn(tableName, c);
+      if (cpHost.preDeleteColumn(tableName, c)) {
+        return;
+      }
     }
     new TableDeleteFamilyHandler(tableName, c, this, this).process();
     if (cpHost != null) {
@@ -1042,6 +1051,7 @@ implements HMasterInterface, HMasterRegi
     }
     this.executorService.submit(new EnableTableHandler(this, tableName,
       catalogTracker, assignmentManager, false));
+
     if (cpHost != null) {
       cpHost.postEnableTable(tableName);
     }
@@ -1053,6 +1063,7 @@ implements HMasterInterface, HMasterRegi
     }
     this.executorService.submit(new DisableTableHandler(this, tableName,
       catalogTracker, assignmentManager, false));
+
     if (cpHost != null) {
       cpHost.postDisableTable(tableName);
     }
@@ -1099,7 +1110,10 @@ implements HMasterInterface, HMasterRegi
     if (cpHost != null) {
       cpHost.preModifyTable(tableName, htd);
     }
-    this.executorService.submit(new ModifyTableHandler(tableName, htd, this, 
this));
+
+    this.executorService.submit(new ModifyTableHandler(tableName, htd, this,
+      this));
+
     if (cpHost != null) {
       cpHost.postModifyTable(tableName, htd);
     }
@@ -1319,17 +1333,17 @@ implements HMasterInterface, HMasterRegi
   @Override
   public void assign(final byte [] regionName, final boolean force)
   throws IOException {
+    Pair<HRegionInfo, ServerName> pair =
+      MetaReader.getRegion(this.catalogTracker, regionName);
+    if (pair == null) throw new 
UnknownRegionException(Bytes.toString(regionName));
     if (cpHost != null) {
-      if (cpHost.preAssign(regionName, force)) {
+      if (cpHost.preAssign(pair.getFirst(), force)) {
         return;
       }
     }
-    Pair<HRegionInfo, ServerName> pair =
-      MetaReader.getRegion(this.catalogTracker, regionName);
-    if (pair == null) throw new 
UnknownRegionException(Bytes.toString(regionName));
     assignRegion(pair.getFirst());
     if (cpHost != null) {
-      cpHost.postAssign(pair.getFirst());
+      cpHost.postAssign(pair.getFirst(), force);
     }
   }
 
@@ -1340,15 +1354,15 @@ implements HMasterInterface, HMasterRegi
   @Override
   public void unassign(final byte [] regionName, final boolean force)
   throws IOException {
-    if (cpHost != null) {
-      if (cpHost.preUnassign(regionName, force)) {
-        return;
-      }
-    }
     Pair<HRegionInfo, ServerName> pair =
       MetaReader.getRegion(this.catalogTracker, regionName);
     if (pair == null) throw new 
UnknownRegionException(Bytes.toString(regionName));
     HRegionInfo hri = pair.getFirst();
+    if (cpHost != null) {
+      if (cpHost.preUnassign(hri, force)) {
+        return;
+      }
+    }
     if (force) this.assignmentManager.clearRegionFromTransition(hri);
     this.assignmentManager.unassign(hri, force);
     if (cpHost != null) {

Modified: 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java?rev=1166540&r1=1166539&r2=1166540&view=diff
==============================================================================
--- 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
 (original)
+++ 
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
 Thu Sep  8 06:49:35 2011
@@ -70,13 +70,13 @@ public class MasterCoprocessorHost
   }
 
   /* Implementation of hooks for invoking MasterObservers */
-  void preCreateTable(HTableDescriptor desc, byte[][] splitKeys)
-      throws IOException {
+  void preCreateTable(HTableDescriptor htd, HRegionInfo[] regions)
+    throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
         ctx = ObserverContext.createAndPrepare(env, ctx);
-        ((MasterObserver)env.getInstance()).preCreateTable(ctx, desc, 
splitKeys);
+        ((MasterObserver)env.getInstance()).preCreateTable(ctx, htd, regions);
         if (ctx.shouldComplete()) {
           break;
         }
@@ -84,12 +84,13 @@ public class MasterCoprocessorHost
     }
   }
 
-  void postCreateTable(HRegionInfo[] regions, boolean sync) throws IOException 
{
+  void postCreateTable(HTableDescriptor htd, HRegionInfo[] regions)
+    throws IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
         ctx = ObserverContext.createAndPrepare(env, ctx);
-        ((MasterObserver)env.getInstance()).postCreateTable(ctx, regions, 
sync);
+        ((MasterObserver)env.getInstance()).postCreateTable(ctx, htd, regions);
         if (ctx.shouldComplete()) {
           break;
         }
@@ -151,18 +152,21 @@ public class MasterCoprocessorHost
     }
   }
 
-  void preAddColumn(byte [] tableName, HColumnDescriptor column)
+  boolean preAddColumn(byte [] tableName, HColumnDescriptor column)
       throws IOException {
+    boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
         ctx = ObserverContext.createAndPrepare(env, ctx);
         ((MasterObserver)env.getInstance()).preAddColumn(ctx, tableName, 
column);
+        bypass |= ctx.shouldBypass();
         if (ctx.shouldComplete()) {
           break;
         }
       }
     }
+    return bypass;
   }
 
   void postAddColumn(byte [] tableName, HColumnDescriptor column)
@@ -179,19 +183,22 @@ public class MasterCoprocessorHost
     }
   }
 
-  void preModifyColumn(byte [] tableName, HColumnDescriptor descriptor)
+  boolean preModifyColumn(byte [] tableName, HColumnDescriptor descriptor)
       throws IOException {
+    boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
         ctx = ObserverContext.createAndPrepare(env, ctx);
         ((MasterObserver)env.getInstance()).preModifyColumn(
             ctx, tableName, descriptor);
+        bypass |= ctx.shouldBypass();
         if (ctx.shouldComplete()) {
           break;
         }
       }
     }
+    return bypass;
   }
 
   void postModifyColumn(byte [] tableName, HColumnDescriptor descriptor)
@@ -209,18 +216,21 @@ public class MasterCoprocessorHost
     }
   }
 
-  void preDeleteColumn(final byte [] tableName, final byte [] c)
+  boolean preDeleteColumn(final byte [] tableName, final byte [] c)
       throws IOException {
+    boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
         ctx = ObserverContext.createAndPrepare(env, ctx);
         ((MasterObserver)env.getInstance()).preDeleteColumn(ctx, tableName, c);
+        bypass |= ctx.shouldBypass();
         if (ctx.shouldComplete()) {
           break;
         }
       }
     }
+    return bypass;
   }
 
   void postDeleteColumn(final byte [] tableName, final byte [] c)
@@ -289,19 +299,22 @@ public class MasterCoprocessorHost
     }
   }
 
-  void preMove(final HRegionInfo region, final ServerName srcServer, final 
ServerName destServer)
+  boolean preMove(final HRegionInfo region, final ServerName srcServer, final 
ServerName destServer)
       throws UnknownRegionException {
+    boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
         ctx = ObserverContext.createAndPrepare(env, ctx);
         ((MasterObserver)env.getInstance()).preMove(
             ctx, region, srcServer, destServer);
+        bypass |= ctx.shouldBypass();
         if (ctx.shouldComplete()) {
           break;
         }
       }
     }
+    return bypass;
   }
 
   void postMove(final HRegionInfo region, final ServerName srcServer, final 
ServerName destServer)
@@ -319,14 +332,14 @@ public class MasterCoprocessorHost
     }
   }
 
-  boolean preAssign(final byte [] regionName, final boolean force)
+  boolean preAssign(final HRegionInfo regionInfo, final boolean force)
       throws IOException {
     boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
         ctx = ObserverContext.createAndPrepare(env, ctx);
-        ((MasterObserver)env.getInstance()).preAssign(ctx, regionName, force);
+        ((MasterObserver)env.getInstance()).preAssign(ctx, regionInfo, force);
         bypass |= ctx.shouldBypass();
         if (ctx.shouldComplete()) {
           break;
@@ -336,12 +349,12 @@ public class MasterCoprocessorHost
     return bypass;
   }
 
-  void postAssign(final HRegionInfo regionInfo) throws IOException {
+  void postAssign(final HRegionInfo regionInfo, final boolean force) throws 
IOException {
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
     for (MasterEnvironment env: coprocessors) {
       if (env.getInstance() instanceof MasterObserver) {
         ctx = ObserverContext.createAndPrepare(env, ctx);
-        ((MasterObserver)env.getInstance()).postAssign(ctx, regionInfo);
+        ((MasterObserver)env.getInstance()).postAssign(ctx, regionInfo, force);
         if (ctx.shouldComplete()) {
           break;
         }
@@ -349,7 +362,7 @@ public class MasterCoprocessorHost
     }
   }
 
-  boolean preUnassign(final byte [] regionName, final boolean force)
+  boolean preUnassign(final HRegionInfo regionInfo, final boolean force)
       throws IOException {
     boolean bypass = false;
     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
@@ -357,7 +370,7 @@ public class MasterCoprocessorHost
       if (env.getInstance() instanceof MasterObserver) {
         ctx = ObserverContext.createAndPrepare(env, ctx);
         ((MasterObserver)env.getInstance()).preUnassign(
-            ctx, regionName, force);
+            ctx, regionInfo, force);
         bypass |= ctx.shouldBypass();
         if (ctx.shouldComplete()) {
           break;

Modified: 
hbase/trunk/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java?rev=1166540&r1=1166539&r2=1166540&view=diff
==============================================================================
--- 
hbase/trunk/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java
 (original)
+++ 
hbase/trunk/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java
 Thu Sep  8 06:49:35 2011
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010 The Apache Software Foundation
+ * Copyright 2011 The Apache Software Foundation
  *
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -59,6 +59,7 @@ public class TestMasterObserver {
 
   public static class CPMasterObserver implements MasterObserver {
 
+    private boolean bypass = false;
     private boolean preCreateTableCalled;
     private boolean postCreateTableCalled;
     private boolean preDeleteTableCalled;
@@ -91,15 +92,51 @@ public class TestMasterObserver {
     private boolean startCalled;
     private boolean stopCalled;
 
+    public void enableBypass(boolean bypass) {
+      this.bypass = bypass;
+    }
+
+    public void resetStates() {
+      preCreateTableCalled = false;
+      postCreateTableCalled = false;
+      preDeleteTableCalled = false;
+      postDeleteTableCalled = false;
+      preModifyTableCalled = false;
+      postModifyTableCalled = false;
+      preAddColumnCalled = false;
+      postAddColumnCalled = false;
+      preModifyColumnCalled = false;
+      postModifyColumnCalled = false;
+      preDeleteColumnCalled = false;
+      postDeleteColumnCalled = false;
+      preEnableTableCalled = false;
+      postEnableTableCalled = false;
+      preDisableTableCalled = false;
+      postDisableTableCalled = false;
+      preMoveCalled= false;
+      postMoveCalled = false;
+      preAssignCalled = false;
+      postAssignCalled = false;
+      preUnassignCalled = false;
+      postUnassignCalled = false;
+      preBalanceCalled = false;
+      postBalanceCalled = false;
+      preBalanceSwitchCalled = false;
+      postBalanceSwitchCalled = false;
+    }
+
     @Override
     public void preCreateTable(ObserverContext<MasterCoprocessorEnvironment> 
env,
-        HTableDescriptor desc, byte[][] splitKeys) throws IOException {
+        HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preCreateTableCalled = true;
     }
 
     @Override
     public void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> 
env,
-        HRegionInfo[] regions, boolean sync) throws IOException {
+        HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
       postCreateTableCalled = true;
     }
 
@@ -107,9 +144,16 @@ public class TestMasterObserver {
       return preCreateTableCalled && postCreateTableCalled;
     }
 
+    public boolean preCreateTableCalledOnly() {
+      return preCreateTableCalled && !postCreateTableCalled;
+    }
+
     @Override
     public void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> 
env,
         byte[] tableName) throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preDeleteTableCalled = true;
     }
 
@@ -123,9 +167,16 @@ public class TestMasterObserver {
       return preDeleteTableCalled && postDeleteTableCalled;
     }
 
+    public boolean preDeleteTableCalledOnly() {
+      return preDeleteTableCalled && !postDeleteTableCalled;
+    }
+
     @Override
     public void preModifyTable(ObserverContext<MasterCoprocessorEnvironment> 
env,
         byte[] tableName, HTableDescriptor htd) throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preModifyTableCalled = true;
     }
 
@@ -139,9 +190,16 @@ public class TestMasterObserver {
       return preModifyTableCalled && postModifyTableCalled;
     }
 
+    public boolean preModifyTableCalledOnly() {
+      return preModifyTableCalled && !postModifyTableCalled;
+    }
+
     @Override
     public void preAddColumn(ObserverContext<MasterCoprocessorEnvironment> env,
         byte[] tableName, HColumnDescriptor column) throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preAddColumnCalled = true;
     }
 
@@ -155,9 +213,16 @@ public class TestMasterObserver {
       return preAddColumnCalled && postAddColumnCalled;
     }
 
+    public boolean preAddColumnCalledOnly() {
+      return preAddColumnCalled && !postAddColumnCalled;
+    }
+
     @Override
     public void preModifyColumn(ObserverContext<MasterCoprocessorEnvironment> 
env,
         byte[] tableName, HColumnDescriptor descriptor) throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preModifyColumnCalled = true;
     }
 
@@ -171,9 +236,16 @@ public class TestMasterObserver {
       return preModifyColumnCalled && postModifyColumnCalled;
     }
 
+    public boolean preModifyColumnCalledOnly() {
+      return preModifyColumnCalled && !postModifyColumnCalled;
+    }
+
     @Override
     public void preDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> 
env,
         byte[] tableName, byte[] c) throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preDeleteColumnCalled = true;
     }
 
@@ -187,9 +259,16 @@ public class TestMasterObserver {
       return preDeleteColumnCalled && postDeleteColumnCalled;
     }
 
+    public boolean preDeleteColumnCalledOnly() {
+      return preDeleteColumnCalled && !postDeleteColumnCalled;
+    }
+
     @Override
     public void preEnableTable(ObserverContext<MasterCoprocessorEnvironment> 
env,
         byte[] tableName) throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preEnableTableCalled = true;
     }
 
@@ -203,9 +282,16 @@ public class TestMasterObserver {
       return preEnableTableCalled && postEnableTableCalled;
     }
 
+    public boolean preEnableTableCalledOnly() {
+      return preEnableTableCalled && !postEnableTableCalled;
+    }
+
     @Override
     public void preDisableTable(ObserverContext<MasterCoprocessorEnvironment> 
env,
         byte[] tableName) throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preDisableTableCalled = true;
     }
 
@@ -219,10 +305,17 @@ public class TestMasterObserver {
       return preDisableTableCalled && postDisableTableCalled;
     }
 
+    public boolean preDisableTableCalledOnly() {
+      return preDisableTableCalled && !postDisableTableCalled;
+    }
+
     @Override
     public void preMove(ObserverContext<MasterCoprocessorEnvironment> env,
         HRegionInfo region, ServerName srcServer, ServerName destServer)
     throws UnknownRegionException {
+      if (bypass) {
+        env.bypass();
+      }
       preMoveCalled = true;
     }
 
@@ -237,15 +330,22 @@ public class TestMasterObserver {
       return preMoveCalled && postMoveCalled;
     }
 
+    public boolean preMoveCalledOnly() {
+      return preMoveCalled && !postMoveCalled;
+    }
+
     @Override
     public void preAssign(ObserverContext<MasterCoprocessorEnvironment> env,
-        final byte [] regionName, final boolean force) throws IOException {
+        final HRegionInfo regionInfo, final boolean force) throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preAssignCalled = true;
     }
 
     @Override
     public void postAssign(ObserverContext<MasterCoprocessorEnvironment> env,
-        final HRegionInfo regionInfo) throws IOException {
+        final HRegionInfo regionInfo, final boolean force) throws IOException {
       postAssignCalled = true;
     }
 
@@ -253,9 +353,16 @@ public class TestMasterObserver {
       return preAssignCalled && postAssignCalled;
     }
 
+    public boolean preAssignCalledOnly() {
+      return preAssignCalled && !postAssignCalled;
+    }
+
     @Override
     public void preUnassign(ObserverContext<MasterCoprocessorEnvironment> env,
-        final byte [] regionName, final boolean force) throws IOException {
+        final HRegionInfo regionInfo, final boolean force) throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preUnassignCalled = true;
     }
 
@@ -269,9 +376,16 @@ public class TestMasterObserver {
       return preUnassignCalled && postUnassignCalled;
     }
 
+    public boolean preUnassignCalledOnly() {
+      return preUnassignCalled && !postUnassignCalled;
+    }
+
     @Override
     public void preBalance(ObserverContext<MasterCoprocessorEnvironment> env)
         throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preBalanceCalled = true;
     }
 
@@ -285,9 +399,16 @@ public class TestMasterObserver {
       return preBalanceCalled && postBalanceCalled;
     }
 
+    public boolean preBalanceCalledOnly() {
+      return preBalanceCalled && !postBalanceCalled;
+    }
+
     @Override
     public boolean 
preBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> env, boolean b)
         throws IOException {
+      if (bypass) {
+        env.bypass();
+      }
       preBalanceSwitchCalled = true;
       return b;
     }
@@ -302,6 +423,10 @@ public class TestMasterObserver {
       return preBalanceSwitchCalled && postBalanceSwitchCalled;
     }
 
+    public boolean preBalanceSwitchCalledOnly() {
+      return preBalanceSwitchCalled && !postBalanceSwitchCalled;
+    }
+
     @Override
     public void preShutdown(ObserverContext<MasterCoprocessorEnvironment> env)
         throws IOException {
@@ -384,21 +509,78 @@ public class TestMasterObserver {
     MasterCoprocessorHost host = master.getCoprocessorHost();
     CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
         CPMasterObserver.class.getName());
+    cp.enableBypass(true);
+    cp.resetStates();
     assertFalse("No table created yet", cp.wasCreateTableCalled());
 
     // create a table
     HTableDescriptor htd = new HTableDescriptor(TEST_TABLE);
     htd.addFamily(new HColumnDescriptor(TEST_FAMILY));
     HBaseAdmin admin = UTIL.getHBaseAdmin();
+
+    admin.createTable(htd);
+    // preCreateTable can't bypass default action.
+    assertTrue("Test table should be created", cp.wasCreateTableCalled());
+
+    admin.disableTable(TEST_TABLE);
+    assertTrue(admin.isTableDisabled(TEST_TABLE));
+    // preDisableTable can't bypass default action.
+    assertTrue("Coprocessor should have been called on table disable",
+      cp.wasDisableTableCalled());
+
+    // enable
+    assertFalse(cp.wasEnableTableCalled());
+    admin.enableTable(TEST_TABLE);
+    assertTrue(admin.isTableEnabled(TEST_TABLE));
+    // preEnableTable can't bypass default action.
+    assertTrue("Coprocessor should have been called on table enable",
+      cp.wasEnableTableCalled());
+
+    admin.disableTable(TEST_TABLE);
+    assertTrue(admin.isTableDisabled(TEST_TABLE));
+
+    // modify table
+    htd.setMaxFileSize(512 * 1024 * 1024);
+    admin.modifyTable(TEST_TABLE, htd);
+    // preModifyTable can't bypass default action.
+    assertTrue("Test table should have been modified",
+      cp.wasModifyTableCalled());
+
+    // add a column family
+    admin.addColumn(TEST_TABLE, new HColumnDescriptor(TEST_FAMILY2));
+    assertTrue("New column family shouldn't have been added to test table",
+      cp.preAddColumnCalledOnly());
+
+    // modify a column family
+    HColumnDescriptor hcd1 = new HColumnDescriptor(TEST_FAMILY2);
+    hcd1.setMaxVersions(25);
+    admin.modifyColumn(TEST_TABLE, hcd1);
+    assertTrue("Second column family should be modified",
+      cp.preModifyColumnCalledOnly());
+
+    // delete table
+    admin.deleteTable(TEST_TABLE);
+    assertFalse("Test table should have been deleted",
+        admin.tableExists(TEST_TABLE));
+    // preDeleteTable can't bypass default action.
+    assertTrue("Coprocessor should have been called on table delete",
+      cp.wasDeleteTableCalled());
+
+
+    // turn off bypass, run the tests again
+    cp.enableBypass(false);
+    cp.resetStates();
+
     admin.createTable(htd);
     assertTrue("Test table should be created", cp.wasCreateTableCalled());
 
     // disable
     assertFalse(cp.wasDisableTableCalled());
+
     admin.disableTable(TEST_TABLE);
     assertTrue(admin.isTableDisabled(TEST_TABLE));
     assertTrue("Coprocessor should have been called on table disable",
-        cp.wasDisableTableCalled());
+      cp.wasDisableTableCalled());
 
     // modify table
     htd.setMaxFileSize(512 * 1024 * 1024);
@@ -455,6 +637,8 @@ public class TestMasterObserver {
     MasterCoprocessorHost host = master.getCoprocessorHost();
     CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor(
         CPMasterObserver.class.getName());
+    cp.enableBypass(false);
+    cp.resetStates();
 
     HTable table = UTIL.createTable(TEST_TABLE, TEST_FAMILY);
     UTIL.createMultiRegions(table, TEST_FAMILY);


Reply via email to