Repository: incubator-slider
Updated Branches:
  refs/heads/develop 0b0022185 -> 67938ee99


SLIDER-782 moving all of AM IPC operations out of AM, moving to async queued 
events for all mutating operations


Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/7632f5de
Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/7632f5de
Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/7632f5de

Branch: refs/heads/develop
Commit: 7632f5de400ef7174bec7692db3a7201b12b83c5
Parents: c4a21ad
Author: Steve Loughran <[email protected]>
Authored: Tue Feb 10 21:35:18 2015 +0000
Committer: Steve Loughran <[email protected]>
Committed: Tue Feb 10 21:35:18 2015 +0000

----------------------------------------------------------------------
 .../apache/slider/common/SliderXmlConfKeys.java |  11 +
 .../exceptions/ServiceNotReadyException.java    |  43 +++
 .../providers/AbstractProviderService.java      |  12 +-
 .../appmaster/AppMasterActionOperations.java    |  32 ++
 .../server/appmaster/SliderAppMaster.java       |  60 +++-
 .../appmaster/actions/ActionFlexCluster.java    |  44 +++
 .../appmaster/actions/ActionKillContainer.java  |   5 +-
 .../actions/ReviewAndFlexApplicationSize.java   |   2 +-
 .../operations/AbstractRMOperation.java         |   3 +-
 .../operations/CancelRequestOperation.java      |   2 +-
 .../operations/ContainerReleaseOperation.java   |   2 +-
 .../operations/ContainerRequestOperation.java   |   2 +-
 .../operations/RMOperationHandler.java          |   7 +-
 .../operations/RMOperationHandlerActions.java   |   8 +
 .../slider/server/appmaster/rpc/RpcBinder.java  |  39 ++-
 .../rpc/SliderClusterProtocolService.java       | 299 +++++++++++++++++++
 .../slider/server/appmaster/state/AppState.java |   4 +-
 .../appmaster/state/ProviderAppState.java       |  18 +-
 .../state/StateAccessForProviders.java          |   9 +-
 .../slider/server/appmaster/web/WebAppApi.java  |   5 +-
 .../server/appmaster/web/WebAppApiImpl.java     |  11 +-
 .../appstate/StubSliderClusterProtocol.groovy   |   3 +
 .../TestMockAppStateAppRestIntegration.groovy   |   2 +-
 .../model/mock/MockProviderService.groovy       |   6 +
 .../view/TestClusterSpecificationBlock.groovy   |   2 +-
 .../web/view/TestContainerStatsBlock.groovy     |   2 +-
 .../appmaster/web/view/TestIndexBlock.groovy    |   2 +-
 .../agent/TestAgentProviderService.java         |   3 +-
 .../web/rest/agent/TestAMAgentWebServices.java  |   2 +-
 .../management/TestAMManagementWebServices.java |   2 +-
 30 files changed, 591 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java 
