You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2017/07/24 09:41:15 UTC

[2/2] hbase git commit: HBASE-18367 Reduce ProcedureInfo usage

HBASE-18367 Reduce ProcedureInfo usage

Signed-off-by: Michael Stack <st...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/8f006582
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/8f006582
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/8f006582

Branch: refs/heads/master
Commit: 8f006582e30b106f0d9841c520250dfd6db4a689
Parents: e9d8a7b
Author: Balazs Meszaros <ba...@cloudera.com>
Authored: Wed Jul 12 10:02:49 2017 +0200
Committer: Michael Stack <st...@apache.org>
Committed: Mon Jul 24 10:41:03 2017 +0100

----------------------------------------------------------------------
 .../hadoop/hbase/procedure2/Procedure.java      |  10 +-
 .../hbase/procedure2/ProcedureExecutor.java     | 204 ++++++++++++-------
 .../hbase/procedure2/store/ProcedureStore.java  |   8 +-
 .../store/wal/ProcedureWALFormatReader.java     |  16 +-
 .../procedure2/ProcedureTestingUtility.java     |  27 ++-
 .../hbase/procedure2/TestChildProcedures.java   |   8 +-
 .../procedure2/TestProcedureExecution.java      |  13 +-
 .../hbase/procedure2/TestProcedureNonce.java    |   8 +-
 .../hbase/procedure2/TestProcedureRecovery.java |  13 +-
 ...ProcedureWALLoaderPerformanceEvaluation.java |  10 +-
 .../store/wal/TestWALProcedureStore.java        |  12 +-
 .../hbase/rsgroup/RSGroupInfoManagerImpl.java   |   7 +-
 .../org/apache/hadoop/hbase/master/HMaster.java |  22 +-
 .../hadoop/hbase/master/MasterRpcServices.java  |  39 ++--
 .../master/procedure/ProcedureSyncWait.java     |   7 +-
 .../hbase-webapps/master/procedures.jsp         |  27 +--
 .../hbase/master/locking/TestLockManager.java   |   4 +-
 .../hbase/master/locking/TestLockProcedure.java |  12 +-
 .../procedure/TestAddColumnFamilyProcedure.java |   8 +-
 .../procedure/TestCloneSnapshotProcedure.java   |   9 +-
 .../procedure/TestCreateNamespaceProcedure.java |  18 +-
 .../procedure/TestCreateTableProcedure.java     |   4 +-
 .../TestDeleteColumnFamilyProcedure.java        |  12 +-
 .../procedure/TestDeleteNamespaceProcedure.java |  14 +-
 .../procedure/TestDeleteTableProcedure.java     |  10 +-
 .../procedure/TestDisableTableProcedure.java    |   6 +-
 .../procedure/TestEnableTableProcedure.java     |   6 +-
 .../TestModifyColumnFamilyProcedure.java        |   6 +-
 .../procedure/TestModifyNamespaceProcedure.java |  18 +-
 .../procedure/TestModifyTableProcedure.java     |   4 +-
 .../master/procedure/TestProcedureAdmin.java    |  19 +-
 .../procedure/TestRestoreSnapshotProcedure.java |  17 +-
 .../procedure/TestTruncateTableProcedure.java   |  13 +-
 .../security/access/TestAccessController.java   |  13 +-
 34 files changed, 325 insertions(+), 299 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/Procedure.java
