private SnapshotDescription toSnapshotDescription(ProcedureDescription desc) throws IOException { SnapshotDescription.Builder builder = SnapshotDescription.newBuilder(); if (!desc.hasInstance()) { throw new IOException("Snapshot name is not defined: " + desc.toString()); } String snapshotName = desc.getInstance(); List<NameStringPair> props = desc.getConfigurationList(); String table = null; for (NameStringPair prop : props) { if ("table".equalsIgnoreCase(prop.getName())) { table = prop.getValue(); } } if (table == null) { throw new IOException("Snapshot table is not defined: " + desc.toString()); } TableName tableName = TableName.valueOf(table); builder.setTable(tableName.getNameAsString()); builder.setName(snapshotName); builder.setType(SnapshotDescription.Type.FLUSH); return builder.build(); }
/** * Check the current state of the specified procedure. * <p> * There are three possible states: * <ol> * <li>running - returns <tt>false</tt></li> * <li>finished - returns <tt>true</tt></li> * <li>finished with error - throws the exception that caused the procedure to fail</li> * </ol> * <p> * * @param signature The signature that uniquely identifies a procedure * @param instance The instance name of the procedure * @param props Property/Value pairs of properties passing to the procedure * @return true if the specified procedure is finished successfully, false if it is still running * @throws IOException if the specified procedure finished with error */ @Override public boolean isProcedureFinished(String signature, String instance, Map<String, String> props) throws IOException { final ProcedureDescription.Builder builder = ProcedureDescription.newBuilder(); builder.setSignature(signature).setInstance(instance); for (Entry<String, String> entry : props.entrySet()) { NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey()) .setValue(entry.getValue()).build(); builder.addConfiguration(pair); } final ProcedureDescription desc = builder.build(); return executeCallable( new MasterCallable<IsProcedureDoneResponse>(getConnection()) { @Override public IsProcedureDoneResponse call(int callTimeout) throws ServiceException { PayloadCarryingRpcController controller = rpcControllerFactory.newController(); controller.setCallTimeout(callTimeout); return master.isProcedureDone(controller, IsProcedureDoneRequest .newBuilder().setProcedure(desc).build()); } }).getDone(); }
/** * Checks if the specified procedure is done. * @return true if the procedure is done, * false if the procedure is in the process of completing * @throws ServiceException if invalid procedure, or * a failed procedure with progress failure reason. */ @Override public IsProcedureDoneResponse isProcedureDone(RpcController controller, IsProcedureDoneRequest request) throws ServiceException { try { master.checkInitialized(); ProcedureDescription desc = request.getProcedure(); MasterProcedureManager mpm = master.mpmHost.getProcedureManager( desc.getSignature()); if (mpm == null) { throw new ServiceException("The procedure is not registered: " + desc.getSignature()); } LOG.debug("Checking to see if procedure from request:" + desc.getSignature() + " is done"); IsProcedureDoneResponse.Builder builder = IsProcedureDoneResponse.newBuilder(); boolean done = mpm.isProcedureDone(desc); builder.setDone(done); return builder.build(); } catch (IOException e) { throw new ServiceException(e); } }
/** * Execute a distributed procedure on a cluster synchronously with return data * * @param signature A distributed procedure is uniquely identified * by its signature (default the root ZK node name of the procedure). * @param instance The instance name of the procedure. For some procedures, this parameter is * optional. * @param props Property/Value pairs of properties passing to the procedure * @return data returned after procedure execution. null if no return data. * @throws IOException */ @Override public byte[] execProcedureWithRet(String signature, String instance, Map<String, String> props) throws IOException { ProcedureDescription.Builder builder = ProcedureDescription.newBuilder(); builder.setSignature(signature).setInstance(instance); for (Entry<String, String> entry : props.entrySet()) { NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey()) .setValue(entry.getValue()).build(); builder.addConfiguration(pair); } final ExecProcedureRequest request = ExecProcedureRequest.newBuilder() .setProcedure(builder.build()).build(); // run the procedure on the master ExecProcedureResponse response = executeCallable(new MasterCallable<ExecProcedureResponse>( getConnection()) { @Override public ExecProcedureResponse call(int callTimeout) throws ServiceException { return master.execProcedureWithRet(null, request); } }); return response.hasReturnData() ? response.getReturnData().toByteArray() : null; }
/** * Check the current state of the specified procedure. * <p> * There are three possible states: * <ol> * <li>running - returns <tt>false</tt></li> * <li>finished - returns <tt>true</tt></li> * <li>finished with error - throws the exception that caused the procedure to fail</li> * </ol> * <p> * * @param signature The signature that uniquely identifies a procedure * @param instance The instance name of the procedure * @param props Property/Value pairs of properties passing to the procedure * @return true if the specified procedure is finished successfully, false if it is still running * @throws IOException if the specified procedure finished with error */ @Override public boolean isProcedureFinished(String signature, String instance, Map<String, String> props) throws IOException { final ProcedureDescription.Builder builder = ProcedureDescription.newBuilder(); builder.setSignature(signature).setInstance(instance); for (Entry<String, String> entry : props.entrySet()) { NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey()) .setValue(entry.getValue()).build(); builder.addConfiguration(pair); } final ProcedureDescription desc = builder.build(); return executeCallable( new MasterCallable<IsProcedureDoneResponse>(getConnection()) { @Override public IsProcedureDoneResponse call(int callTimeout) throws ServiceException { return master.isProcedureDone(null, IsProcedureDoneRequest .newBuilder().setProcedure(desc).build()); } }).getDone(); }
/** * Checks if the specified procedure is done. * @return true if the procedure is done, * false if the procedure is in the process of completing * @throws ServiceException if invalid procedure, or * a failed procedure with progress failure reason. */ @Override public IsProcedureDoneResponse isProcedureDone(RpcController controller, IsProcedureDoneRequest request) throws ServiceException { ProcedureDescription desc = request.getProcedure(); MasterProcedureManager mpm = this.mpmHost.getProcedureManager(desc .getSignature()); if (mpm == null) { throw new ServiceException("The procedure is not registered: " + desc.getSignature()); } LOG.debug("Checking to see if procedure from request:" + desc.getSignature() + " is done"); try { IsProcedureDoneResponse.Builder builder = IsProcedureDoneResponse .newBuilder(); boolean done = mpm.isProcedureDone(desc); builder.setDone(done); return builder.build(); } catch (IOException e) { throw new ServiceException(e); } }
/** * Check the current state of the specified procedure. * <p> * There are three possible states: * <ol> * <li>running - returns <tt>false</tt></li> * <li>finished - returns <tt>true</tt></li> * <li>finished with error - throws the exception that caused the procedure to fail</li> * </ol> * <p> * * @param signature The signature that uniquely identifies a procedure * @param instance The instance name of the procedure * @param props Property/Value pairs of properties passing to the procedure * @return true if the specified procedure is finished successfully, false if it is still running * @throws IOException if the specified procedure finished with error */ public boolean isProcedureFinished(String signature, String instance, Map<String, String> props) throws IOException { final ProcedureDescription.Builder builder = ProcedureDescription.newBuilder(); builder.setSignature(signature).setInstance(instance); for (String key : props.keySet()) { NameStringPair pair = NameStringPair.newBuilder().setName(key) .setValue(props.get(key)).build(); builder.addConfiguration(pair); } final ProcedureDescription desc = builder.build(); return executeCallable( new MasterCallable<IsProcedureDoneResponse>(getConnection()) { @Override public IsProcedureDoneResponse call() throws ServiceException { return master.isProcedureDone(null, IsProcedureDoneRequest .newBuilder().setProcedure(desc).build()); } }).getDone(); }
/** * Check the current state of the specified procedure. * <p> * There are three possible states: * <ol> * <li>running - returns <tt>false</tt></li> * <li>finished - returns <tt>true</tt></li> * <li>finished with error - throws the exception that caused the procedure to fail</li> * </ol> * <p> * * @param signature The signature that uniquely identifies a procedure * @param instance The instance name of the procedure * @param props Property/Value pairs of properties passing to the procedure * @return true if the specified procedure is finished successfully, false if it is still running * @throws IOException if the specified procedure finished with error */ public boolean isProcedureFinished(String signature, String instance, Map<String, String> props) throws IOException { final ProcedureDescription.Builder builder = ProcedureDescription.newBuilder(); builder.setSignature(signature).setInstance(instance); for (Entry<String, String> entry : props.entrySet()) { NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey()) .setValue(entry.getValue()).build(); builder.addConfiguration(pair); } final ProcedureDescription desc = builder.build(); return executeCallable( new MasterCallable<IsProcedureDoneResponse>(getConnection()) { @Override public IsProcedureDoneResponse call(int callTimeout) throws ServiceException { return master.isProcedureDone(null, IsProcedureDoneRequest .newBuilder().setProcedure(desc).build()); } }).getDone(); }
/** * Triggers a synchronous attempt to run a distributed procedure and sets * return data in response. * {@inheritDoc} */ @Override public ExecProcedureResponse execProcedureWithRet(RpcController controller, ExecProcedureRequest request) throws ServiceException { try { master.checkInitialized(); ProcedureDescription desc = request.getProcedure(); MasterProcedureManager mpm = master.mpmHost.getProcedureManager( desc.getSignature()); if (mpm == null) { throw new ServiceException("The procedure is not registered: " + desc.getSignature()); } LOG.info(master.getClientIdAuditPrefix() + " procedure request for: " + desc.getSignature()); byte[] data = mpm.execProcedureWithRet(desc); ExecProcedureResponse.Builder builder = ExecProcedureResponse.newBuilder(); // set return data if available if (data != null) { builder.setReturnData(ByteString.copyFrom(data)); } return builder.build(); } catch (IOException e) { throw new ServiceException(e); } }
@Override public synchronized boolean isProcedureDone(ProcedureDescription desc) throws IOException { // Procedure instance name is the table name. TableName tableName = TableName.valueOf(desc.getInstance()); Procedure proc = procMap.get(tableName); if (proc == null) { // The procedure has not even been started yet. // The client would request the procedure and call isProcedureDone(). // The HBaseAdmin.execProcedure() wraps both request and isProcedureDone(). return false; } // We reply on the existing Distributed Procedure framework to give us the status. return proc.isCompleted(); }
/** * Execute a distributed procedure on a cluster synchronously with return data * * @param signature A distributed procedure is uniquely identified * by its signature (default the root ZK node name of the procedure). * @param instance The instance name of the procedure. For some procedures, this parameter is * optional. * @param props Property/Value pairs of properties passing to the procedure * @return data returned after procedure execution. null if no return data. * @throws IOException */ @Override public byte[] execProcedureWithRet(String signature, String instance, Map<String, String> props) throws IOException { ProcedureDescription.Builder builder = ProcedureDescription.newBuilder(); builder.setSignature(signature).setInstance(instance); for (Entry<String, String> entry : props.entrySet()) { NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey()) .setValue(entry.getValue()).build(); builder.addConfiguration(pair); } final ExecProcedureRequest request = ExecProcedureRequest.newBuilder() .setProcedure(builder.build()).build(); // run the procedure on the master ExecProcedureResponse response = executeCallable(new MasterCallable<ExecProcedureResponse>( getConnection()) { @Override public ExecProcedureResponse call(int callTimeout) throws ServiceException { PayloadCarryingRpcController controller = rpcControllerFactory.newController(); controller.setCallTimeout(callTimeout); return master.execProcedureWithRet(controller, request); } }); return response.hasReturnData() ? response.getReturnData().toByteArray() : null; }
/** * Triggers an asynchronous attempt to run a distributed procedure. * {@inheritDoc} */ @Override public ExecProcedureResponse execProcedure(RpcController controller, ExecProcedureRequest request) throws ServiceException { try { master.checkInitialized(); ProcedureDescription desc = request.getProcedure(); MasterProcedureManager mpm = master.mpmHost.getProcedureManager( desc.getSignature()); if (mpm == null) { throw new ServiceException("The procedure is not registered: " + desc.getSignature()); } LOG.info(master.getClientIdAuditPrefix() + " procedure request for: " + desc.getSignature()); mpm.execProcedure(desc); // send back the max amount of time the client should wait for the procedure // to complete long waitTime = SnapshotDescriptionUtils.DEFAULT_MAX_WAIT_TIME; return ExecProcedureResponse.newBuilder().setExpectedTimeout( waitTime).build(); } catch (IOException e) { throw new ServiceException(e); } }
/** * Triggers an asynchronous attempt to run a distributed procedure. * {@inheritDoc} */ @Override public ExecProcedureResponse execProcedure(RpcController controller, ExecProcedureRequest request) throws ServiceException { ProcedureDescription desc = request.getProcedure(); MasterProcedureManager mpm = this.mpmHost.getProcedureManager(desc .getSignature()); if (mpm == null) { throw new ServiceException("The procedure is not registered: " + desc.getSignature()); } LOG.info(getClientIdAuditPrefix() + " procedure request for: " + desc.getSignature()); try { mpm.execProcedure(desc); } catch (IOException e) { throw new ServiceException(e); } // send back the max amount of time the client should wait for the procedure // to complete long waitTime = SnapshotDescriptionUtils.DEFAULT_MAX_WAIT_TIME; return ExecProcedureResponse.newBuilder().setExpectedTimeout(waitTime) .build(); }
@Override public void execProcedure(ProcedureDescription desc) throws IOException { takeSnapshot(toSnapshotDescription(desc)); }
@Override public boolean isProcedureDone(ProcedureDescription desc) throws IOException { return isSnapshotDone(toSnapshotDescription(desc)); }
@Override public boolean isProcedureDone(ProcedureDescription desc) throws IOException { return done; }
/** * Execute a distributed procedure on a cluster. * * @param signature A distributed procedure is uniquely identified * by its signature (default the root ZK node name of the procedure). * @param instance The instance name of the procedure. For some procedures, this parameter is * optional. * @param props Property/Value pairs of properties passing to the procedure * @throws IOException */ @Override public void execProcedure(String signature, String instance, Map<String, String> props) throws IOException { ProcedureDescription.Builder builder = ProcedureDescription.newBuilder(); builder.setSignature(signature).setInstance(instance); for (Entry<String, String> entry : props.entrySet()) { NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey()) .setValue(entry.getValue()).build(); builder.addConfiguration(pair); } final ExecProcedureRequest request = ExecProcedureRequest.newBuilder() .setProcedure(builder.build()).build(); // run the procedure on the master ExecProcedureResponse response = executeCallable(new MasterCallable<ExecProcedureResponse>( getConnection()) { @Override public ExecProcedureResponse call(int callTimeout) throws ServiceException { PayloadCarryingRpcController controller = rpcControllerFactory.newController(); controller.setCallTimeout(callTimeout); return master.execProcedure(controller, request); } }); long start = EnvironmentEdgeManager.currentTime(); long max = response.getExpectedTimeout(); long maxPauseTime = max / this.numRetries; int tries = 0; LOG.debug("Waiting a max of " + max + " ms for procedure '" + signature + " : " + instance + "'' to complete. (max " + maxPauseTime + " ms per retry)"); boolean done = false; while (tries == 0 || ((EnvironmentEdgeManager.currentTime() - start) < max && !done)) { try { // sleep a backoff <= pauseTime amount long sleep = getPauseTime(tries++); sleep = sleep > maxPauseTime ? maxPauseTime : sleep; LOG.debug("(#" + tries + ") Sleeping: " + sleep + "ms while waiting for procedure completion."); Thread.sleep(sleep); } catch (InterruptedException e) { throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e); } LOG.debug("Getting current status of procedure from master..."); done = isProcedureFinished(signature, instance, props); } if (!done) { throw new IOException("Procedure '" + signature + " : " + instance + "' wasn't completed in expectedTime:" + max + " ms"); } }
/** * Execute a distributed procedure on a cluster. * * @param signature A distributed procedure is uniquely identified * by its signature (default the root ZK node name of the procedure). * @param instance The instance name of the procedure. For some procedures, this parameter is * optional. * @param props Property/Value pairs of properties passing to the procedure * @throws IOException */ @Override public void execProcedure(String signature, String instance, Map<String, String> props) throws IOException { ProcedureDescription.Builder builder = ProcedureDescription.newBuilder(); builder.setSignature(signature).setInstance(instance); for (Entry<String, String> entry : props.entrySet()) { NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey()) .setValue(entry.getValue()).build(); builder.addConfiguration(pair); } final ExecProcedureRequest request = ExecProcedureRequest.newBuilder() .setProcedure(builder.build()).build(); // run the procedure on the master ExecProcedureResponse response = executeCallable(new MasterCallable<ExecProcedureResponse>( getConnection()) { @Override public ExecProcedureResponse call(int callTimeout) throws ServiceException { return master.execProcedure(null, request); } }); long start = EnvironmentEdgeManager.currentTime(); long max = response.getExpectedTimeout(); long maxPauseTime = max / this.numRetries; int tries = 0; LOG.debug("Waiting a max of " + max + " ms for procedure '" + signature + " : " + instance + "'' to complete. (max " + maxPauseTime + " ms per retry)"); boolean done = false; while (tries == 0 || ((EnvironmentEdgeManager.currentTime() - start) < max && !done)) { try { // sleep a backoff <= pauseTime amount long sleep = getPauseTime(tries++); sleep = sleep > maxPauseTime ? maxPauseTime : sleep; LOG.debug("(#" + tries + ") Sleeping: " + sleep + "ms while waiting for procedure completion."); Thread.sleep(sleep); } catch (InterruptedException e) { throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e); } LOG.debug("Getting current status of procedure from master..."); done = isProcedureFinished(signature, instance, props); } if (!done) { throw new IOException("Procedure '" + signature + " : " + instance + "' wasn't completed in expectedTime:" + max + " ms"); } }
/** * Execute a distributed procedure on a cluster. * * @param signature A distributed procedure is uniquely identified * by its signature (default the root ZK node name of the procedure). * @param instance The instance name of the procedure. For some procedures, this parameter is * optional. * @param props Property/Value pairs of properties passing to the procedure */ public void execProcedure(String signature, String instance, Map<String, String> props) throws IOException { ProcedureDescription.Builder builder = ProcedureDescription.newBuilder(); builder.setSignature(signature).setInstance(instance); for (String key : props.keySet()) { NameStringPair pair = NameStringPair.newBuilder().setName(key) .setValue(props.get(key)).build(); builder.addConfiguration(pair); } final ExecProcedureRequest request = ExecProcedureRequest.newBuilder() .setProcedure(builder.build()).build(); // run the procedure on the master ExecProcedureResponse response = executeCallable(new MasterCallable<ExecProcedureResponse>( getConnection()) { @Override public ExecProcedureResponse call() throws ServiceException { return master.execProcedure(null, request); } }); long start = EnvironmentEdgeManager.currentTimeMillis(); long max = response.getExpectedTimeout(); long maxPauseTime = max / this.numRetries; int tries = 0; LOG.debug("Waiting a max of " + max + " ms for procedure '" + signature + " : " + instance + "'' to complete. (max " + maxPauseTime + " ms per retry)"); boolean done = false; while (tries == 0 || ((EnvironmentEdgeManager.currentTimeMillis() - start) < max && !done)) { try { // sleep a backoff <= pauseTime amount long sleep = getPauseTime(tries++); sleep = sleep > maxPauseTime ? maxPauseTime : sleep; LOG.debug("(#" + tries + ") Sleeping: " + sleep + "ms while waiting for procedure completion."); Thread.sleep(sleep); } catch (InterruptedException e) { LOG.debug("Interrupted while waiting for procedure " + signature + " to complete"); Thread.currentThread().interrupt(); } LOG.debug("Getting current status of procedure from master..."); done = isProcedureFinished(signature, instance, props); } if (!done) { throw new IOException("Procedure '" + signature + " : " + instance + "' wasn't completed in expectedTime:" + max + " ms"); } }
/** * Execute a distributed procedure on a cluster. * * @param signature A distributed procedure is uniquely identified * by its signature (default the root ZK node name of the procedure). * @param instance The instance name of the procedure. For some procedures, this parameter is * optional. * @param props Property/Value pairs of properties passing to the procedure */ public void execProcedure(String signature, String instance, Map<String, String> props) throws IOException { ProcedureDescription.Builder builder = ProcedureDescription.newBuilder(); builder.setSignature(signature).setInstance(instance); for (Entry<String, String> entry : props.entrySet()) { NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey()) .setValue(entry.getValue()).build(); builder.addConfiguration(pair); } final ExecProcedureRequest request = ExecProcedureRequest.newBuilder() .setProcedure(builder.build()).build(); // run the procedure on the master ExecProcedureResponse response = executeCallable(new MasterCallable<ExecProcedureResponse>( getConnection()) { @Override public ExecProcedureResponse call(int callTimeout) throws ServiceException { return master.execProcedure(null, request); } }); long start = EnvironmentEdgeManager.currentTimeMillis(); long max = response.getExpectedTimeout(); long maxPauseTime = max / this.numRetries; int tries = 0; LOG.debug("Waiting a max of " + max + " ms for procedure '" + signature + " : " + instance + "'' to complete. (max " + maxPauseTime + " ms per retry)"); boolean done = false; while (tries == 0 || ((EnvironmentEdgeManager.currentTimeMillis() - start) < max && !done)) { try { // sleep a backoff <= pauseTime amount long sleep = getPauseTime(tries++); sleep = sleep > maxPauseTime ? maxPauseTime : sleep; LOG.debug("(#" + tries + ") Sleeping: " + sleep + "ms while waiting for procedure completion."); Thread.sleep(sleep); } catch (InterruptedException e) { throw (InterruptedIOException)new InterruptedIOException("Interrupted").initCause(e); } LOG.debug("Getting current status of procedure from master..."); done = isProcedureFinished(signature, instance, props); } if (!done) { throw new IOException("Procedure '" + signature + " : " + instance + "' wasn't completed in expectedTime:" + max + " ms"); } }
/** * Execute a distributed procedure on cluster with return data. * * @param desc Procedure description * @return data returned from the procedure execution, null if no data * @throws IOException */ public byte[] execProcedureWithRet(ProcedureDescription desc) throws IOException { return null; }
/** * Check if the procedure is finished successfully * * @param desc Procedure description * @return true if the specified procedure is finished successfully * @throws IOException */ public abstract boolean isProcedureDone(ProcedureDescription desc) throws IOException;