b/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java
index a89ae20..a808058 100644
--- a/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java
+++ b/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java
@@ -161,4 +161,15 @@ public interface SliderXmlConfKeys {
    */
   boolean X_DEV_INSECURE_REQUIRED = true;
 
+  /**
+   *
+   */
+  String KEY_IPC_CLIENT_RETRY_POLICY_ENABLED =
+      "slider.ipc.client.retry.enabled";
+  public static final boolean IPC_CLIENT_RETRY_POLICY_ENABLED_DEFAULT = true;
+  public static final String KEY_IPC_CLIENT_RETRY_POLICY_SPEC =
+      "slider.ipc.client.retry.policy.spec";
+  public static final String IPC_CLIENT_RETRY_POLICY_SPEC_DEFAULT =
+      "10000,6,60000,10"; //t1,n1,t2,n2,... 
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/core/exceptions/ServiceNotReadyException.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/core/exceptions/ServiceNotReadyException.java
 
b/slider-core/src/main/java/org/apache/slider/core/exceptions/ServiceNotReadyException.java
new file mode 100644
index 0000000..435bc1a
--- /dev/null
+++ 
b/slider-core/src/main/java/org/apache/slider/core/exceptions/ServiceNotReadyException.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.core.exceptions;
+
+import java.io.IOException;
+
+/**
+ * This is an exception raised when the service does not consider itself
+ * live (yet)
+ */
+public class ServiceNotReadyException extends IOException {
+
+  public static final String E_NOT_READY =
+      "Service not ready for access: please retry";
+
+  public ServiceNotReadyException(String message) {
+    super(message);
+  }
+
+  public ServiceNotReadyException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public ServiceNotReadyException(Throwable cause) {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
 
b/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
index 6856400..fd7df73 100644
--- 
a/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
+++ 
b/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java
@@ -39,6 +39,7 @@ import 
org.apache.slider.core.exceptions.BadCommandArgumentsException;
 import org.apache.slider.core.exceptions.SliderException;
 import org.apache.slider.core.main.ExitCodeProvider;
 import org.apache.slider.server.appmaster.actions.QueueAccess;
+import org.apache.slider.server.appmaster.operations.AbstractRMOperation;
 import org.apache.slider.server.appmaster.state.ContainerReleaseSelector;
 import 
org.apache.slider.server.appmaster.state.MostRecentContainerReleaseSelector;
 import org.apache.slider.server.appmaster.state.StateAccessForProviders;
@@ -180,9 +181,8 @@ public abstract class AbstractProviderService
   @Override
   public void validateApplicationConfiguration(AggregateConf instance,
                                                File confDir,
-                                               boolean secure) throws
-      IOException,
-      SliderException {
+                                               boolean secure)
+      throws IOException, SliderException {
 
   }
 
@@ -411,6 +411,12 @@ public abstract class AbstractProviderService
     return 0;
   }
 
+  @Override
+  public void execute(List<AbstractRMOperation> operations) {
+    for (AbstractRMOperation operation : operations) {
+      operation.execute(this);
+    }
+  }
   /**
    * No-op implementation of this method.
    */

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/AppMasterActionOperations.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/AppMasterActionOperations.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/AppMasterActionOperations.java
new file mode 100644
index 0000000..d78b718
--- /dev/null
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/AppMasterActionOperations.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.server.appmaster;
+
+import org.apache.slider.server.appmaster.operations.AbstractRMOperation;
+import org.apache.slider.server.appmaster.operations.RMOperationHandlerActions;
+
+import java.util.List;
+
+/**
+ * Interface of AM operations
+ */
+public interface AppMasterActionOperations extends RMOperationHandlerActions {
+
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
index f1e3a84..ab67b16 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
@@ -54,7 +54,9 @@ import org.apache.hadoop.yarn.api.records.ContainerState;
 import org.apache.hadoop.yarn.api.records.ContainerStatus;
 import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
 import org.apache.hadoop.yarn.api.records.NodeReport;
+import org.apache.hadoop.yarn.api.records.Priority;
 import org.apache.hadoop.yarn.api.records.Resource;
+import org.apache.hadoop.yarn.client.api.AMRMClient;
 import org.apache.hadoop.yarn.client.api.async.AMRMClientAsync;
 import org.apache.hadoop.yarn.client.api.async.NMClientAsync;
 import org.apache.hadoop.yarn.client.api.async.impl.NMClientAsyncImpl;
@@ -83,7 +85,6 @@ import org.apache.slider.api.proto.Messages;
 import org.apache.slider.api.proto.SliderClusterAPI;
 import org.apache.slider.common.SliderExitCodes;
 import org.apache.slider.common.SliderKeys;
-import static org.apache.slider.common.SliderXmlConfKeys.*;
 import org.apache.slider.common.params.AbstractActionArgs;
 import org.apache.slider.common.params.SliderAMArgs;
 import org.apache.slider.common.params.SliderAMCreateAction;
@@ -138,6 +139,7 @@ import org.apache.slider.server.appmaster.rpc.RpcBinder;
 import org.apache.slider.server.appmaster.rpc.SliderAMPolicyProvider;
 import org.apache.slider.server.appmaster.rpc.SliderClusterProtocolPBImpl;
 import org.apache.slider.server.appmaster.operations.AbstractRMOperation;
+import org.apache.slider.server.appmaster.rpc.SliderClusterProtocolService;
 import org.apache.slider.server.appmaster.security.SecurityConfiguration;
 import org.apache.slider.server.appmaster.state.AppState;
 import org.apache.slider.server.appmaster.state.ContainerAssignment;
@@ -195,7 +197,8 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
     SliderClusterProtocol,
     ServiceStateChangeListener,
     RoleKeys,
-    ProviderCompleted {
+    ProviderCompleted,
+    AppMasterActionOperations {
 
   protected static final Logger log =
     LoggerFactory.getLogger(SliderAppMaster.class);
@@ -246,6 +249,13 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
    */
   private Credentials containerCredentials;
 
+  /**
+   * Slider IPC: Real service handler
+   */
+  private SliderClusterProtocolService sliderIPCService;
+  /**
+   * Slider IPC: binding
+   */
   private WorkflowRpcService rpcService;
 
   /**
@@ -744,9 +754,11 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
       appInformation.put(StatusKeys.INFO_AM_WEB_URL, appMasterTrackingUrl + 
"/");
       appInformation.set(StatusKeys.INFO_AM_WEB_PORT, webAppPort);
 
+      // *****************************************************
       // Register self with ResourceManager
       // This will start heartbeating to the RM
       // address = 
SliderUtils.getRmSchedulerAddress(asyncRMClient.getConfig());
+      // *****************************************************
       log.info("Connecting to RM at {},address tracking URL={}",
                appMasterRpcPort, appMasterTrackingUrl);
       amRegistrationData = asyncRMClient
@@ -805,8 +817,8 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
       providerService
           .initializeApplicationConfiguration(instanceDefinition, fs);
 
-      providerService.validateApplicationConfiguration(instanceDefinition, 
-                                                       confDir,
+      providerService.validateApplicationConfiguration(instanceDefinition,
+          confDir,
           securityEnabled);
 
       //determine the location for the role history data
@@ -903,13 +915,17 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
               certificateManager,
               registryOperations,
               metricsAndMonitoring,
-              actionQueues);
+              actionQueues,
+              this);
       initAMFilterOptions(serviceConf);
 
       // start the agent web app
       startAgentWebApp(appInformation, serviceConf, webAppApi);
       deployWebApplication(webAppPort, webAppApi);
 
+      // bind the IPC service to the API
+      sliderIPCService.bind(webAppApi);
+      
       // schedule YARN Registry registration
       queue(new ActionRegisterServiceInstance(clustername, appid));
 
@@ -1473,9 +1489,11 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
       throws IOException, SliderException {
     verifyIPCAccess();
 
+    sliderIPCService = new SliderClusterProtocolService();
 
+    deployChildService(sliderIPCService);
     SliderClusterProtocolPBImpl protobufRelay =
-        new SliderClusterProtocolPBImpl(this);
+        new SliderClusterProtocolPBImpl(sliderIPCService);
     BlockingService blockingService = SliderClusterAPI.SliderClusterProtocolPB
         .newReflectiveBlockingService(
             protobufRelay);
@@ -1545,7 +1563,7 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
     }
     
     //for all the operations, exec them
-    executeRMOperations(operations);
+    execute(operations);
     log.info("Diagnostics: {}", getContainerDiagnosticInfo());
   }
 
@@ -1590,7 +1608,7 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
    * @throws SliderException slider problems, including invalid configs
    * @throws IOException IO problems
    */
-  private void flexCluster(ConfTree resources)
+  public void flexCluster(ConfTree resources)
       throws IOException, SliderException {
 
     AggregateConf newConf =
@@ -1685,7 +1703,7 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
       // tell the provider
       providerRMOperationHandler.execute(allOperations);
       //now apply the operations
-      executeRMOperations(allOperations);
+      execute(allOperations);
     } catch (TriggerClusterTeardownException e) {
       //App state has decided that it is time to exit
       log.error("Cluster teardown triggered {}", e, e);
@@ -1698,7 +1716,7 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
    */
   private void releaseAllContainers() {
     //now apply the operations
-    executeRMOperations(appState.releaseAllContainers());
+    execute(appState.releaseAllContainers());
   }
 
   /**
@@ -1939,11 +1957,29 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
     return builder.build();
   }
 
-  public void executeRMOperations(List<AbstractRMOperation> operations) {
+  @Override
+  public void execute(List<AbstractRMOperation> operations) {
     rmOperationHandler.execute(operations);
   }
 
   @Override
+  public void releaseAssignedContainer(ContainerId containerId) {
+    rmOperationHandler.releaseAssignedContainer(containerId);
+  }
+
+  @Override
+  public void addContainerRequest(AMRMClient.ContainerRequest req) {
+    rmOperationHandler.addContainerRequest(req);
+  }
+
+  @Override
+  public int cancelContainerRequests(Priority priority1,
+      Priority priority2,
+      int count) {
+    return rmOperationHandler.cancelContainerRequests(priority1, priority2, 
count);
+  }
+
+  @Override
   public Messages.AMSuicideResponseProto amSuicide(
       Messages.AMSuicideRequestProto request)
       throws IOException, YarnException {
@@ -2030,7 +2066,7 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
         containerId);
     RoleInstance activeContainer = appState.getOwnedContainer(containerId);
     if (activeContainer != null) {
-      executeRMOperations(appState.releaseContainer(containerId));
+      execute(appState.releaseContainer(containerId));
       // ask for more containers if needed
       log.info("Container released; triggering review");
       reviewRequestAndReleaseNodes("Loss of container");

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionFlexCluster.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionFlexCluster.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionFlexCluster.java
new file mode 100644
index 0000000..6b61681
--- /dev/null
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionFlexCluster.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.server.appmaster.actions;
+
+import org.apache.slider.core.conf.ConfTree;
+import org.apache.slider.server.appmaster.SliderAppMaster;
+import org.apache.slider.server.appmaster.state.AppState;
+
+import java.util.concurrent.TimeUnit;
+
+public class ActionFlexCluster extends AsyncAction {
+
+  public final ConfTree resources;
+  
+  public ActionFlexCluster(String name,
+      long delay,
+      TimeUnit timeUnit, ConfTree resources) {
+    super(name, delay, timeUnit, ATTR_CHANGES_APP_SIZE);
+    this.resources = resources;
+  }
+
+  @Override
+  public void execute(SliderAppMaster appMaster,
+      QueueAccess queueService,
+      AppState appState) throws Exception {
+    appMaster.flexCluster(resources);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java
index 95bf067..1aa9088 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java
@@ -24,6 +24,7 @@ import org.apache.slider.server.appmaster.SliderAppMaster;
 import org.apache.slider.server.appmaster.operations.AbstractRMOperation;
 import org.apache.slider.server.appmaster.operations.ContainerReleaseOperation;
 import org.apache.slider.server.appmaster.operations.RMOperationHandler;
+import org.apache.slider.server.appmaster.operations.RMOperationHandlerActions;
 import org.apache.slider.server.appmaster.state.AppState;
 
 import java.util.LinkedList;
@@ -43,7 +44,7 @@ public class ActionKillContainer extends AsyncAction {
   /**
    *  handler for the operation
    */
-  private final RMOperationHandler operationHandler;
+  private final RMOperationHandlerActions operationHandler;
 
   /**
    * Kill a container
@@ -56,7 +57,7 @@ public class ActionKillContainer extends AsyncAction {
       ContainerId containerId,
       long delay,
       TimeUnit timeUnit,
-      RMOperationHandler operationHandler) {
+      RMOperationHandlerActions operationHandler) {
     super("kill container", delay, timeUnit, ATTR_CHANGES_APP_SIZE);
     this.operationHandler = operationHandler;
     Preconditions.checkArgument(containerId != null);

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ReviewAndFlexApplicationSize.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ReviewAndFlexApplicationSize.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ReviewAndFlexApplicationSize.java
index 273f599..bf7edf9 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ReviewAndFlexApplicationSize.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ReviewAndFlexApplicationSize.java
@@ -26,7 +26,7 @@ import java.util.concurrent.TimeUnit;
 /**
  * Tell the AM to execute the full flex review operation
  */
-public class ReviewAndFlexApplicationSize extends AsyncAction{
+public class ReviewAndFlexApplicationSize extends AsyncAction {
 
   public ReviewAndFlexApplicationSize(String name,
       long delay,

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AbstractRMOperation.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AbstractRMOperation.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AbstractRMOperation.java
index 2c55215..da8d646 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AbstractRMOperation.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AbstractRMOperation.java
@@ -23,7 +23,8 @@ public abstract class AbstractRMOperation {
   /**
    * Execute the operation
    * @param asyncRMClient client
+   * @param handler
    */
-  public abstract void execute(RMOperationHandler handler);
+  public abstract void execute(RMOperationHandlerActions handler);
   
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/CancelRequestOperation.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/CancelRequestOperation.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/CancelRequestOperation.java
index be5dbab..9e9f277 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/CancelRequestOperation.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/CancelRequestOperation.java
@@ -37,7 +37,7 @@ public class CancelRequestOperation extends 
AbstractRMOperation {
   }
 
   @Override
-  public void execute(RMOperationHandler handler) {
+  public void execute(RMOperationHandlerActions handler) {
     handler.cancelContainerRequests(priority1, priority2, count);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerReleaseOperation.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerReleaseOperation.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerReleaseOperation.java
index 3d2016b..46da536 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerReleaseOperation.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerReleaseOperation.java
@@ -33,7 +33,7 @@ public class ContainerReleaseOperation extends 
AbstractRMOperation {
   }
 
   @Override
-  public void execute(RMOperationHandler handler) {
+  public void execute(RMOperationHandlerActions handler) {
     handler.releaseAssignedContainer(containerId);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerRequestOperation.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerRequestOperation.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerRequestOperation.java
index 203f898..b8120ca 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerRequestOperation.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ContainerRequestOperation.java
@@ -34,7 +34,7 @@ public class ContainerRequestOperation extends 
AbstractRMOperation {
   }
 
   @Override
-  public void execute(RMOperationHandler handler) {
+  public void execute(RMOperationHandlerActions handler) {
     handler.addContainerRequest(request);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandler.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandler.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandler.java
index 3ab9d89..d0d038a 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandler.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandler.java
@@ -18,16 +18,11 @@
 
 package org.apache.slider.server.appmaster.operations;
 
-import org.apache.hadoop.yarn.api.records.Priority;
-
 import java.util.List;
 
 public abstract class RMOperationHandler implements RMOperationHandlerActions {
 
-  /**
-   * Execute an entire list of operations
-   * @param operations ops
-   */
+  @Override
   public void execute(List<AbstractRMOperation> operations) {
     for (AbstractRMOperation operation : operations) {
       operation.execute(this);

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandlerActions.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandlerActions.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandlerActions.java
index e6d6c9d..97fde09 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandlerActions.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandlerActions.java
@@ -22,6 +22,8 @@ import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.hadoop.yarn.api.records.Priority;
 import org.apache.hadoop.yarn.client.api.AMRMClient;
 
+import java.util.List;
+
 public interface RMOperationHandlerActions {
   void releaseAssignedContainer(ContainerId containerId);
 
@@ -34,4 +36,10 @@ public interface RMOperationHandlerActions {
    * @param count number to remove
    */
   int cancelContainerRequests(Priority priority1, Priority priority2, int 
count);
+
+  /**
+   * Execute an entire list of operations
+   * @param operations ops
+   */
+  void execute(List<AbstractRMOperation> operations);
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/rpc/RpcBinder.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/rpc/RpcBinder.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/rpc/RpcBinder.java
index 4cb6ee1..080d0f2 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/rpc/RpcBinder.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/rpc/RpcBinder.java
@@ -20,6 +20,8 @@ package org.apache.slider.server.appmaster.rpc;
 
 import com.google.protobuf.BlockingService;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.io.retry.RetryPolicy;
+import org.apache.hadoop.io.retry.RetryUtils;
 import org.apache.hadoop.ipc.ProtobufRpcEngine;
 import org.apache.hadoop.ipc.ProtocolProxy;
 import org.apache.hadoop.ipc.RPC;
@@ -43,7 +45,11 @@ import org.apache.slider.common.SliderExitCodes;
 import org.apache.slider.common.tools.Duration;
 import org.apache.slider.core.exceptions.BadClusterStateException;
 import org.apache.slider.core.exceptions.ErrorStrings;
+import org.apache.slider.core.exceptions.ServiceNotReadyException;
 import org.apache.slider.core.exceptions.SliderException;
+
+import static org.apache.slider.common.SliderXmlConfKeys.*; 
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -112,6 +118,15 @@ public class RpcBinder {
   }
 
 
+  /**
+   * Connect to a server. May include setting up retry policies
+   * @param addr
+   * @param currentUser
+   * @param conf
+   * @param rpcTimeout
+   * @return
+   * @throws IOException
+   */
   public static SliderClusterProtocol connectToServer(InetSocketAddress addr,
                                                     UserGroupInformation 
currentUser,
                                                     Configuration conf,
@@ -119,16 +134,24 @@ public class RpcBinder {
     Class<SliderClusterProtocolPB> sliderClusterAPIClass = registerSliderAPI(
         conf);
 
+    final RetryPolicy retryPolicy =
+        RetryUtils.getDefaultRetryPolicy(
+            conf,
+            KEY_IPC_CLIENT_RETRY_POLICY_ENABLED,
+            IPC_CLIENT_RETRY_POLICY_ENABLED_DEFAULT,
+            KEY_IPC_CLIENT_RETRY_POLICY_SPEC,
+            IPC_CLIENT_RETRY_POLICY_SPEC_DEFAULT,
+            ServiceNotReadyException.class);
     log.debug("Connecting to Slider AM at {}", addr);
     ProtocolProxy<SliderClusterProtocolPB> protoProxy =
-      RPC.getProtocolProxy(sliderClusterAPIClass,
-                           1,
-                           addr,
-                           currentUser,
-                           conf,
-                           NetUtils.getDefaultSocketFactory(conf),
-                           rpcTimeout,
-                           null);
+        RPC.getProtocolProxy(sliderClusterAPIClass,
+            1,
+            addr,
+            currentUser,
+            conf,
+            NetUtils.getDefaultSocketFactory(conf),
+            rpcTimeout,
+            retryPolicy);
     SliderClusterProtocolPB endpoint = protoProxy.getProxy();
     return new SliderClusterProtocolProxy(endpoint, addr);
   }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/rpc/SliderClusterProtocolService.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/rpc/SliderClusterProtocolService.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/rpc/SliderClusterProtocolService.java
new file mode 100644
index 0000000..613bda4
--- /dev/null
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/rpc/SliderClusterProtocolService.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.server.appmaster.rpc;
+
+import org.apache.hadoop.ipc.ProtocolSignature;
+import org.apache.hadoop.service.AbstractService;
+import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
+import org.apache.hadoop.yarn.exceptions.YarnException;
+import org.apache.slider.api.ClusterDescription;
+import org.apache.slider.api.SliderClusterProtocol;
+import org.apache.slider.api.proto.Messages;
+import org.apache.slider.core.conf.AggregateConf;
+import org.apache.slider.core.conf.ConfTree;
+import org.apache.slider.core.exceptions.ServiceNotReadyException;
+import org.apache.slider.core.main.LauncherExitCodes;
+import org.apache.slider.core.persist.ConfTreeSerDeser;
+import org.apache.slider.server.appmaster.actions.ActionFlexCluster;
+import org.apache.slider.server.appmaster.actions.ActionHalt;
+import org.apache.slider.server.appmaster.actions.ActionKillContainer;
+import org.apache.slider.server.appmaster.actions.ActionStopSlider;
+import org.apache.slider.server.appmaster.actions.AsyncAction;
+import org.apache.slider.server.appmaster.actions.QueueAccess;
+import org.apache.slider.server.appmaster.management.MetricsAndMonitoring;
+import org.apache.slider.server.appmaster.state.RoleInstance;
+import org.apache.slider.server.appmaster.state.StateAccessForProviders;
+import org.apache.slider.server.appmaster.web.WebAppApi;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implement the {@link SliderClusterProtocol}.
+ * Important: not live until {@link #bind(WebAppApi)}
+ * is invoked. Until then all RPC calls will raise an exception.
+ */
+public class SliderClusterProtocolService extends AbstractService
+    implements SliderClusterProtocol {
+
+  protected static final Logger log =
+      LoggerFactory.getLogger(SliderClusterProtocol.class);
+
+  private WebAppApi appmaster;
+  private QueueAccess actionQueues;
+  private StateAccessForProviders appState;
+  private MetricsAndMonitoring metricsAndMonitoring;
+  public static final String PROTOCOL_PREFIX =
+      "org.apache.slider.api.SliderClusterProtocol.";
+
+  public SliderClusterProtocolService() {
+    super("SliderClusterProtocolService");
+  }
+
+  /**
+   * Bind to the AM API
+   * @param appmaster api binding.
+   */
+  public void bind(WebAppApi appmaster) {
+    this.appmaster = appmaster;
+    actionQueues = appmaster.getQueues();
+    appState = appmaster.getAppState();
+    metricsAndMonitoring = appmaster.getMetricsAndMonitoring();
+  }
+  
+
+  @Override   //SliderClusterProtocol
+  public ProtocolSignature getProtocolSignature(String protocol,
+      long clientVersion,
+      int clientMethodsHash) throws IOException {
+    return ProtocolSignature.getProtocolSignature(
+        this, protocol, clientVersion, clientMethodsHash);
+  }
+
+
+  @Override   //SliderClusterProtocol
+  public long getProtocolVersion(String protocol, long clientVersion)
+      throws IOException {
+    return SliderClusterProtocol.versionID;
+  }
+
+  /**
+   * General actions to perform on a slider RPC call coming in
+   * @param operation operation to log
+   * @throws IOException problems
+   * @throws ServiceNotReadyException if the RPC service is constructed
+   * but not fully initialized
+   */
+  protected void onRpcCall(String operation) throws IOException {
+    log.debug("Received call to {}", operation);
+    if (appmaster == null) {
+      // fail fast if the service is not ready
+      log.warn("Rejecting {} as service is not ready", operation);
+      throw new ServiceNotReadyException(ServiceNotReadyException.E_NOT_READY);
+    }
+    metricsAndMonitoring.markMeterAndCounter(PROTOCOL_PREFIX + operation);
+  }
+
+  /**
+   * Schedule an action
+   * @param action for delayed execution
+   */
+  public void schedule(AsyncAction action) {
+    actionQueues.schedule(action);
+  }
+
+  /**
+   * Queue an action for immediate execution in the executor thread
+   * @param action action to execute
+   */
+  public void queue(AsyncAction action) {
+    actionQueues.put(action);
+  }
+
+  @Override //SliderClusterProtocol
+  public Messages.StopClusterResponseProto 
stopCluster(Messages.StopClusterRequestProto request)
+      throws IOException, YarnException {
+    onRpcCall("stop");
+    String message = request.getMessage();
+    if (message == null) {
+      message = "application stopped by client";
+    }
+    ActionStopSlider stopSlider =
+        new ActionStopSlider(message,
+            1000, TimeUnit.MILLISECONDS,
+            LauncherExitCodes.EXIT_SUCCESS,
+            FinalApplicationStatus.SUCCEEDED,
+            message);
+    log.info("SliderAppMasterApi.stopCluster: {}", stopSlider);
+    schedule(stopSlider);
+    return Messages.StopClusterResponseProto.getDefaultInstance();
+  }
+
+  @Override //SliderClusterProtocol
+  public Messages.FlexClusterResponseProto 
flexCluster(Messages.FlexClusterRequestProto request)
+      throws IOException, YarnException {
+    onRpcCall("flex");
+    String payload = request.getClusterSpec();
+    ConfTreeSerDeser confTreeSerDeser = new ConfTreeSerDeser();
+    ConfTree updatedResources = confTreeSerDeser.fromJson(payload);
+    schedule(new ActionFlexCluster("flex", 1, TimeUnit.MILLISECONDS,
+        updatedResources));
+    return Messages.FlexClusterResponseProto.newBuilder().setResponse(
+        true).build();
+  }
+
+  @Override //SliderClusterProtocol
+  public Messages.GetJSONClusterStatusResponseProto getJSONClusterStatus(
+      Messages.GetJSONClusterStatusRequestProto request)
+      throws IOException, YarnException {
+    onRpcCall("getstatus");
+    String result;
+    //quick update
+    //query and json-ify
+    ClusterDescription cd = appState.refreshClusterStatus();
+    result = cd.toJsonString();
+    String stat = result;
+    return Messages.GetJSONClusterStatusResponseProto.newBuilder()
+                                                     .setClusterSpec(stat)
+                                                     .build();
+  }
+
+  @Override
+  public Messages.GetInstanceDefinitionResponseProto getInstanceDefinition(
+      Messages.GetInstanceDefinitionRequestProto request)
+      throws IOException, YarnException {
+
+    onRpcCall("getinstancedefinition");
+    String internal;
+    String resources;
+    String app;
+    AggregateConf instanceDefinition =
+        appState.getInstanceDefinitionSnapshot();
+    internal = instanceDefinition.getInternal().toJson();
+    resources = instanceDefinition.getResources().toJson();
+    app = instanceDefinition.getAppConf().toJson();
+    assert internal != null;
+    assert resources != null;
+    assert app != null;
+    log.debug("Generating getInstanceDefinition Response");
+    Messages.GetInstanceDefinitionResponseProto.Builder builder =
+        Messages.GetInstanceDefinitionResponseProto.newBuilder();
+    builder.setInternal(internal);
+    builder.setResources(resources);
+    builder.setApplication(app);
+    return builder.build();
+  }
+
+  @Override //SliderClusterProtocol
+  public Messages.ListNodeUUIDsByRoleResponseProto 
listNodeUUIDsByRole(Messages.ListNodeUUIDsByRoleRequestProto request)
+      throws IOException, YarnException {
+    onRpcCall("listnodes)");
+    String role = request.getRole();
+    Messages.ListNodeUUIDsByRoleResponseProto.Builder builder =
+        Messages.ListNodeUUIDsByRoleResponseProto.newBuilder();
+    List<RoleInstance> nodes = appState.enumLiveNodesInRole(role);
+    for (RoleInstance node : nodes) {
+      builder.addUuid(node.id);
+    }
+    return builder.build();
+  }
+
+  @Override //SliderClusterProtocol
+  public Messages.GetNodeResponseProto getNode(Messages.GetNodeRequestProto 
request)
+      throws IOException, YarnException {
+    onRpcCall("getnode");
+    RoleInstance instance = appState.getLiveInstanceByContainerID(
+        request.getUuid());
+    return Messages.GetNodeResponseProto.newBuilder()
+                                        .setClusterNode(instance.toProtobuf())
+                                        .build();
+  }
+
+  @Override //SliderClusterProtocol
+  public Messages.GetClusterNodesResponseProto getClusterNodes(
+      Messages.GetClusterNodesRequestProto request)
+      throws IOException, YarnException {
+    onRpcCall("getclusternodes");
+    List<RoleInstance>
+        clusterNodes = appState.getLiveInstancesByContainerIDs(
+        request.getUuidList());
+
+    Messages.GetClusterNodesResponseProto.Builder builder =
+        Messages.GetClusterNodesResponseProto.newBuilder();
+    for (RoleInstance node : clusterNodes) {
+      builder.addClusterNode(node.toProtobuf());
+    }
+    //at this point: a possibly empty list of nodes
+    return builder.build();
+  }
+
+  @Override
+  public Messages.EchoResponseProto echo(Messages.EchoRequestProto request)
+      throws IOException, YarnException {
+    onRpcCall("echo");
+    Messages.EchoResponseProto.Builder builder =
+        Messages.EchoResponseProto.newBuilder();
+    String text = request.getText();
+    log.info("Echo request size ={}", text.length());
+    log.info(text);
+    //now return it
+    builder.setText(text);
+    return builder.build();
+  }
+
+  @Override
+  public Messages.KillContainerResponseProto 
killContainer(Messages.KillContainerRequestProto request)
+      throws IOException, YarnException {
+    onRpcCall("killcontainer");
+    String containerID = request.getId();
+    log.info("Kill Container {}", containerID);
+    //throws NoSuchNodeException if it is missing
+    RoleInstance instance =
+        appState.getLiveInstanceByContainerID(containerID);
+    queue(new ActionKillContainer(instance.getId(), 0, TimeUnit.MILLISECONDS,
+        appmaster.getAMOperations()));
+    Messages.KillContainerResponseProto.Builder builder =
+        Messages.KillContainerResponseProto.newBuilder();
+    builder.setSuccess(true);
+    return builder.build();
+  }
+
+
+  @Override
+  public Messages.AMSuicideResponseProto amSuicide(
+      Messages.AMSuicideRequestProto request)
+      throws IOException, YarnException {
+    onRpcCall("amsuicide");
+    int signal = request.getSignal();
+    String text = request.getText();
+    if (text == null) {
+      text = "";
+    }
+    int delay = request.getDelay();
+    log.info("AM Suicide with signal {}, message {} delay = {}", signal, text,
+        delay);
+    ActionHalt action = new ActionHalt(signal, text, delay,
+        TimeUnit.MILLISECONDS);
+    schedule(action);
+    return Messages.AMSuicideResponseProto.getDefaultInstance();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java
index a4ca130..854a706 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java
@@ -1631,8 +1631,8 @@ public class AppState {
    * Update the cluster description with the current application state
    */
 
-  public void refreshClusterStatus() {
-    refreshClusterStatus(null);
+  public ClusterDescription refreshClusterStatus() {
+    return refreshClusterStatus(null);
   }
   
   /**

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java
index da91bbf..b5b2cb7 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java
@@ -215,8 +215,8 @@ public class ProviderAppState implements 
StateAccessForProviders {
   }
 
   @Override
-  public void refreshClusterStatus() {
-    appState.refreshClusterStatus();
+  public ClusterDescription refreshClusterStatus() {
+    return appState.refreshClusterStatus();
   }
 
   @Override
@@ -243,4 +243,18 @@ public class ProviderAppState implements 
StateAccessForProviders {
   public Map<String, Map<String, ClusterNode>> getRoleClusterNodeMapping() {
     return appState.createRoleToClusterNodeMap();
   }
+
+  @Override
+  public List<RoleInstance> enumLiveNodesInRole(String role) {
+    List<RoleInstance> nodes = new ArrayList<RoleInstance>();
+    Collection<RoleInstance> allRoleInstances = cloneLiveContainerInfoList();
+        getLiveNodes().values();
+    for (RoleInstance node : allRoleInstances) {
+      if (role.isEmpty() || role.equals(node.role)) {
+        nodes.add(node);
+      }
+    }
+    return nodes;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java
index a1c6f24..0ea5428 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java
@@ -229,7 +229,7 @@ public interface StateAccessForProviders {
   /**
    * Update the cluster description with anything interesting
    */
-  void refreshClusterStatus();
+  ClusterDescription refreshClusterStatus();
 
   /**
    * Get a deep clone of the role status list. Concurrent events may mean this
@@ -265,4 +265,11 @@ public interface StateAccessForProviders {
    * @return 
    */
   Map<String, Map<String, ClusterNode>> getRoleClusterNodeMapping();
+
+  /**
+   * Enum all nodes by role. 
+   * @param role role, or "" for all roles
+   * @return a list of nodes, may be empty
+   */
+  List<RoleInstance> enumLiveNodesInRole(String role);
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/web/WebAppApi.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/WebAppApi.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/WebAppApi.java
index db32e48..e198e35 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/WebAppApi.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/WebAppApi.java
@@ -19,6 +19,7 @@ package org.apache.slider.server.appmaster.web;
 import org.apache.hadoop.registry.client.api.RegistryOperations;
 import org.apache.slider.api.SliderClusterProtocol;
 import org.apache.slider.providers.ProviderService;
+import org.apache.slider.server.appmaster.AppMasterActionOperations;
 import org.apache.slider.server.appmaster.actions.QueueAccess;
 import org.apache.slider.server.appmaster.management.MetricsAndMonitoring;
 import org.apache.slider.server.appmaster.state.AppState;
@@ -65,8 +66,7 @@ public interface WebAppApi {
    * Returns an interface that can support the agent-based REST operations.
    */
   AgentRestOperations getAgentRestOperations();
-
-
+  
   /**
    * Registry operations accessor
    * @return registry access
@@ -85,4 +85,5 @@ public interface WebAppApi {
    */
   QueueAccess getQueues();
 
+  AppMasterActionOperations getAMOperations();
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/main/java/org/apache/slider/server/appmaster/web/WebAppApiImpl.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/WebAppApiImpl.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/WebAppApiImpl.java
index 0597c39..4eb984f 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/WebAppApiImpl.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/WebAppApiImpl.java
@@ -19,6 +19,7 @@ package org.apache.slider.server.appmaster.web;
 import org.apache.hadoop.registry.client.api.RegistryOperations;
 import org.apache.slider.api.SliderClusterProtocol;
 import org.apache.slider.providers.ProviderService;
+import org.apache.slider.server.appmaster.AppMasterActionOperations;
 import org.apache.slider.server.appmaster.actions.QueueAccess;
 import org.apache.slider.server.appmaster.management.MetricsAndMonitoring;
 import org.apache.slider.server.appmaster.state.RoleStatus;
@@ -47,6 +48,7 @@ public class WebAppApiImpl implements WebAppApi {
   private final RegistryOperations registryOperations;
   private final MetricsAndMonitoring metricsAndMonitoring;
   private final QueueAccess queues;
+  private final AppMasterActionOperations appMasterOperations;
 
   public WebAppApiImpl(SliderClusterProtocol clusterProto,
       StateAccessForProviders appState,
@@ -54,7 +56,9 @@ public class WebAppApiImpl implements WebAppApi {
       CertificateManager certificateManager,
       RegistryOperations registryOperations,
       MetricsAndMonitoring metricsAndMonitoring,
-      QueueAccess queues) {
+      QueueAccess queues,
+      AppMasterActionOperations appMasterOperations) {
+    this.appMasterOperations = appMasterOperations;
     checkNotNull(clusterProto);
     checkNotNull(appState);
     checkNotNull(provider);
@@ -118,4 +122,9 @@ public class WebAppApiImpl implements WebAppApi {
   public QueueAccess getQueues() {
     return queues;
   }
+
+  @Override
+  public AppMasterActionOperations getAMOperations() {
+    return appMasterOperations;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/StubSliderClusterProtocol.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/StubSliderClusterProtocol.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/StubSliderClusterProtocol.groovy
index 0836dcb..eb05d61 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/StubSliderClusterProtocol.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/StubSliderClusterProtocol.groovy
@@ -23,6 +23,9 @@ import org.apache.hadoop.yarn.exceptions.YarnException
 import org.apache.slider.api.SliderClusterProtocol
 import org.apache.slider.api.proto.Messages
 
+/**
+ * Stub implementation of the Protobuf <code>SliderClusterProtocol</code>
+ */
 class StubSliderClusterProtocol implements SliderClusterProtocol {
   @Override
   Messages.StopClusterResponseProto stopCluster(

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/TestMockAppStateAppRestIntegration.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/TestMockAppStateAppRestIntegration.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/TestMockAppStateAppRestIntegration.groovy
index 4fc82b9..a43ee1e 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/TestMockAppStateAppRestIntegration.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/TestMockAppStateAppRestIntegration.groovy
@@ -118,7 +118,7 @@ class TestMockAppStateAppRestIntegration extends 
BaseMockAppStateTest implements
         stateAccess,
         new MockProviderService(),
         null, null,
-        new MetricsAndMonitoring("metrics"), null)
+        new MetricsAndMonitoring("metrics"), null, null)
     return api
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy
index e62c24e..f8ab56d 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy
@@ -39,6 +39,7 @@ import org.apache.slider.providers.ProviderCompleted
 import org.apache.slider.providers.ProviderRole
 import org.apache.slider.providers.ProviderService
 import org.apache.slider.server.appmaster.actions.QueueAccess
+import org.apache.slider.server.appmaster.operations.AbstractRMOperation
 import org.apache.slider.server.appmaster.state.ContainerReleaseSelector
 import 
org.apache.slider.server.appmaster.state.MostRecentContainerReleaseSelector
 import org.apache.slider.server.appmaster.state.StateAccessForProviders
@@ -275,6 +276,11 @@ class MockProviderService implements ProviderService {
   }
 
   @Override
+  void execute(List<AbstractRMOperation> operations) {
+
+  }
+
+  @Override
   int cancelContainerRequests(
       Priority priority1,
       Priority priority2,

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestClusterSpecificationBlock.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestClusterSpecificationBlock.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestClusterSpecificationBlock.groovy
index 7ea5a2a..8976f1c 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestClusterSpecificationBlock.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestClusterSpecificationBlock.groovy
@@ -57,7 +57,7 @@ public class TestClusterSpecificationBlock {
         providerAppState,
         providerService,
         null,
-        null, null, null);
+        null, null, null, null);
 
     Injector injector = Guice.createInjector(new AbstractModule() {
           @Override

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestContainerStatsBlock.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestContainerStatsBlock.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestContainerStatsBlock.groovy
index abd8477..297b8e7 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestContainerStatsBlock.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestContainerStatsBlock.groovy
@@ -64,7 +64,7 @@ public class TestContainerStatsBlock extends 
BaseMockAppStateTest {
         providerAppState,
         providerService,
         null,
-        null, metrics, null);
+        null, metrics, null, null);
 
     Injector injector = Guice.createInjector(new AbstractModule() {
           @Override

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestIndexBlock.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestIndexBlock.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestIndexBlock.groovy
index 324aa38..4a053fd 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestIndexBlock.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/web/view/TestIndexBlock.groovy
@@ -56,7 +56,7 @@ public class TestIndexBlock extends BaseMockAppStateTest {
         providerAppState,
         providerService,
         null,
-        null, metrics, null);
+        null, metrics, null, null);
 
     Injector injector = Guice.createInjector(new AbstractModule() {
           @Override

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
 
b/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
index 1a10ee3..38e7db1 100644
--- 
a/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
+++ 
b/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
@@ -792,8 +792,9 @@ public class TestAgentProviderService {
       }
 
       @Override
-      public void refreshClusterStatus() {
+      public ClusterDescription refreshClusterStatus() {
         // do nothing
+        return null;
       }
     };
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/agent/TestAMAgentWebServices.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/agent/TestAMAgentWebServices.java
 
b/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/agent/TestAMAgentWebServices.java
index 4aac2f1..b75d51d 100644
--- 
a/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/agent/TestAMAgentWebServices.java
+++ 
b/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/agent/TestAMAgentWebServices.java
@@ -145,7 +145,7 @@ public class TestAMAgentWebServices {
 
     slider = new WebAppApiImpl(new MockSliderClusterProtocol(), 
providerAppState,
                                new MockProviderService(), null, null, null,
-        null);
+        null, null);
 
     MapOperations compOperations = new MapOperations();
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/7632f5de/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/management/TestAMManagementWebServices.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/management/TestAMManagementWebServices.java
 
b/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/management/TestAMManagementWebServices.java
index f19f8f3..5a6ec96 100644
--- 
a/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/management/TestAMManagementWebServices.java
+++ 
b/slider-core/src/test/java/org/apache/slider/server/appmaster/web/rest/management/TestAMManagementWebServices.java
@@ -193,7 +193,7 @@ public class TestAMManagementWebServices extends JerseyTest 
{
 
         slider = new WebAppApiImpl(new MockSliderClusterProtocol(), 
providerAppState,
                                    new MockProviderService(), null, null, null,
-            null);
+            null, null);
 
         bind(SliderJacksonJaxbJsonProvider.class);
         bind(MockSliderAMWebServices.class);

Reply via email to