----------------------------------------------------------------------
diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/Procedure.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/Procedure.java
index 8b9dc48..335e83c 100644
--- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/Procedure.java
+++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/Procedure.java
@@ -183,7 +183,7 @@ public abstract class Procedure<TEnvironment> implements Comparable<Procedure<TE
    * A lock can be anything, and it is up to the implementor. The Procedure
    * Framework will call this method just before it invokes {@link #execute(Object)}.
    * It calls {@link #releaseLock(Object)} after the call to execute.
-   * 
+   *
    * <p>If you need to hold the lock for the life of the Procdure -- i.e. you do not
    * want any other Procedure interfering while this Procedure is running, see
    * {@link #holdLock(Object)}.
@@ -466,6 +466,10 @@ public abstract class Procedure<TEnvironment> implements Comparable<Procedure<TE
     return rootProcId;
   }
 
+  public String getProcName() {
+    return toStringClass();
+  }
+
   public NonceKey getNonceKey() {
     return nonceKey;
   }
@@ -625,7 +629,7 @@ public abstract class Procedure<TEnvironment> implements Comparable<Procedure<TE
   /**
    * @return true if the procedure is in a RUNNABLE state.
    */
-  protected synchronized boolean isRunnable() {
+  public synchronized boolean isRunnable() {
     return state == ProcedureState.RUNNABLE;
   }
 
@@ -677,7 +681,7 @@ public abstract class Procedure<TEnvironment> implements Comparable<Procedure<TE
   }
 
   @InterfaceAudience.Private
-  protected synchronized ProcedureState getState() {
+  public synchronized ProcedureState getState() {
     return state;
   }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.java
----------------------------------------------------------------------
diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.java
index bc80445..c110c2d 100644
--- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.java
+++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.java
@@ -22,12 +22,15 @@ import org.apache.hadoop.hbase.shaded.com.google.common.annotations.VisibleForTe
 import org.apache.hadoop.hbase.shaded.com.google.common.base.Preconditions;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -43,7 +46,6 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HConstants;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
 import org.apache.hadoop.hbase.classification.InterfaceStability;
 import org.apache.hadoop.hbase.exceptions.IllegalArgumentIOException;
@@ -57,7 +59,6 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.Procedu
 import org.apache.hadoop.hbase.security.User;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.apache.hadoop.hbase.util.NonceKey;
-import org.apache.hadoop.hbase.util.Pair;
 import org.apache.hadoop.hbase.util.Threads;
 
 /**
@@ -111,6 +112,37 @@ public class ProcedureExecutor<TEnvironment> {
     void procedureFinished(long procId);
   }
 
+  private static class CompletedProcedureRetainer {
+    private final Procedure<?> procedure;
+    private long clientAckTime;
+
+    public CompletedProcedureRetainer(Procedure<?> procedure) {
+      this.procedure = procedure;
+      clientAckTime = -1;
+    }
+
+    public Procedure<?> getProcedure() {
+      return procedure;
+    }
+
+    public boolean hasClientAckTime() {
+      return clientAckTime != -1;
+    }
+
+    public long getClientAckTime() {
+      return clientAckTime;
+    }
+
+    public void setClientAckTime(long clientAckTime) {
+      this.clientAckTime = clientAckTime;
+    }
+
+    public boolean isExpired(long now, long evictTtl, long evictAckTtl) {
+      return (hasClientAckTime() && (now - getClientAckTime()) >= evictAckTtl) ||
+        (now - procedure.getLastUpdate()) >= evictTtl;
+    }
+  }
+
   /**
    * Internal cleaner that removes the completed procedure results after a TTL.
    * NOTE: This is a special case handled in timeoutLoop().
@@ -144,13 +176,13 @@ public class ProcedureExecutor<TEnvironment> {
     private static final String BATCH_SIZE_CONF_KEY = "hbase.procedure.cleaner.evict.batch.size";
     private static final int DEFAULT_BATCH_SIZE = 32;
 
-    private final Map<Long, ProcedureInfo> completed;
+    private final Map<Long, CompletedProcedureRetainer> completed;
     private final Map<NonceKey, Long> nonceKeysToProcIdsMap;
     private final ProcedureStore store;
     private Configuration conf;
 
     public CompletedProcedureCleaner(final Configuration conf, final ProcedureStore store,
-        final Map<Long, ProcedureInfo> completedMap,
+        final Map<Long, CompletedProcedureRetainer> completedMap,
         final Map<NonceKey, Long> nonceKeysToProcIdsMap) {
       // set the timeout interval that triggers the periodic-procedure
       super(conf.getInt(CLEANER_INTERVAL_CONF_KEY, DEFAULT_CLEANER_INTERVAL));
@@ -177,17 +209,17 @@ public class ProcedureExecutor<TEnvironment> {
       int batchCount = 0;
 
       final long now = EnvironmentEdgeManager.currentTime();
-      final Iterator<Map.Entry<Long, ProcedureInfo>> it = completed.entrySet().iterator();
+      final Iterator<Map.Entry<Long, CompletedProcedureRetainer>> it = completed.entrySet().iterator();
       final boolean debugEnabled = LOG.isDebugEnabled();
       while (it.hasNext() && store.isRunning()) {
-        final Map.Entry<Long, ProcedureInfo> entry = it.next();
-        final ProcedureInfo procInfo = entry.getValue();
+        final Map.Entry<Long, CompletedProcedureRetainer> entry = it.next();
+        final CompletedProcedureRetainer retainer = entry.getValue();
+        final Procedure<?> proc = retainer.getProcedure();
 
         // TODO: Select TTL based on Procedure type
-        if ((procInfo.hasClientAckTime() && (now - procInfo.getClientAckTime()) >= evictAckTtl) ||
-            (now - procInfo.getLastUpdate()) >= evictTtl) {
+        if (retainer.isExpired(now, evictTtl, evictAckTtl)) {
           if (debugEnabled) {
-            LOG.debug("Evict completed " + procInfo);
+            LOG.debug("Evict completed " + proc);
           }
           batchIds[batchCount++] = entry.getKey();
           if (batchCount == batchIds.length) {
@@ -196,7 +228,7 @@ public class ProcedureExecutor<TEnvironment> {
           }
           it.remove();
 
-          final NonceKey nonceKey = procInfo.getNonceKey();
+          final NonceKey nonceKey = proc.getNonceKey();
           if (nonceKey != null) {
             nonceKeysToProcIdsMap.remove(nonceKey);
           }
@@ -213,7 +245,7 @@ public class ProcedureExecutor<TEnvironment> {
    * Once a Root-Procedure completes (success or failure), the result will be added to this map.
    * The user of ProcedureExecutor should call getResult(procId) to get the result.
    */
-  private final ConcurrentHashMap<Long, ProcedureInfo> completed = new ConcurrentHashMap<>();
+  private final ConcurrentHashMap<Long, CompletedProcedureRetainer> completed = new ConcurrentHashMap<>();
 
   /**
    * Map the the procId returned by submitProcedure(), the Root-ProcID, to the RootProcedureState.
@@ -296,7 +328,7 @@ public class ProcedureExecutor<TEnvironment> {
       public void handleCorrupted(ProcedureIterator procIter) throws IOException {
         int corruptedCount = 0;
         while (procIter.hasNext()) {
-          ProcedureInfo proc = procIter.nextAsProcedureInfo();
+          Procedure<?> proc = procIter.next();
           LOG.error("Corrupt " + proc);
           corruptedCount++;
         }
@@ -314,22 +346,17 @@ public class ProcedureExecutor<TEnvironment> {
     // 1. Build the rollback stack
     int runnablesCount = 0;
     while (procIter.hasNext()) {
-      final NonceKey nonceKey;
-      final long procId;
+      boolean finished = procIter.isNextFinished();
+      Procedure proc = procIter.next();
+      NonceKey nonceKey = proc.getNonceKey();
+      long procId = proc.getProcId();
 
-      if (procIter.isNextFinished()) {
-        ProcedureInfo proc = procIter.nextAsProcedureInfo();
-        nonceKey = proc.getNonceKey();
-        procId = proc.getProcId();
-        completed.put(proc.getProcId(), proc);
+      if (finished) {
+        completed.put(proc.getProcId(), new CompletedProcedureRetainer(proc));
         if (debugEnabled) {
           LOG.debug("Completed " + proc);
         }
       } else {
-        Procedure proc = procIter.nextAsProcedure();
-        nonceKey = proc.getNonceKey();
-        procId = proc.getProcId();
-
         if (!proc.hasParent()) {
           assert !proc.isFinished() : "unexpected finished procedure";
           rollbackStack.put(proc.getProcId(), new RootProcedureState());
@@ -360,7 +387,7 @@ public class ProcedureExecutor<TEnvironment> {
         continue;
       }
 
-      Procedure proc = procIter.nextAsProcedure();
+      Procedure proc = procIter.next();
       assert !(proc.isFinished() && !proc.hasParent()) : "unexpected completed proc=" + proc;
 
       if (debugEnabled) {
@@ -723,6 +750,49 @@ public class ProcedureExecutor<TEnvironment> {
     }
   }
 
+  private static class FailedProcedure<TEnvironment> extends Procedure<TEnvironment> {
+    private String procName;
+
+    public FailedProcedure(NonceKey nonceKey, String procName, User owner,
+        IOException exception) {
+      this.procName = procName;
+      setNonceKey(nonceKey);
+      setOwner(owner);
+      setFailure(Objects.toString(exception.getMessage(), ""), exception);
+    }
+
+    @Override
+    public String getProcName() {
+      return procName;
+    }
+
+    @Override
+    protected Procedure<TEnvironment>[] execute(TEnvironment env)
+        throws ProcedureYieldException, ProcedureSuspendedException,
+        InterruptedException {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void rollback(TEnvironment env)
+        throws IOException, InterruptedException {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected boolean abort(TEnvironment env) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected void serializeStateData(OutputStream stream) throws IOException {
+    }
+
+    @Override
+    protected void deserializeStateData(InputStream stream) throws IOException {
+    }
+  }
+
   /**
    * If the failure failed before submitting it, we may want to give back the
    * same error to the requests with the same nonceKey.
@@ -739,12 +809,8 @@ public class ProcedureExecutor<TEnvironment> {
     final Long procId = nonceKeysToProcIdsMap.get(nonceKey);
     if (procId == null || completed.containsKey(procId)) return;
 
-    final long currentTime = EnvironmentEdgeManager.currentTime();
-    final ProcedureInfo result = new ProcedureInfo(procId.longValue(),
-      procName, procOwner != null ? procOwner.getShortName() : null,
-      ProcedureUtil.convertToProcedureState(ProcedureState.ROLLEDBACK),
-      -1, nonceKey, exception, currentTime, currentTime, null);
-    completed.putIfAbsent(procId, result);
+    Procedure proc = new FailedProcedure(nonceKey, procName, procOwner, exception);
+    completed.putIfAbsent(procId, new CompletedProcedureRetainer(proc));
   }
 
   // ==========================================================================
@@ -893,8 +959,13 @@ public class ProcedureExecutor<TEnvironment> {
     return null;
   }
 
-  public ProcedureInfo getResult(final long procId) {
-    return completed.get(procId);
+  public Procedure getResult(final long procId) {
+    CompletedProcedureRetainer retainer = completed.get(procId);
+    if (retainer == null) {
+      return null;
+    } else {
+      return retainer.getProcedure();
+    }
   }
 
   /**
@@ -926,8 +997,8 @@ public class ProcedureExecutor<TEnvironment> {
    * @param procId the ID of the procedure to remove
    */
   public void removeResult(final long procId) {
-    final ProcedureInfo result = completed.get(procId);
-    if (result == null) {
+    CompletedProcedureRetainer retainer = completed.get(procId);
+    if (retainer == null) {
       assert !procedures.containsKey(procId) : "procId=" + procId + " is still running";
       if (LOG.isDebugEnabled()) {
         LOG.debug("procId=" + procId + " already removed by the cleaner.");
@@ -936,19 +1007,16 @@ public class ProcedureExecutor<TEnvironment> {
     }
 
     // The CompletedProcedureCleaner will take care of deletion, once the TTL is expired.
-    result.setClientAckTime(EnvironmentEdgeManager.currentTime());
+    retainer.setClientAckTime(EnvironmentEdgeManager.currentTime());
   }
 
-  public Pair<ProcedureInfo, Procedure> getResultOrProcedure(final long procId) {
-    ProcedureInfo result = completed.get(procId);
-    Procedure proc = null;
-    if (result == null) {
-      proc = procedures.get(procId);
-      if (proc == null) {
-        result = completed.get(procId);
-      }
+  public Procedure getResultOrProcedure(final long procId) {
+    CompletedProcedureRetainer retainer = completed.get(procId);
+    if (retainer == null) {
+      return procedures.get(procId);
+    } else {
+      return retainer.getProcedure();
     }
-    return new Pair(result, proc);
   }
 
   /**
@@ -961,35 +1029,34 @@ public class ProcedureExecutor<TEnvironment> {
   public boolean isProcedureOwner(final long procId, final User user) {
     if (user == null) return false;
 
-    final Procedure proc = procedures.get(procId);
-    if (proc != null) {
-      return proc.getOwner().equals(user.getShortName());
+    final Procedure runningProc = procedures.get(procId);
+    if (runningProc != null) {
+      return runningProc.getOwner().equals(user.getShortName());
     }
 
-    final ProcedureInfo procInfo = completed.get(procId);
-    if (procInfo == null) {
-      // Procedure either does not exist or has already completed and got cleaned up.
-      // At this time, we cannot check the owner of the procedure
-      return false;
+    final CompletedProcedureRetainer retainer = completed.get(procId);
+    if (retainer != null) {
+      return retainer.getProcedure().getOwner().equals(user.getShortName());
     }
-    return ProcedureInfo.isProcedureOwner(procInfo, user);
+
+    // Procedure either does not exist or has already completed and got cleaned up.
+    // At this time, we cannot check the owner of the procedure
+    return false;
   }
 
   /**
    * List procedures.
    * @return the procedures in a list
    */
-  public List<ProcedureInfo> listProcedures() {
-    final List<ProcedureInfo> procedureLists = new ArrayList<>(procedures.size() + completed.size());
-    for (Map.Entry<Long, Procedure> p: procedures.entrySet()) {
-      procedureLists.add(ProcedureUtil.convertToProcedureInfo(p.getValue()));
-    }
-    for (Map.Entry<Long, ProcedureInfo> e: completed.entrySet()) {
-      // Note: The procedure could show up twice in the list with different state, as
-      // it could complete after we walk through procedures list and insert into
-      // procedureList - it is ok, as we will use the information in the ProcedureInfo
-      // to figure it out; to prevent this would increase the complexity of the logic.
-      procedureLists.add(e.getValue());
+  public List<Procedure> listProcedures() {
+    final List<Procedure> procedureLists = new ArrayList<>(procedures.size() + completed.size());
+    procedureLists.addAll(procedures.values());
+    // Note: The procedure could show up twice in the list with different state, as
+    // it could complete after we walk through procedures list and insert into
+    // procedureList - it is ok, as we will use the information in the ProcedureInfo
+    // to figure it out; to prevent this would increase the complexity of the logic.
+    for (CompletedProcedureRetainer retainer: completed.values()) {
+      procedureLists.add(retainer.getProcedure());
     }
     return procedureLists;
   }
@@ -1595,13 +1662,14 @@ public class ProcedureExecutor<TEnvironment> {
     // call the procedure completion cleanup handler
     execCompletionCleanup(proc);
 
+    CompletedProcedureRetainer retainer = new CompletedProcedureRetainer(proc);
+
     // update the executor internal state maps
-    final ProcedureInfo procInfo = ProcedureUtil.convertToProcedureInfo(proc, proc.getNonceKey());
     if (!proc.shouldWaitClientAck(getEnvironment())) {
-      procInfo.setClientAckTime(0);
+      retainer.setClientAckTime(0);
     }
 
-    completed.put(procInfo.getProcId(), procInfo);
+    completed.put(proc.getProcId(), retainer);
     rollbackStack.remove(proc.getProcId());
     procedures.remove(proc.getProcId());
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/ProcedureStore.java
----------------------------------------------------------------------
diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/ProcedureStore.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/ProcedureStore.java
index a690c81..ab14bb1 100644
--- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/ProcedureStore.java
+++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/ProcedureStore.java
@@ -20,7 +20,6 @@ package org.apache.hadoop.hbase.procedure2.store;
 
 import java.io.IOException;
 
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
 import org.apache.hadoop.hbase.classification.InterfaceStability;
 import org.apache.hadoop.hbase.procedure2.Procedure;
@@ -82,12 +81,7 @@ public interface ProcedureStore {
      * @throws IOException if there was an error fetching/deserializing the procedure
      * @return the next procedure in the iteration.
      */
-    Procedure nextAsProcedure() throws IOException;
-
-    /**
-     * @return the next procedure in the iteration as ProcedureInfo.
-     */
-    ProcedureInfo nextAsProcedureInfo();
+    Procedure next() throws IOException;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/wal/ProcedureWALFormatReader.java
----------------------------------------------------------------------
diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/wal/ProcedureWALFormatReader.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/wal/ProcedureWALFormatReader.java
index e528c73..fe098a5 100644
--- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/wal/ProcedureWALFormatReader.java
+++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/wal/ProcedureWALFormatReader.java
@@ -25,7 +25,6 @@ import java.io.IOException;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.fs.FSDataInputStream;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
 import org.apache.hadoop.hbase.classification.InterfaceStability;
 import org.apache.hadoop.hbase.procedure2.Procedure;
@@ -362,10 +361,6 @@ public class ProcedureWALFormatReader {
       return procedure;
     }
 
-    public ProcedureInfo convertToInfo() {
-      return ProcedureUtil.convertToProcedureInfo(proto);
-    }
-
     @Override
     public String toString() {
       final StringBuilder sb = new StringBuilder();
@@ -410,22 +405,13 @@ public class ProcedureWALFormatReader {
     }
 
     @Override
-    public Procedure nextAsProcedure() throws IOException {
+    public Procedure next() throws IOException {
       try {
         return current.convert();
       } finally {
         current = current.replayNext;
       }
     }
-
-    @Override
-    public ProcedureInfo nextAsProcedureInfo() {
-      try {
-        return current.convertToInfo();
-      } finally {
-        current = current.replayNext;
-      }
-    }
   }
 
   private static class WalProcedureMap {

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/ProcedureTestingUtility.java
----------------------------------------------------------------------
diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/ProcedureTestingUtility.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/ProcedureTestingUtility.java
index dd3c8f4..5cdbc35 100644
--- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/ProcedureTestingUtility.java
+++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/ProcedureTestingUtility.java
@@ -35,7 +35,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.HConstants;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.exceptions.IllegalArgumentIOException;
 import org.apache.hadoop.hbase.exceptions.TimeoutIOException;
 import org.apache.hadoop.hbase.io.util.StreamUtils;
@@ -259,45 +258,45 @@ public class ProcedureTestingUtility {
 
   public static <TEnv> void assertProcNotFailed(ProcedureExecutor<TEnv> procExecutor,
       long procId) {
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     assertTrue("expected procedure result", result != null);
     assertProcNotFailed(result);
   }
 
-  public static void assertProcNotFailed(final ProcedureInfo result) {
+  public static void assertProcNotFailed(final Procedure<?> result) {
     assertFalse("found exception: " + result.getException(), result.isFailed());
   }
 
   public static <TEnv> Throwable assertProcFailed(final ProcedureExecutor<TEnv> procExecutor,
       final long procId) {
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     assertTrue("expected procedure result", result != null);
     return assertProcFailed(result);
   }
 
-  public static Throwable assertProcFailed(final ProcedureInfo result) {
+  public static Throwable assertProcFailed(final Procedure<?> result) {
     assertEquals(true, result.isFailed());
     LOG.info("procId=" + result.getProcId() + " exception: " + result.getException().getMessage());
     return getExceptionCause(result);
   }
 
-  public static void assertIsAbortException(final ProcedureInfo result) {
+  public static void assertIsAbortException(final Procedure<?> result) {
     Throwable cause = assertProcFailed(result);
     assertTrue("expected abort exception, got "+ cause, cause instanceof ProcedureAbortedException);
   }
 
-  public static void assertIsTimeoutException(final ProcedureInfo result) {
+  public static void assertIsTimeoutException(final Procedure<?> result) {
     Throwable cause = assertProcFailed(result);
     assertTrue("expected TimeoutIOException, got " + cause, cause instanceof TimeoutIOException);
   }
 
-  public static void assertIsIllegalArgumentException(final ProcedureInfo result) {
+  public static void assertIsIllegalArgumentException(final Procedure<?> result) {
     Throwable cause = assertProcFailed(result);
     assertTrue("expected IllegalArgumentIOException, got " + cause,
       cause instanceof IllegalArgumentIOException);
   }
 
-  public static Throwable getExceptionCause(final ProcedureInfo procInfo) {
+  public static Throwable getExceptionCause(final Procedure<?> procInfo) {
     assert procInfo.isFailed();
     Throwable cause = procInfo.getException().getCause();
     return cause == null ? procInfo.getException() : cause;
@@ -447,7 +446,7 @@ public class ProcedureTestingUtility {
 
   public static class LoadCounter implements ProcedureStore.ProcedureLoader {
     private final ArrayList<Procedure> corrupted = new ArrayList<>();
-    private final ArrayList<ProcedureInfo> completed = new ArrayList<>();
+    private final ArrayList<Procedure> completed = new ArrayList<>();
     private final ArrayList<Procedure> runnable = new ArrayList<>();
 
     private Set<Long> procIds;
@@ -485,7 +484,7 @@ public class ProcedureTestingUtility {
       return runnable.size();
     }
 
-    public ArrayList<ProcedureInfo> getCompleted() {
+    public ArrayList<Procedure> getCompleted() {
       return completed;
     }
 
@@ -524,12 +523,12 @@ public class ProcedureTestingUtility {
       while (procIter.hasNext()) {
         long procId;
         if (procIter.isNextFinished()) {
-          ProcedureInfo proc = procIter.nextAsProcedureInfo();
+          Procedure<?> proc = procIter.next();
           procId = proc.getProcId();
           LOG.debug("loading completed procId=" + procId + ": " + proc);
           completed.add(proc);
         } else {
-          Procedure proc = procIter.nextAsProcedure();
+          Procedure proc = procIter.next();
           procId = proc.getProcId();
           LOG.debug("loading runnable procId=" + procId + ": " + proc);
           runnable.add(proc);
@@ -543,7 +542,7 @@ public class ProcedureTestingUtility {
     @Override
     public void handleCorrupted(ProcedureIterator procIter) throws IOException {
       while (procIter.hasNext()) {
-        Procedure proc = procIter.nextAsProcedure();
+        Procedure proc = procIter.next();
         LOG.debug("corrupted procId=" + proc.getProcId() + ": " + proc);
         corrupted.add(proc);
       }

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestChildProcedures.java
----------------------------------------------------------------------
diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestChildProcedures.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestChildProcedures.java
index 997999b..1a4dd86 100644
--- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestChildProcedures.java
+++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestChildProcedures.java
@@ -25,7 +25,6 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.procedure2.store.ProcedureStore;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -35,7 +34,6 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 @Category({MasterTests.class, SmallTests.class})
@@ -138,7 +136,7 @@ public class TestChildProcedures {
 
   private void assertProcFailed(long procId) {
     assertTrue("expected completed proc", procExecutor.isFinished(procId));
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     assertEquals(true, result.isFailed());
     LOG.info(result.getException().getMessage());
   }
@@ -146,6 +144,7 @@ public class TestChildProcedures {
   public static class TestRootProcedure extends SequentialProcedure<TestProcEnv> {
     public TestRootProcedure() {}
 
+    @Override
     public Procedure[] execute(TestProcEnv env) {
       if (env.toggleKillBeforeStoreUpdate) {
         ProcedureTestingUtility.toggleKillBeforeStoreUpdate(procExecutor);
@@ -153,6 +152,7 @@ public class TestChildProcedures {
       return new Procedure[] { new TestChildProcedure(), new TestChildProcedure() };
     }
 
+    @Override
     public void rollback(TestProcEnv env) {
     }
 
@@ -165,6 +165,7 @@ public class TestChildProcedures {
   public static class TestChildProcedure extends SequentialProcedure<TestProcEnv> {
     public TestChildProcedure() {}
 
+    @Override
     public Procedure[] execute(TestProcEnv env) {
       if (env.toggleKillBeforeStoreUpdate) {
         ProcedureTestingUtility.toggleKillBeforeStoreUpdate(procExecutor);
@@ -175,6 +176,7 @@ public class TestChildProcedures {
       return null;
     }
 
+    @Override
     public void rollback(TestProcEnv env) {
     }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecution.java
----------------------------------------------------------------------
diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecution.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecution.java
index 38adbf5..496a0f1 100644
--- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecution.java
+++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecution.java
@@ -27,7 +27,6 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.procedure2.store.ProcedureStore;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
@@ -138,7 +137,7 @@ public class TestProcedureExecution {
     // subProc1 has a "null" subprocedure which is catched as InvalidArgument
     // failed state with 2 execute and 2 rollback
     LOG.info(state);
-    ProcedureInfo result = procExecutor.getResult(rootId);
+    Procedure<?> result = procExecutor.getResult(rootId);
     assertTrue(state.toString(), result.isFailed());
     ProcedureTestingUtility.assertIsIllegalArgumentException(result);
 
@@ -159,7 +158,7 @@ public class TestProcedureExecution {
 
     // successful state, with 3 execute
     LOG.info(state);
-    ProcedureInfo result = procExecutor.getResult(rootId);
+    Procedure<?> result = procExecutor.getResult(rootId);
     ProcedureTestingUtility.assertProcNotFailed(result);
     assertEquals(state.toString(), 3, state.size());
   }
@@ -175,7 +174,7 @@ public class TestProcedureExecution {
 
     // the 3rd proc fail, rollback after 2 successful execution
     LOG.info(state);
-    ProcedureInfo result = procExecutor.getResult(rootId);
+    Procedure<?> result = procExecutor.getResult(rootId);
     assertTrue(state.toString(), result.isFailed());
     LOG.info(result.getException().getMessage());
     Throwable cause = ProcedureTestingUtility.getExceptionCause(result);
@@ -219,7 +218,7 @@ public class TestProcedureExecution {
   public void testRollbackRetriableFailure() {
     long procId = ProcedureTestingUtility.submitAndWait(procExecutor, new TestFaultyRollback());
 
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     assertTrue("expected a failure", result.isFailed());
     LOG.info(result.getException().getMessage());
     Throwable cause = ProcedureTestingUtility.getExceptionCause(result);
@@ -303,7 +302,7 @@ public class TestProcedureExecution {
     long execTime = EnvironmentEdgeManager.currentTime() - startTime;
     LOG.info(state);
     assertTrue("we didn't wait enough execTime=" + execTime, execTime >= PROC_TIMEOUT_MSEC);
-    ProcedureInfo result = procExecutor.getResult(rootId);
+    Procedure<?> result = procExecutor.getResult(rootId);
     assertTrue(state.toString(), result.isFailed());
     ProcedureTestingUtility.assertIsTimeoutException(result);
     assertEquals(state.toString(), 2, state.size());
@@ -318,7 +317,7 @@ public class TestProcedureExecution {
     proc.setTimeout(2500);
     long rootId = ProcedureTestingUtility.submitAndWait(procExecutor, proc);
     LOG.info(state);
-    ProcedureInfo result = procExecutor.getResult(rootId);
+    Procedure<?> result = procExecutor.getResult(rootId);
     assertTrue(state.toString(), result.isFailed());
     ProcedureTestingUtility.assertIsTimeoutException(result);
     assertEquals(state.toString(), 4, state.size());

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureNonce.java
----------------------------------------------------------------------
diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureNonce.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureNonce.java
index f275426..c64b3b0 100644
--- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureNonce.java
+++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureNonce.java
@@ -27,7 +27,6 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.procedure2.store.ProcedureStore;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -44,7 +43,6 @@ import org.junit.experimental.categories.Category;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 @Category({MasterTests.class, SmallTests.class})
 public class TestProcedureNonce {
@@ -105,7 +103,7 @@ public class TestProcedureNonce {
     // we should get back the old procId
     assertEquals(procId, procExecutor.registerNonce(nonceKey));
 
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     ProcedureTestingUtility.assertProcNotFailed(result);
   }
 
@@ -140,7 +138,7 @@ public class TestProcedureNonce {
     // we should get back the old procId
     assertEquals(procId, procExecutor.registerNonce(nonceKey));
 
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     ProcedureTestingUtility.assertProcNotFailed(result);
   }
 
@@ -157,7 +155,7 @@ public class TestProcedureNonce {
       new IOException("test failure"));
 
     final long procId = procExecutor.registerNonce(nonceKey);
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     ProcedureTestingUtility.assertProcFailed(result);
   }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java
----------------------------------------------------------------------
diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java
index 00920ee..9681bfb 100644
--- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java
+++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java
@@ -30,7 +30,6 @@ import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.procedure2.store.ProcedureStore;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -198,7 +197,7 @@ public class TestProcedureRecovery {
     long restartTs = EnvironmentEdgeManager.currentTime();
     restart();
     waitProcedure(procId);
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     assertTrue(result.getLastUpdate() > restartTs);
     ProcedureTestingUtility.assertProcNotFailed(result);
     assertEquals(1, Bytes.toInt(result.getResult()));
@@ -237,7 +236,7 @@ public class TestProcedureRecovery {
     assertTrue(procExecutor.isRunning());
 
     // The procedure is completed
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     ProcedureTestingUtility.assertProcNotFailed(result);
   }
 
@@ -284,7 +283,7 @@ public class TestProcedureRecovery {
     waitProcedure(procId);
 
     // The procedure is completed
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     ProcedureTestingUtility.assertIsAbortException(result);
   }
 
@@ -402,7 +401,7 @@ public class TestProcedureRecovery {
     long procId = procExecutor.submitProcedure(new TestStateMachineProcedure(true));
     // Wait the completion
     ProcedureTestingUtility.waitProcedure(procExecutor, procId);
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     ProcedureTestingUtility.assertProcNotFailed(result);
     assertEquals(19, Bytes.toInt(result.getResult()));
     assertEquals(4, procExecutor.getLastProcId());
@@ -441,7 +440,7 @@ public class TestProcedureRecovery {
     assertTrue(procExecutor.isRunning());
 
     // The procedure is completed
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     ProcedureTestingUtility.assertProcNotFailed(result);
     assertEquals(26, Bytes.toInt(result.getResult()));
   }
@@ -495,7 +494,7 @@ public class TestProcedureRecovery {
     assertTrue(procExecutor.isRunning());
 
     // The procedure is completed
-    ProcedureInfo result = procExecutor.getResult(procId);
+    Procedure<?> result = procExecutor.getResult(procId);
     ProcedureTestingUtility.assertIsAbortException(result);
   }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/ProcedureWALLoaderPerformanceEvaluation.java
----------------------------------------------------------------------
diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/ProcedureWALLoaderPerformanceEvaluation.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/ProcedureWALLoaderPerformanceEvaluation.java
index 75623d5..46613b7 100644
--- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/ProcedureWALLoaderPerformanceEvaluation.java
+++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/ProcedureWALLoaderPerformanceEvaluation.java
@@ -31,8 +31,6 @@ import org.apache.commons.cli.Option;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
-import org.apache.hadoop.hbase.ProcedureInfo;
-import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility.TestProcedure;
 import org.apache.hadoop.hbase.procedure2.store.ProcedureStore;
@@ -82,18 +80,14 @@ public class ProcedureWALLoaderPerformanceEvaluation extends AbstractHBaseTool {
     @Override
     public void load(ProcedureIterator procIter) throws IOException {
       while (procIter.hasNext()) {
-        if (procIter.isNextFinished()) {
-          ProcedureInfo proc = procIter.nextAsProcedureInfo();
-        } else {
-          Procedure proc = procIter.nextAsProcedure();
-        }
+        procIter.next();
       }
     }
 
     @Override
     public void handleCorrupted(ProcedureIterator procIter) throws IOException {
       while (procIter.hasNext()) {
-        Procedure proc = procIter.nextAsProcedure();
+        procIter.next();
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/TestWALProcedureStore.java
----------------------------------------------------------------------
diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/TestWALProcedureStore.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/TestWALProcedureStore.java
index 525a663..9b8c46f 100644
--- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/TestWALProcedureStore.java
+++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/TestWALProcedureStore.java
@@ -604,9 +604,9 @@ public class TestWALProcedureStore {
       @Override
       public void load(ProcedureIterator procIter) throws IOException {
         assertTrue(procIter.hasNext());
-        assertEquals(1, procIter.nextAsProcedureInfo().getProcId());
+        assertEquals(1, procIter.next().getProcId());
         assertTrue(procIter.hasNext());
-        assertEquals(2, procIter.nextAsProcedureInfo().getProcId());
+        assertEquals(2, procIter.next().getProcId());
         assertFalse(procIter.hasNext());
       }
 
@@ -660,16 +660,16 @@ public class TestWALProcedureStore {
       @Override
       public void load(ProcedureIterator procIter) throws IOException {
         assertTrue(procIter.hasNext());
-        assertEquals(4, procIter.nextAsProcedureInfo().getProcId());
+        assertEquals(4, procIter.next().getProcId());
         // TODO: This will be multiple call once we do fast-start
         //assertFalse(procIter.hasNext());
 
         assertTrue(procIter.hasNext());
-        assertEquals(1, procIter.nextAsProcedureInfo().getProcId());
+        assertEquals(1, procIter.next().getProcId());
         assertTrue(procIter.hasNext());
-        assertEquals(2, procIter.nextAsProcedureInfo().getProcId());
+        assertEquals(2, procIter.next().getProcId());
         assertTrue(procIter.hasNext());
-        assertEquals(3, procIter.nextAsProcedureInfo().getProcId());
+        assertEquals(3, procIter.next().getProcId());
         assertFalse(procIter.hasNext());
       }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java
----------------------------------------------------------------------
diff --git a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java
index 8cb5606..8a35d2c 100644
--- a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java
+++ b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java
@@ -47,7 +47,6 @@ import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.MetaTableAccessor;
 import org.apache.hadoop.hbase.MetaTableAccessor.DefaultVisitorBase;
 import org.apache.hadoop.hbase.NamespaceDescriptor;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
@@ -68,6 +67,7 @@ import org.apache.hadoop.hbase.master.MasterServices;
 import org.apache.hadoop.hbase.master.ServerListener;
 import org.apache.hadoop.hbase.master.TableStateManager;
 import org.apache.hadoop.hbase.net.Address;
+import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.protobuf.ProtobufMagic;
 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
 import org.apache.hadoop.hbase.protobuf.generated.MultiRowMutationProtos;
@@ -762,9 +762,10 @@ class RSGroupInfoManagerImpl implements RSGroupInfoManager {
       if(tries <= 0) {
         throw new IOException("Failed to create group table in a given time.");
       } else {
-        ProcedureInfo result = masterServices.getMasterProcedureExecutor().getResult(procId);
+        Procedure<?> result = masterServices.getMasterProcedureExecutor().getResult(procId);
         if (result != null && result.isFailed()) {
-          throw new IOException("Failed to create group table. " + result.getExceptionFullMessage());
+          throw new IOException("Failed to create group table. " +
+            result.getException().unwrapRemoteIOException());
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
index 77869f5..0e6f13d 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
@@ -133,8 +133,10 @@ import org.apache.hadoop.hbase.monitoring.TaskMonitor;
 import org.apache.hadoop.hbase.procedure.MasterProcedureManagerHost;
 import org.apache.hadoop.hbase.procedure.flush.MasterFlushTableProcedureManager;
 import org.apache.hadoop.hbase.procedure2.LockInfo;
+import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.procedure2.ProcedureEvent;
 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
+import org.apache.hadoop.hbase.procedure2.ProcedureUtil;
 import org.apache.hadoop.hbase.procedure2.store.wal.WALProcedureStore;
 import org.apache.hadoop.hbase.quotas.MasterQuotaManager;
 import org.apache.hadoop.hbase.quotas.MasterSpaceQuotaObserver;
@@ -2534,6 +2536,7 @@ public class HMaster extends HRegionServer implements MasterServices {
     return info.getInfoPort();
   }
 
+  @Override
   public String getRegionServerVersion(final ServerName sn) {
     RegionServerInfo info = this.regionServerTracker.getRegionServerInfo(sn);
     if (info != null && info.hasVersionInfo()) {
@@ -3002,7 +3005,13 @@ public class HMaster extends HRegionServer implements MasterServices {
       cpHost.preListProcedures();
     }
 
-    final List<ProcedureInfo> procInfoList = this.procedureExecutor.listProcedures();
+    final List<Procedure> procList = this.procedureExecutor.listProcedures();
+    final List<ProcedureInfo> procInfoList = new ArrayList<>(procList.size());
+
+    for (Procedure proc : procList) {
+      ProcedureInfo procInfo = ProcedureUtil.convertToProcedureInfo(proc);
+      procInfoList.add(procInfo);
+    }
 
     if (cpHost != null) {
       cpHost.postListProcedures(procInfoList);
@@ -3011,17 +3020,6 @@ public class HMaster extends HRegionServer implements MasterServices {
     return procInfoList;
   }
 
-  private Map<Long, ProcedureInfo> getProcedureInfos() {
-    final List<ProcedureInfo> list = procedureExecutor.listProcedures();
-    final Map<Long, ProcedureInfo> map = new HashMap<>();
-
-    for (ProcedureInfo procedureInfo : list) {
-      map.put(procedureInfo.getProcId(), procedureInfo);
-    }
-
-    return map;
-  }
-
   @Override
   public List<LockInfo> listLocks() throws IOException {
     if (cpHost != null) {

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
index 392e52f..8b9266c 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
@@ -43,7 +43,6 @@ import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.UnknownRegionException;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
-import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
 import org.apache.hadoop.hbase.client.MasterSwitchType;
 import org.apache.hadoop.hbase.client.TableState;
 import org.apache.hadoop.hbase.client.VersionInfoUtil;
@@ -132,7 +131,6 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProto
 import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionSpaceUse;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionSpaceUseReportRequest;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionSpaceUseReportResponse;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRSFatalErrorRequest;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRSFatalErrorResponse;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionRequest;
@@ -1013,28 +1011,33 @@ public class MasterRpcServices extends RSRpcServices
       master.checkInitialized();
       GetProcedureResultResponse.Builder builder = GetProcedureResultResponse.newBuilder();
 
-      Pair<ProcedureInfo, Procedure> v = master.getMasterProcedureExecutor()
+      Procedure<?> result = master.getMasterProcedureExecutor()
           .getResultOrProcedure(request.getProcId());
-      if (v.getFirst() != null) {
-        ProcedureInfo result = v.getFirst();
-        builder.setState(GetProcedureResultResponse.State.FINISHED);
+      if (result == null) {
+        builder.setState(GetProcedureResultResponse.State.NOT_FOUND);
+      } else {
+        boolean remove = false;
+
+        if (result.isFinished() || result.isFailed()) {
+          builder.setState(GetProcedureResultResponse.State.FINISHED);
+          remove = true;
+        } else {
+          builder.setState(GetProcedureResultResponse.State.RUNNING);
+        }
+
         builder.setSubmittedTime(result.getSubmittedTime());
         builder.setLastUpdate(result.getLastUpdate());
         if (result.isFailed()) {
-          builder.setException(ForeignExceptionUtil.toProtoForeignException(result.getException()));
+          IOException exception = result.getException().unwrapRemoteIOException();
+          builder.setException(ForeignExceptionUtil.toProtoForeignException(exception));
         }
-        if (result.hasResultData()) {
-          builder.setResult(UnsafeByteOperations.unsafeWrap(result.getResult()));
+        byte[] resultData = result.getResult();
+        if (resultData != null) {
+          builder.setResult(UnsafeByteOperations.unsafeWrap(resultData));
         }
-        master.getMasterProcedureExecutor().removeResult(request.getProcId());
-      } else {
-        Procedure<?> proc = v.getSecond();
-        if (proc == null) {
-          builder.setState(GetProcedureResultResponse.State.NOT_FOUND);
-        } else {
-          builder.setState(GetProcedureResultResponse.State.RUNNING);
-          builder.setSubmittedTime(proc.getSubmittedTime());
-          builder.setLastUpdate(proc.getLastUpdate());
+
+        if (remove) {
+          master.getMasterProcedureExecutor().removeResult(request.getProcId());
         }
       }
       return builder.build();

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
index 5199bf8..12d659b 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
@@ -32,7 +32,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.CoordinatedStateException;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
 import org.apache.hadoop.hbase.classification.InterfaceStability;
 import org.apache.hadoop.hbase.exceptions.TimeoutIOException;
@@ -147,11 +146,11 @@ public final class ProcedureSyncWait {
       }
     );
 
-    ProcedureInfo result = procExec.getResult(procId);
+    Procedure result = procExec.getResult(procId);
     if (result != null) {
-      if (result.isFailed()) {
+      if (result.hasException()) {
         // If the procedure fails, we should always have an exception captured. Throw it.
-        throw result.getException();
+        throw result.getException().unwrapRemoteIOException();
       }
       return result.getResult();
     } else {

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/main/resources/hbase-webapps/master/procedures.jsp
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/resources/hbase-webapps/master/procedures.jsp b/hbase-server/src/main/resources/hbase-webapps/master/procedures.jsp
index 29c3d45..a3701ff 100644
--- a/hbase-server/src/main/resources/hbase-webapps/master/procedures.jsp
+++ b/hbase-server/src/main/resources/hbase-webapps/master/procedures.jsp
@@ -31,6 +31,7 @@
   import="org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv"
   import="org.apache.hadoop.hbase.ProcedureInfo"
   import="org.apache.hadoop.hbase.procedure2.LockInfo"
+  import="org.apache.hadoop.hbase.procedure2.Procedure"
   import="org.apache.hadoop.hbase.procedure2.ProcedureExecutor"
   import="org.apache.hadoop.hbase.procedure2.store.wal.ProcedureWALFile"
   import="org.apache.hadoop.hbase.procedure2.store.wal.WALProcedureStore"
@@ -47,11 +48,11 @@
   long millisFromLastRoll = walStore.getMillisFromLastRoll();
   ArrayList<ProcedureWALFile> procedureWALFiles = walStore.getActiveLogs();
   Set<ProcedureWALFile> corruptedWALFiles = walStore.getCorruptedLogs();
-  List<ProcedureInfo> procedures = procExecutor.listProcedures();
-  Collections.sort(procedures, new Comparator<ProcedureInfo>() {
+  List<Procedure> procedures = procExecutor.listProcedures();
+  Collections.sort(procedures, new Comparator<Procedure>() {
     @Override
-    public int compare(ProcedureInfo lhs, ProcedureInfo rhs) {
-      long cmp = lhs.getParentId() - rhs.getParentId();
+    public int compare(Procedure lhs, Procedure rhs) {
+      long cmp = lhs.getParentProcId() - rhs.getParentProcId();
       cmp = cmp != 0 ? cmp : lhs.getProcId() - rhs.getProcId();
       return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
     }
@@ -118,16 +119,16 @@
         <th>Last Update</th>
         <th>Errors</th>
     </tr>
-    <% for (ProcedureInfo procInfo : procedures) { %>
+    <% for (Procedure<?> proc : procedures) { %>
       <tr>
-        <td><%= procInfo.getProcId() %></td>
-        <td><%= procInfo.hasParentId() ? procInfo.getParentId() : "" %></td>
-        <td><%= escapeXml(procInfo.getProcState().toString()) %></td>
-        <td><%= escapeXml(procInfo.getProcOwner()) %></td>
-        <td><%= escapeXml(procInfo.getProcName()) %></td>
-        <td><%= new Date(procInfo.getSubmittedTime()) %></td>
-        <td><%= new Date(procInfo.getLastUpdate()) %></td>
-        <td><%= escapeXml(procInfo.isFailed() ? procInfo.getException().getMessage() : "") %></td>
+        <td><%= proc.getProcId() %></td>
+        <td><%= proc.hasParent() ? proc.getParentProcId() : "" %></td>
+        <td><%= escapeXml(proc.getState().toString()) %></td>
+        <td><%= escapeXml(proc.getOwner()) %></td>
+        <td><%= escapeXml(proc.getProcName()) %></td>
+        <td><%= new Date(proc.getSubmittedTime()) %></td>
+        <td><%= new Date(proc.getLastUpdate()) %></td>
+        <td><%= escapeXml(proc.isFailed() ? proc.getException().unwrapRemoteIOException().getMessage() : "") %></td>
       </tr>
     <% } %>
   </table>

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/test/java/org/apache/hadoop/hbase/master/locking/TestLockManager.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/locking/TestLockManager.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/locking/TestLockManager.java
index fa43fbd..d85146a 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/locking/TestLockManager.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/locking/TestLockManager.java
@@ -24,7 +24,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.NamespaceDescriptor;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.master.MasterServices;
 import org.apache.hadoop.hbase.master.locking.LockProcedure;
@@ -95,8 +94,7 @@ public class TestLockManager {
 
   @After
   public void tearDown() throws Exception {
-    for (ProcedureInfo procInfo : getMasterProcedureExecutor().listProcedures()) {
-      Procedure proc = getMasterProcedureExecutor().getProcedure(procInfo.getProcId());
+    for (Procedure<?> proc : getMasterProcedureExecutor().listProcedures()) {
       if (proc instanceof LockProcedure) {
         ((LockProcedure) proc).unlock(getMasterProcedureExecutor().getEnvironment());
         ProcedureTestingUtility.waitProcedure(getMasterProcedureExecutor(), proc);

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/test/java/org/apache/hadoop/hbase/master/locking/TestLockProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/locking/TestLockProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/locking/TestLockProcedure.java
index ac157e4..adaebf4 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/locking/TestLockProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/locking/TestLockProcedure.java
@@ -26,7 +26,6 @@ import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.NamespaceDescriptor;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.locking.LockServiceClient;
 import org.apache.hadoop.hbase.master.procedure.MasterProcedureConstants;
@@ -39,7 +38,6 @@ import org.apache.hadoop.hbase.shaded.com.google.protobuf.ServiceException;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos.*;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
-import org.apache.hadoop.hbase.util.Pair;
 import org.hamcrest.core.IsInstanceOf;
 import org.hamcrest.core.StringStartsWith;
 import org.junit.rules.TestRule;
@@ -132,10 +130,8 @@ public class TestLockProcedure {
   public void tearDown() throws Exception {
     ProcedureTestingUtility.setKillAndToggleBeforeStoreUpdate(procExec, false);
     // Kill all running procedures.
-    for (ProcedureInfo procInfo : procExec.listProcedures()) {
-      Procedure proc = procExec.getProcedure(procInfo.getProcId());
-      if (proc == null) continue;
-      procExec.abort(procInfo.getProcId());
+    for (Procedure<?> proc : procExec.listProcedures()) {
+      procExec.abort(proc.getProcId());
       ProcedureTestingUtility.waitProcedure(procExec, proc);
     }
     assertEquals(0, procExec.getEnvironment().getProcedureScheduler().size());
@@ -440,8 +436,8 @@ public class TestLockProcedure {
     }
     assertEquals(true, procExec.isRunning());
     ProcedureTestingUtility.waitProcedure(procExec, lockProc.getProcId());
-    Pair<ProcedureInfo, Procedure> result = procExec.getResultOrProcedure(lockProc.getProcId());
-    assertTrue(result.getFirst() != null && !result.getFirst().isFailed());
+    Procedure<?> result = procExec.getResultOrProcedure(lockProc.getProcId());
+    assertTrue(result != null && !result.isFailed());
     ProcedureTestingUtility.assertProcNotFailed(procExec, lockProc.getProcId());
   }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestAddColumnFamilyProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestAddColumnFamilyProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestAddColumnFamilyProcedure.java
index 506e537..01de512 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestAddColumnFamilyProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestAddColumnFamilyProcedure.java
@@ -25,8 +25,8 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.CategoryBasedTimeout;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.InvalidFamilyOperationException;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -100,9 +100,9 @@ public class TestAddColumnFamilyProcedure extends TestTableDDLProcedureBase {
     ProcedureTestingUtility.waitProcedure(procExec, procId2);
 
     // Second add should fail with InvalidFamilyOperationException
-    ProcedureInfo result = procExec.getResult(procId2);
+    Procedure<?> result = procExec.getResult(procId2);
     assertTrue(result.isFailed());
-    LOG.debug("Add failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Add failed with exception: " + result.getException());
     assertTrue(
       ProcedureTestingUtility.getExceptionCause(result) instanceof InvalidFamilyOperationException);
 
@@ -116,7 +116,7 @@ public class TestAddColumnFamilyProcedure extends TestTableDDLProcedureBase {
     // Second add should fail with InvalidFamilyOperationException
     result = procExec.getResult(procId3);
     assertTrue(result.isFailed());
-    LOG.debug("Add failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Add failed with exception: " + result.getException());
     assertTrue(
       ProcedureTestingUtility.getExceptionCause(result) instanceof InvalidFamilyOperationException);
   }

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCloneSnapshotProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCloneSnapshotProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCloneSnapshotProcedure.java
index b70aff3..b68a2f7 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCloneSnapshotProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCloneSnapshotProcedure.java
@@ -26,17 +26,14 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HTableDescriptor;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.TableExistsException;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.Admin;
 import org.apache.hadoop.hbase.client.SnapshotDescription;
+import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
 import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;
-import org.apache.hadoop.hbase.client.SnapshotDescription;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.CloneSnapshotState;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos;
 import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -125,9 +122,9 @@ public class TestCloneSnapshotProcedure extends TestTableDDLProcedureBase {
 
     long procId = ProcedureTestingUtility.submitAndWait(
       procExec, new CloneSnapshotProcedure(procExec.getEnvironment(), htd, snapshotDesc));
-    ProcedureInfo result = procExec.getResult(procId);
+    Procedure<?> result = procExec.getResult(procId);
     assertTrue(result.isFailed());
-    LOG.debug("Clone snapshot failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Clone snapshot failed with exception: " + result.getException());
     assertTrue(
       ProcedureTestingUtility.getExceptionCause(result) instanceof TableExistsException);
   }

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateNamespaceProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateNamespaceProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateNamespaceProcedure.java
index 147ee27..81942e1 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateNamespaceProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateNamespaceProcedure.java
@@ -31,8 +31,8 @@ import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.NamespaceDescriptor;
 import org.apache.hadoop.hbase.NamespaceExistException;
 import org.apache.hadoop.hbase.NamespaceNotFoundException;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.constraint.ConstraintException;
+import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -112,9 +112,9 @@ public class TestCreateNamespaceProcedure {
     ProcedureTestingUtility.waitProcedure(procExec, procId2);
 
     // Second create should fail with NamespaceExistException
-    ProcedureInfo result = procExec.getResult(procId2);
+    Procedure<?> result = procExec.getResult(procId2);
     assertTrue(result.isFailed());
-    LOG.debug("Create namespace failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Create namespace failed with exception: " + result.getException());
     assertTrue(
       ProcedureTestingUtility.getExceptionCause(result) instanceof NamespaceExistException);
   }
@@ -129,9 +129,9 @@ public class TestCreateNamespaceProcedure {
       new CreateNamespaceProcedure(procExec.getEnvironment(), nsd));
     // Wait the completion
     ProcedureTestingUtility.waitProcedure(procExec, procId);
-    ProcedureInfo result = procExec.getResult(procId);
+    Procedure<?> result = procExec.getResult(procId);
     assertTrue(result.isFailed());
-    LOG.debug("Create namespace failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Create namespace failed with exception: " + result.getException());
     assertTrue(
       ProcedureTestingUtility.getExceptionCause(result) instanceof NamespaceExistException);
   }
@@ -150,9 +150,9 @@ public class TestCreateNamespaceProcedure {
       new CreateNamespaceProcedure(procExec.getEnvironment(), nsd));
     // Wait the completion
     ProcedureTestingUtility.waitProcedure(procExec, procId);
-    ProcedureInfo result = procExec.getResult(procId);
+    Procedure<?> result = procExec.getResult(procId);
     assertTrue(result.isFailed());
-    LOG.debug("Create namespace failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Create namespace failed with exception: " + result.getException());
     assertTrue(ProcedureTestingUtility.getExceptionCause(result) instanceof ConstraintException);
   }
 
@@ -170,9 +170,9 @@ public class TestCreateNamespaceProcedure {
       new CreateNamespaceProcedure(procExec.getEnvironment(), nsd));
     // Wait the completion
     ProcedureTestingUtility.waitProcedure(procExec, procId);
-    ProcedureInfo result = procExec.getResult(procId);
+    Procedure<?> result = procExec.getResult(procId);
     assertTrue(result.isFailed());
-    LOG.debug("Create namespace failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Create namespace failed with exception: " + result.getException());
     assertTrue(ProcedureTestingUtility.getExceptionCause(result) instanceof ConstraintException);
   }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateTableProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateTableProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateTableProcedure.java
index 6bd88c7..177d862 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateTableProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateTableProcedure.java
@@ -23,9 +23,9 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.HTableDescriptor;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.TableExistsException;
 import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -85,7 +85,7 @@ public class TestCreateTableProcedure extends TestTableDDLProcedureBase {
     long procId =
         ProcedureTestingUtility.submitAndWait(procExec,
             new CreateTableProcedure(procExec.getEnvironment(), htd, regions));
-    final ProcedureInfo result = procExec.getResult(procId);
+    final Procedure<?> result = procExec.getResult(procId);
     assertEquals(true, result.isFailed());
     Throwable cause = ProcedureTestingUtility.getExceptionCause(result);
     assertTrue("expected DoNotRetryIOException, got " + cause,

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteColumnFamilyProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteColumnFamilyProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteColumnFamilyProcedure.java
index 6096755..d126251 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteColumnFamilyProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteColumnFamilyProcedure.java
@@ -25,8 +25,8 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.CategoryBasedTimeout;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.InvalidFamilyOperationException;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -98,9 +98,9 @@ public class TestDeleteColumnFamilyProcedure extends TestTableDDLProcedureBase {
     ProcedureTestingUtility.waitProcedure(procExec, procId2);
 
     // Second delete should fail with InvalidFamilyOperationException
-    ProcedureInfo result = procExec.getResult(procId2);
+    Procedure<?> result = procExec.getResult(procId2);
     assertTrue(result.isFailed());
-    LOG.debug("Delete online failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Delete online failed with exception: " + result.getException());
     assertTrue(
       ProcedureTestingUtility.getExceptionCause(result) instanceof InvalidFamilyOperationException);
 
@@ -113,7 +113,7 @@ public class TestDeleteColumnFamilyProcedure extends TestTableDDLProcedureBase {
     // Expect fail with InvalidFamilyOperationException
     result = procExec.getResult(procId2);
     assertTrue(result.isFailed());
-    LOG.debug("Delete offline failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Delete offline failed with exception: " + result.getException());
     assertTrue(
       ProcedureTestingUtility.getExceptionCause(result) instanceof InvalidFamilyOperationException);
   }
@@ -133,9 +133,9 @@ public class TestDeleteColumnFamilyProcedure extends TestTableDDLProcedureBase {
     // Wait the completion
     ProcedureTestingUtility.waitProcedure(procExec, procId1);
 
-    ProcedureInfo result = procExec.getResult(procId1);
+    Procedure<?> result = procExec.getResult(procId1);
     assertTrue(result.isFailed());
-    LOG.debug("Delete failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Delete failed with exception: " + result.getException());
     assertTrue(
       ProcedureTestingUtility.getExceptionCause(result) instanceof InvalidFamilyOperationException);
   }

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteNamespaceProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteNamespaceProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteNamespaceProcedure.java
index 5ecacb6..dcfed29 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteNamespaceProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteNamespaceProcedure.java
@@ -31,9 +31,9 @@ import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.NamespaceDescriptor;
 import org.apache.hadoop.hbase.NamespaceNotFoundException;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.constraint.ConstraintException;
+import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -117,9 +117,9 @@ public class TestDeleteNamespaceProcedure {
     // Wait the completion
     ProcedureTestingUtility.waitProcedure(procExec, procId);
     // Expect fail with NamespaceNotFoundException
-    ProcedureInfo result = procExec.getResult(procId);
+    Procedure<?> result = procExec.getResult(procId);
     assertTrue(result.isFailed());
-    LOG.debug("Delete namespace failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Delete namespace failed with exception: " + result.getException());
     assertTrue(
       ProcedureTestingUtility.getExceptionCause(result) instanceof NamespaceNotFoundException);
   }
@@ -133,9 +133,9 @@ public class TestDeleteNamespaceProcedure {
       new DeleteNamespaceProcedure(procExec.getEnvironment(), namespaceName));
     // Wait the completion
     ProcedureTestingUtility.waitProcedure(procExec, procId);
-    ProcedureInfo result = procExec.getResult(procId);
+    Procedure<?> result = procExec.getResult(procId);
     assertTrue(result.isFailed());
-    LOG.debug("Delete namespace failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Delete namespace failed with exception: " + result.getException());
     assertTrue(ProcedureTestingUtility.getExceptionCause(result) instanceof ConstraintException);
   }
 
@@ -153,9 +153,9 @@ public class TestDeleteNamespaceProcedure {
       new DeleteNamespaceProcedure(procExec.getEnvironment(), namespaceName));
     // Wait the completion
     ProcedureTestingUtility.waitProcedure(procExec, procId);
-    ProcedureInfo result = procExec.getResult(procId);
+    Procedure<?> result = procExec.getResult(procId);
     assertTrue(result.isFailed());
-    LOG.debug("Delete namespace failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Delete namespace failed with exception: " + result.getException());
     assertTrue(ProcedureTestingUtility.getExceptionCause(result) instanceof ConstraintException);
   }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteTableProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteTableProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteTableProcedure.java
index 2a11544..3ad8ec8 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteTableProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDeleteTableProcedure.java
@@ -18,14 +18,16 @@
 
 package org.apache.hadoop.hbase.master.procedure;
 
+import static org.junit.Assert.assertTrue;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.CategoryBasedTimeout;
 import org.apache.hadoop.hbase.HRegionInfo;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.TableNotDisabledException;
 import org.apache.hadoop.hbase.TableNotFoundException;
+import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -37,8 +39,6 @@ import org.junit.experimental.categories.Category;
 import org.junit.rules.TestName;
 import org.junit.rules.TestRule;
 
-import static org.junit.Assert.assertTrue;
-
 @Category({MasterTests.class, MediumTests.class})
 public class TestDeleteTableProcedure extends TestTableDDLProcedureBase {
   private static final Log LOG = LogFactory.getLog(TestDeleteTableProcedure.class);
@@ -95,9 +95,9 @@ public class TestDeleteTableProcedure extends TestTableDDLProcedureBase {
     MasterProcedureTestingUtility.validateTableDeletion(getMaster(), tableName);
 
     // Second delete should fail with TableNotFound
-    ProcedureInfo result = procExec.getResult(procId2);
+    Procedure<?> result = procExec.getResult(procId2);
     assertTrue(result.isFailed());
-    LOG.debug("Delete failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Delete failed with exception: " + result.getException());
     assertTrue(ProcedureTestingUtility.getExceptionCause(result) instanceof TableNotFoundException);
   }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDisableTableProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDisableTableProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDisableTableProcedure.java
index 11c4e2a..9c5970c 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDisableTableProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestDisableTableProcedure.java
@@ -23,9 +23,9 @@ import static org.junit.Assert.assertTrue;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.CategoryBasedTimeout;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.TableNotEnabledException;
+import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -82,9 +82,9 @@ public class TestDisableTableProcedure extends TestTableDDLProcedureBase {
         procExec.getEnvironment(), tableName, false));
     // Wait the completion
     ProcedureTestingUtility.waitProcedure(procExec, procId2);
-    ProcedureInfo result = procExec.getResult(procId2);
+    Procedure<?> result = procExec.getResult(procId2);
     assertTrue(result.isFailed());
-    LOG.debug("Disable failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Disable failed with exception: " + result.getException());
     assertTrue(
       ProcedureTestingUtility.getExceptionCause(result) instanceof TableNotEnabledException);
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/8f006582/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestEnableTableProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestEnableTableProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestEnableTableProcedure.java
index 01f9ed8..66071d3 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestEnableTableProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestEnableTableProcedure.java
@@ -23,9 +23,9 @@ import static org.junit.Assert.assertTrue;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.CategoryBasedTimeout;
-import org.apache.hadoop.hbase.ProcedureInfo;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.TableNotDisabledException;
+import org.apache.hadoop.hbase.procedure2.Procedure;
 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
 import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -74,9 +74,9 @@ public class TestEnableTableProcedure extends TestTableDDLProcedureBase {
         new EnableTableProcedure(procExec.getEnvironment(), tableName, false));
     ProcedureTestingUtility.waitProcedure(procExec, procId1);
 
-    ProcedureInfo result = procExec.getResult(procId1);
+    Procedure<?> result = procExec.getResult(procId1);
     assertTrue(result.isFailed());
-    LOG.debug("Enable failed with exception: " + result.getExceptionFullMessage());
+    LOG.debug("Enable failed with exception: " + result.getException());
     assertTrue(
       ProcedureTestingUtility.getExceptionCause(result) instanceof TableNotDisabledException);