You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2015/02/06 21:33:13 UTC

incubator-nifi git commit: NIFI-250: - Updating the UI to gather the availability for a controller service during creation. - Removing the concept of availability from the core as the service/task can only be available on the cluster manager OR nodes. -

Repository: incubator-nifi
Updated Branches:
  refs/heads/NIFI-250 55949a428 -> 7da7c9327


NIFI-250:
- Updating the UI to gather the availability for a controller service during creation. 
- Removing the concept of availability from the core as the service/task can only be available on the cluster manager OR nodes.
- Updating web tier to support this concept.

Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/7da7c932
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/7da7c932
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/7da7c932

Branch: refs/heads/NIFI-250
Commit: 7da7c9327029a84581c5aff5f3435f2706d2c18e
Parents: 55949a4
Author: Matt Gilman <ma...@gmail.com>
Authored: Fri Feb 6 15:32:09 2015 -0500
Committer: Matt Gilman <ma...@gmail.com>
Committed: Fri Feb 6 15:32:09 2015 -0500

----------------------------------------------------------------------
 .../cluster/manager/impl/WebClusterManager.java |   5 -
 .../apache/nifi/controller/Availability.java    |  30 -----
 .../service/ControllerServiceNode.java          |   1 -
 .../service/ControllerServiceProvider.java      |  11 --
 .../apache/nifi/controller/FlowController.java  |  12 +-
 .../controller/StandardFlowSynchronizer.java    |   2 +-
 .../StandardControllerServiceProvider.java      |   5 -
 .../nifi/fingerprint/FingerprintFactory.java    |   2 -
 .../nifi/web/StandardNiFiServiceFacade.java     |   6 +-
 .../nifi/web/api/ControllerServiceResource.java |  31 +++--
 .../org/apache/nifi/web/api/dto/DtoFactory.java |   1 -
 .../nifi/web/controller/ControllerFacade.java   |   5 +-
 .../dao/impl/StandardControllerServiceDAO.java  |  15 +--
 .../org/apache/nifi/web/util/Availability.java  |  34 ++++++
 .../canvas/controller-service-configuration.jsp |   4 +-
 .../canvas/new-controller-service-dialog.jsp    |   5 +
 .../css/controller-service-configuration.css    |   6 -
 .../css/new-controller-service-dialog.css       |  20 ++++
 .../nf-controller-service-configuration.js      |  36 +-----
 .../src/main/webapp/js/nf/canvas/nf-settings.js | 113 +++++++++++++++----
 20 files changed, 186 insertions(+), 158 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
index 6a83894..4d768c6 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java
@@ -1297,11 +1297,6 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C
         }
     }
     
-    @Override
-    public ControllerServiceNode createControllerService(final String type, final boolean firstTimeAdded) {
-    	return controllerServiceProvider.createControllerService(type, firstTimeAdded);
-    }
-
     /**
      * Adds an instance of a specified controller service.
      *

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Availability.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Availability.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Availability.java
deleted file mode 100644
index 44987e2..0000000
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/Availability.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.nifi.controller;
-
-public enum Availability {
-
-	/**
-	 * Service or reporting task will run only on the NiFi Cluster Manager (NCM)
-	 */
-    NCM,
-    
-    /**
-     * Service or reporting task will run only on NiFi Nodes (or standalone instance, if not clustered)
-     */
-    NODE;
-}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
index e14f59d..d737d04 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceNode.java
@@ -16,7 +16,6 @@
  */
 package org.apache.nifi.controller.service;
 
-import org.apache.nifi.controller.Availability;
 import org.apache.nifi.controller.ConfiguredComponent;
 import org.apache.nifi.controller.ControllerService;
 

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceProvider.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceProvider.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceProvider.java
index 40e30b2..4074e89 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceProvider.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/service/ControllerServiceProvider.java
@@ -19,7 +19,6 @@ package org.apache.nifi.controller.service;
 import java.util.Set;
 
 import org.apache.nifi.annotation.lifecycle.OnAdded;
-import org.apache.nifi.controller.Availability;
 import org.apache.nifi.controller.ControllerServiceLookup;
 
 /**
@@ -28,16 +27,6 @@ import org.apache.nifi.controller.ControllerServiceLookup;
 public interface ControllerServiceProvider extends ControllerServiceLookup {
 
     /**
-     * Creates a new Controller Service of the specified type and assigns it a randomly generated ID. If <code>firstTimeadded</code>
-     * is true, calls any methods that are annotated with {@link OnAdded}
-     *
-     * @param type
-     * @param firstTimeAdded
-     * @return
-     */
-	ControllerServiceNode createControllerService(String type, boolean firstTimeAdded);
-	
-    /**
      * Creates a new Controller Service of the specified type and assigns it the given id. If <code>firstTimeadded</code>
      * is true, calls any methods that are annotated with {@link OnAdded}
      *

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
index fc0be01..71d0012 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
@@ -2465,14 +2465,14 @@ public class FlowController implements EventAccess, ControllerServiceProvider, H
     }
 
     public ReportingTaskNode createReportingTask(final String type) throws ReportingTaskInstantiationException {
-        return createReportingTask(type, Availability.NODE, true);
+        return createReportingTask(type, true);
     }
     
-    public ReportingTaskNode createReportingTask(final String type, final Availability availability, final boolean firstTimeAdded) throws ReportingTaskInstantiationException {
-    	return createReportingTask(type, UUID.randomUUID().toString(), availability, firstTimeAdded);
+    public ReportingTaskNode createReportingTask(final String type, final boolean firstTimeAdded) throws ReportingTaskInstantiationException {
+    	return createReportingTask(type, UUID.randomUUID().toString(), firstTimeAdded);
     }
     
-    public ReportingTaskNode createReportingTask(final String type, final String id, final Availability availability, final boolean firstTimeAdded) throws ReportingTaskInstantiationException {
+    public ReportingTaskNode createReportingTask(final String type, final String id, final boolean firstTimeAdded) throws ReportingTaskInstantiationException {
         if (type == null || id == null) {
             throw new NullPointerException();
         }
@@ -2635,10 +2635,6 @@ public class FlowController implements EventAccess, ControllerServiceProvider, H
     	}
     }
     
-    public ControllerServiceNode createControllerService(final String type, final boolean firstTimeAdded) {
-    	return controllerServiceProvider.createControllerService(type, firstTimeAdded);
-    }
-    
     @Override
     public ControllerServiceNode createControllerService(final String type, final String id, final boolean firstTimeAdded) {
         return controllerServiceProvider.createControllerService(type, id, firstTimeAdded);

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowSynchronizer.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowSynchronizer.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowSynchronizer.java
index 5981a5d..efeabad 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowSynchronizer.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowSynchronizer.java
@@ -391,7 +391,7 @@ public class StandardFlowSynchronizer implements FlowSynchronizer {
     private void addReportingTask(final FlowController controller, final Element reportingTaskElement, final StringEncryptor encryptor) throws ReportingTaskInstantiationException {
     	final ReportingTaskDTO dto = FlowFromDOMFactory.getReportingTask(reportingTaskElement, encryptor);
     	
-    	final ReportingTaskNode reportingTask = controller.createReportingTask(dto.getType(), dto.getId(), Availability.valueOf(dto.getAvailability().toUpperCase()), false);
+    	final ReportingTaskNode reportingTask = controller.createReportingTask(dto.getType(), dto.getId(), false);
     	reportingTask.setName(dto.getName());
     	reportingTask.setComments(dto.getComment());
     	reportingTask.setScheduldingPeriod(dto.getSchedulingPeriod());

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceProvider.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceProvider.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceProvider.java
index 3ec4755..5eed713 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceProvider.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/service/StandardControllerServiceProvider.java
@@ -98,11 +98,6 @@ public class StandardControllerServiceProvider implements ControllerServiceProvi
     }
     
     @Override
-    public ControllerServiceNode createControllerService(final String type, final boolean firstTimeAdded) {
-    	return createControllerService(type, UUID.randomUUID().toString(), firstTimeAdded);
-    }
-
-    @Override
     public ControllerServiceNode createControllerService(final String type, final String id, final boolean firstTimeAdded) {
         if (type == null || id == null) {
             throw new NullPointerException();

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/fingerprint/FingerprintFactory.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/fingerprint/FingerprintFactory.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/fingerprint/FingerprintFactory.java
index 88a2fdf..d1deff9 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/fingerprint/FingerprintFactory.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/fingerprint/FingerprintFactory.java
@@ -862,7 +862,6 @@ public final class FingerprintFactory {
     	builder.append(dto.getType());
     	builder.append(dto.getName());
     	builder.append(dto.getComments());
-    	builder.append(dto.getAvailability());
     	builder.append(dto.getAnnotationData());
     	
     	final Map<String, String> properties = dto.getProperties();
@@ -894,7 +893,6 @@ public final class FingerprintFactory {
     	builder.append(dto.getComment());
     	builder.append(dto.getSchedulingPeriod());
     	builder.append(dto.getSchedulingStrategy());
-    	builder.append(dto.getAvailability());
     	builder.append(dto.getAnnotationData());
     	
     	final Map<String, String> properties = dto.getProperties();

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index f56d787..79a6a87 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -321,7 +321,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
 
     @Override
     public void verifyUpdateControllerService(ControllerServiceDTO controllerServiceDTO) {
-        controllerServiceDAO.verifyUpdate(controllerServiceDTO);
+        // if group does not exist, then the update request is likely creating it
+        // so we don't verify since it will fail
+        if (controllerServiceDAO.hasControllerService(controllerServiceDTO.getId())) {
+            controllerServiceDAO.verifyUpdate(controllerServiceDTO);
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
index bccf218..91949c4 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
@@ -51,10 +51,10 @@ import org.apache.nifi.web.api.dto.RevisionDTO;
 import org.apache.nifi.web.api.request.ClientIdParameter;
 import org.apache.nifi.web.api.request.LongParameter;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.controller.Availability;
 import org.apache.nifi.web.api.dto.ControllerServiceDTO;
 import org.apache.nifi.web.api.entity.ControllerServiceEntity;
 import org.apache.nifi.web.api.entity.ControllerServicesEntity;
+import org.apache.nifi.web.util.Availability;
 import org.codehaus.enunciate.jaxrs.TypeHint;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -77,19 +77,20 @@ public class ControllerServiceResource extends ApplicationResource {
      * @param controllerServices
      * @return 
      */
-    private Set<ControllerServiceDTO> populateRemainingControllerServicesContent(Set<ControllerServiceDTO> controllerServices) {
+    private Set<ControllerServiceDTO> populateRemainingControllerServicesContent(final String availability, final Set<ControllerServiceDTO> controllerServices) {
         for (ControllerServiceDTO controllerService : controllerServices) {
-            populateRemainingControllerServiceContent(controllerService);
+            populateRemainingControllerServiceContent(availability, controllerService);
         }
         return controllerServices;
     }
-
+    
     /**
      * Populates the uri for the specified controller service.
      */
-    private ControllerServiceDTO populateRemainingControllerServiceContent(ControllerServiceDTO controllerService) {
+    private ControllerServiceDTO populateRemainingControllerServiceContent(final String availability, final ControllerServiceDTO controllerService) {
         // populate the controller service href
-        controllerService.setUri(generateResourceUri("controller", "controller-services", controllerService.getId()));
+        controllerService.setUri(generateResourceUri("controller", "controller-services", availability, controllerService.getId()));
+        controllerService.setAvailability(availability);
         return controllerService;
     }
 
@@ -140,8 +141,8 @@ public class ControllerServiceResource extends ApplicationResource {
         }
 
         // get all the controller services
-        final Set<ControllerServiceDTO> controllerServices = populateRemainingControllerServicesContent(serviceFacade.getControllerServices());
-
+        final Set<ControllerServiceDTO> controllerServices = populateRemainingControllerServicesContent(availability, serviceFacade.getControllerServices());
+        
         // create the revision
         final RevisionDTO revision = new RevisionDTO();
         revision.setClientId(clientId.getClientId());
@@ -240,10 +241,6 @@ public class ControllerServiceResource extends ApplicationResource {
 
         // if cluster manager, convert POST to PUT (to maintain same ID across nodes) and replicate
         if (properties.isClusterManager() && Availability.NODE.equals(avail)) {
-
-            // apply action to the cluster manager first
-            serviceFacade.createControllerService(new Revision(revision.getVersion(), revision.getClientId()), controllerServiceEntity.getControllerService());
-            
             // create ID for resource
             final String id = UUID.randomUUID().toString();
 
@@ -276,7 +273,6 @@ public class ControllerServiceResource extends ApplicationResource {
         final ConfigurationSnapshot<ControllerServiceDTO> controllerResponse = serviceFacade.createControllerService(
                 new Revision(revision.getVersion(), revision.getClientId()), controllerServiceEntity.getControllerService());
         final ControllerServiceDTO controllerService = controllerResponse.getConfiguration();
-        populateRemainingControllerServiceContent(controllerService);
 
         // get the updated revision
         final RevisionDTO updatedRevision = new RevisionDTO();
@@ -286,7 +282,7 @@ public class ControllerServiceResource extends ApplicationResource {
         // build the response entity
         final ControllerServiceEntity entity = new ControllerServiceEntity();
         entity.setRevision(updatedRevision);
-        entity.setControllerService(controllerService);
+        entity.setControllerService(populateRemainingControllerServiceContent(availability, controllerService));
 
         // build the response
         return clusterContext(generateCreatedResponse(URI.create(controllerService.getUri()), entity)).build();
@@ -328,7 +324,7 @@ public class ControllerServiceResource extends ApplicationResource {
         // create the response entity
         final ControllerServiceEntity entity = new ControllerServiceEntity();
         entity.setRevision(revision);
-        entity.setControllerService(populateRemainingControllerServiceContent(controllerService));
+        entity.setControllerService(populateRemainingControllerServiceContent(availability, controllerService));
 
         return clusterContext(generateOkResponse(entity)).build();
     }
@@ -482,7 +478,7 @@ public class ControllerServiceResource extends ApplicationResource {
             // replicate the request
             return clusterManager.applyRequest(HttpMethod.PUT, getAbsolutePath(), updateClientId(controllerServiceEntity), getHeaders(headersToOverride)).getResponse();
         }
-
+        
         // handle expects request (usually from the cluster manager)
         final String expects = httpServletRequest.getHeader(WebClusterManager.NCM_EXPECTS_HTTP_HEADER);
         if (expects != null) {
@@ -497,7 +493,6 @@ public class ControllerServiceResource extends ApplicationResource {
 
         // get the results
         final ControllerServiceDTO responseControllerServiceDTO = controllerResponse.getConfiguration();
-        populateRemainingControllerServiceContent(responseControllerServiceDTO);
 
         // get the updated revision
         final RevisionDTO updatedRevision = new RevisionDTO();
@@ -507,7 +502,7 @@ public class ControllerServiceResource extends ApplicationResource {
         // build the response entity
         final ControllerServiceEntity entity = new ControllerServiceEntity();
         entity.setRevision(updatedRevision);
-        entity.setControllerService(responseControllerServiceDTO);
+        entity.setControllerService(populateRemainingControllerServiceContent(availability, responseControllerServiceDTO));
 
         return clusterContext(generateOkResponse(entity)).build();
     }

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
index ab7cd4c..4fe235f 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
@@ -848,7 +848,6 @@ public final class DtoFactory {
         dto.setId(controllerServiceNode.getIdentifier());
         dto.setName(controllerServiceNode.getName());
         dto.setType(controllerServiceNode.getControllerServiceImplementation().getClass().getName());
-        dto.setAvailability(controllerServiceNode.getAvailability().name());
         dto.setEnabled(!controllerServiceNode.isDisabled());
         dto.setComments(controllerServiceNode.getComments());
         

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index 83bdd2f..2f6ce2f 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -404,15 +404,12 @@ public class ControllerFacade implements ControllerServiceProvider {
         return flowController.getControllerService(serviceIdentifier);
     }
 
-    public ControllerServiceNode createControllerService(final String type, final boolean firstTimeAdded) {
-    	return flowController.createControllerService(type, firstTimeAdded);
-    }
-    
     @Override
     public ControllerServiceNode createControllerService(final String type, final String id, final boolean firstTimeAdded) {
         return flowController.createControllerService(type, id, firstTimeAdded);
     }
     
+    @Override
     public void removeControllerService(ControllerServiceNode serviceNode) {
         flowController.removeControllerService(serviceNode);
     }

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java
index 551dcd3..b48abd0 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java
@@ -20,8 +20,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.controller.Availability;
 
 import org.apache.nifi.controller.exception.ValidationException;
 import org.apache.nifi.controller.service.ControllerServiceNode;
@@ -61,8 +59,7 @@ public class StandardControllerServiceDAO extends ComponentDAO implements Contro
     @Override
     public ControllerServiceNode createControllerService(final ControllerServiceDTO controllerServiceDTO) {
         // create the controller service
-    	final Availability availability = Availability.valueOf(controllerServiceDTO.getAvailability().toUpperCase());
-        final ControllerServiceNode controllerService = serviceProvider.createControllerService(controllerServiceDTO.getType(), availability, true);
+        final ControllerServiceNode controllerService = serviceProvider.createControllerService(controllerServiceDTO.getType(), controllerServiceDTO.getId(), true);
         
         // ensure we can perform the update 
         verifyUpdate(controllerService, controllerServiceDTO);
@@ -147,15 +144,6 @@ public class StandardControllerServiceDAO extends ComponentDAO implements Contro
      */
     private List<String> validateProposedConfiguration(final ControllerServiceNode controllerService, final ControllerServiceDTO controllerServiceDTO) {
         final List<String> validationErrors = new ArrayList<>();
-        
-        if (isNotNull(controllerServiceDTO.getAvailability())) {
-            try {
-                Availability.valueOf(controllerServiceDTO.getAvailability());
-            } catch (IllegalArgumentException iae) {
-                validationErrors.add(String.format("Availability: Value must be one of [%s]", StringUtils.join(Availability.values(), ", ")));
-            }
-        }
-        
         return validationErrors;
     }
     
@@ -188,7 +176,6 @@ public class StandardControllerServiceDAO extends ComponentDAO implements Contro
         
         boolean modificationRequest = false;
         if (isAnyNotNull(controllerServiceDTO.getName(),
-                controllerServiceDTO.getAvailability(),
                 controllerServiceDTO.getAnnotationData(),
                 controllerServiceDTO.getComments(),
                 controllerServiceDTO.getProperties())) {

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/Availability.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/Availability.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/Availability.java
new file mode 100644
index 0000000..29ba4f8
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/Availability.java
@@ -0,0 +1,34 @@
+/*
+ * 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.nifi.web.util;
+
+/**
+ * Where a given controller service or reporting task should run.
+ */
+public enum Availability {
+
+    /**
+     * Service or reporting task will run only on the NiFi Cluster Manager (NCM)
+     */
+    NCM,
+    
+    /**
+     * Service or reporting task will run only on NiFi Nodes (or standalone
+     * instance, if not clustered)
+     */
+    NODE;
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/controller-service-configuration.jsp
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/controller-service-configuration.jsp b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/controller-service-configuration.jsp
index 1cadf1d..f769b3e 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/controller-service-configuration.jsp
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/controller-service-configuration.jsp
@@ -47,10 +47,10 @@
                         <div class="availability-setting">
                             <div class="setting-name">
                                 Availability
-                                <img class="setting-icon icon-info" src="images/iconInfo.png" alt="Info" title="Where this controller service will be available."/>
+                                <img class="setting-icon icon-info" src="images/iconInfo.png" alt="Info" title="Where this controller service is available."/>
                             </div>
                             <div class="setting-field">
-                                <div id="availability-combo"></div>
+                                <div id="availability"></div>
                             </div>
                         </div>
                         <div class="clear"></div>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-controller-service-dialog.jsp
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-controller-service-dialog.jsp b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-controller-service-dialog.jsp
index b0091a2..eb54ace 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-controller-service-dialog.jsp
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/new-controller-service-dialog.jsp
@@ -44,5 +44,10 @@
             </div>
         </div>
         <div class="clear"></div>
+        <div id="controller-service-availability-container" class="hidden">
+            <div class="setting-name availability-label">Available on</div>
+            <div id="controller-service-availability-combo"></div>
+            <div class="clear"></div>
+        </div>
     </div>
 </div>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/controller-service-configuration.css
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/controller-service-configuration.css b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/controller-service-configuration.css
index 357aa6b..30a7747 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/controller-service-configuration.css
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/controller-service-configuration.css
@@ -105,12 +105,6 @@ div.availability-setting {
     width: 140px;
 }
 
-#availability-combo {
-    width: 130px;
-    height: 18px;
-    line-height: 18px;
-}
-
 /*
     Service references
 */

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-controller-service-dialog.css
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-controller-service-dialog.css b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-controller-service-dialog.css
index c28a253..16ba47a 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-controller-service-dialog.css
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/new-controller-service-dialog.css
@@ -59,6 +59,26 @@
     height: 60px;
 }
 
+#controller-service-availability-container {
+    position: relative;
+    left: 190px;
+    top: 9px;
+}
+
+div.availability-label {
+    float: left;
+    height: 24px;
+    line-height: 24px;
+}
+
+#controller-service-availability-combo {
+    float: left;
+    margin-left: 6px;
+    width: 125px;
+    height: 18px;
+    line-height: 18px;
+}
+
 #controller-service-types-table {
     width: 586px;
     height: 249px;

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service-configuration.js
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service-configuration.js b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service-configuration.js
index f122c55..1064090 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service-configuration.js
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service-configuration.js
@@ -66,12 +66,6 @@ nf.ControllerServiceConfiguration = (function () {
             return true;
         }
         
-        if (nf.Canvas.isClustered()) {
-            if ($('#availability-combo').combo('getSelectedOption').value !== (details['availability'] + '')) {
-                return true;
-            }
-        }
-
         // defer to the properties
         return $('#controller-service-properties').propertytable('isSaveRequired');
     };
@@ -100,11 +94,6 @@ nf.ControllerServiceConfiguration = (function () {
             controllerServiceDto['enabled'] = true;
         }
 
-        // add the availability if appropriate
-        if (nf.Canvas.isClustered()) {
-            controllerServiceDto['availability'] = $('#availability-combo').combo('getSelectedOption').value;
-        }
-
         // create the controller service entity
         var controllerServiceEntity = {};
         controllerServiceEntity['revision'] = nf.Client.getRevision();
@@ -303,21 +292,6 @@ nf.ControllerServiceConfiguration = (function () {
             
             // we clustered we need to show the controls for editing the availability
             if (nf.Canvas.isClustered()) {
-                $('#availability-combo').combo({
-                    options: [{
-                        text: 'Cluster Manager',
-                        value: 'CLUSTER_MANAGER_ONLY',
-                        description: 'This controller service will be available on the cluster manager only.'
-                    }, {
-                        text: 'Node',
-                        value: 'NODE_ONLY',
-                        description: 'This controller service will be available on the nodes only.'
-                    }, {
-                        text: 'Both',
-                        value: 'BOTH',
-                        description: 'This controller service will be available on the cluster manager and the nodes.'
-                    }]
-                });
                 $('#availability-setting-container').show();
             }
 
@@ -358,7 +332,7 @@ nf.ControllerServiceConfiguration = (function () {
             // reload the service in case the property descriptors have changed
             var reloadService = $.ajax({
                 type: 'GET',
-                url: '../nifi-api/controller/controller-services/' + encodeURIComponent(controllerService.id),
+                url: controllerService.uri,
                 dataType: 'json'
             });
             
@@ -395,9 +369,11 @@ nf.ControllerServiceConfiguration = (function () {
 
                 // select the availability when appropriate
                 if (nf.Canvas.isClustered()) {
-                    $('#availability-combo').combo('setSelectedOption', {
-                        value: controllerService['availability']
-                    });
+                    if (controllerService['availability'] === 'node') {
+                        $('#availability').text('Node');
+                    } else {
+                        $('#availability').text('Cluster Manager');
+                    }
                 }
 
                 // load the controller references list

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/7da7c932/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
index 21dc296..f3c884f 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js
@@ -17,6 +17,8 @@
 nf.Settings = (function () {
 
     var config = {
+        node: 'node',
+        ncm: 'ncm',
         filterText: 'Filter',
         styles: {
             filterList: 'filter-list'
@@ -25,7 +27,7 @@ nf.Settings = (function () {
             controllerConfig: '../nifi-api/controller/config',
             controllerArchive: '../nifi-api/controller/archive',
             controllerServiceTypes: '../nifi-api/controller/controller-service-types',
-            controllerServices: '../nifi-api/controller/controller-services/node',
+            controllerServices: '../nifi-api/controller/controller-services',
             reportingTaskTypes: '../nifi-api/controller/reporting-task-types',
             reportingTasks: '../nifi-api/controller/reporting-tasks'
         }
@@ -187,6 +189,9 @@ nf.Settings = (function () {
     var clearSelectedControllerService = function () {
         $('#controller-service-type-description').text('');
         $('#controller-service-type-name').text('');
+        $('#controller-service-availability-combo').combo('setSelectedOption', {
+            value: config.node
+        });
         $('#selected-controller-service-name').text('');
         $('#selected-controller-service-type').text('');
         $('#controller-service-description-container').hide();
@@ -367,10 +372,18 @@ nf.Settings = (function () {
     var addControllerService = function (controllerServiceType) {
         var revision = nf.Client.getRevision();
 
+        // get the desired availability
+        var availability;
+        if (nf.Canvas.isClustered()) {
+            availability = $('#controller-service-availability-combo').combo('getSelectedOption');
+        } else {
+            availability = config.node;
+        }
+
         // add the new controller service
         var addService = $.ajax({
             type: 'POST',
-            url: config.urls.controllerServices,
+            url: config.urls.controllerServices + '/' + encodeURIComponent(availability.value),
             data: {
                 version: revision.version,
                 clientId: revision.clientId,
@@ -410,6 +423,22 @@ nf.Settings = (function () {
             }
         });
         
+        // specify the controller service availability
+        if (nf.Canvas.isClustered()) {
+            $('#controller-service-availability-combo').combo({
+                options: [{
+                        text: 'Node',
+                        value: config.node,
+                        description: 'This controller service will be available on the nodes only.'
+                    }, {
+                        text: 'Cluster Manager',
+                        value: config.ncm,
+                        description: 'This controller service will be available on the cluster manager only.'
+                    }]
+            });
+            $('#controller-service-availability-container').show();
+        }
+        
         // define the function for filtering the list
         $('#controller-service-type-filter').keyup(function () {
             applyControllerServiceTypeFilter();
@@ -708,7 +737,7 @@ nf.Settings = (function () {
         
         // more details formatter
         var moreControllerServiceDetails = function (row, cell, value, columnDef, dataContext) {
-            var markup = '<img src="images/iconDetails.png" title="View Details" class="pointer view-controller-service" style="margin-top: 5px; float: left;" />&nbsp;';
+            var markup = '<img src="images/iconDetails.png" title="View Details" class="pointer view-controller-service" style="margin-top: 5px; float: left;" />&nbsp;&nbsp;';
             if (!nf.Common.isEmpty(dataContext.validationErrors)) {
                 markup += '<img src="images/iconAlert.png" class="has-errors" style="margin-top: 4px; float: left;" /><span class="hidden row-id">' + nf.Common.escapeHtml(dataContext.id) + '</span>';
             }
@@ -722,7 +751,7 @@ nf.Settings = (function () {
         
         // service state formatter
         var enabledFormatter = function (row, cell, value, columnDef, dataContext) {
-            if (dataContext.enabled === true) {
+            if (value === true) {
                 return 'Enabled';
             } else {
                 return 'Disabled';
@@ -737,6 +766,19 @@ nf.Settings = (function () {
             {id: 'enabled', field: 'enabled', name: 'State', formatter: enabledFormatter, sortable: true, resizeable: true}
         ];
         
+        // only show availability when clustered
+        if (nf.Canvas.isClustered()) {
+            var availabilityFormatter = function (row, cell, value, columnDef, dataContext) {
+                if (value === config.node) {
+                    return 'Node';
+                } else {
+                    return 'Cluster Manager';
+                }
+            };
+            
+            controllerServicesColumns.push({id: 'availability', field: 'availability', name: 'Availability', formatter: availabilityFormatter, sortable: true, resizeable: true});
+        }
+        
         // only DFM can edit controller services
         if (nf.Common.isDFM()) {
             var controllerServiceActionFormatter = function (row, cell, value, columnDef, dataContext) {
@@ -864,24 +906,57 @@ nf.Settings = (function () {
      * Loads the controller services.
      */
     var loadControllerServices = function () {
-        return $.ajax({
+        var services = [];
+        
+        // get the controller services that are running on the nodes
+        var nodeControllerServices = $.ajax({
             type: 'GET',
-            url: config.urls.controllerServices,
+            url: config.urls.controllerServices + '/' + encodeURIComponent(config.node),
             dataType: 'json'
-        }).done(function (response) {
-            var controllerServices = response.controllerServices;
-            if (nf.Common.isDefinedAndNotNull(controllerServices)) {
-                var controllerServicesElement = $('#controller-services-table');
-                nf.Common.cleanUpTooltips(controllerServicesElement, 'img.has-errors');
-                
-                var controllerServicesGrid = controllerServicesElement.data('gridInstance');
-                var controllerServicesData = controllerServicesGrid.getData();
-
-                // update the processors
-                controllerServicesData.setItems(controllerServices);
-                controllerServicesData.reSort();
-                controllerServicesGrid.invalidate();
+        }).done(function(response) {
+            var nodeServices = response.controllerServices;
+            if (nf.Common.isDefinedAndNotNull(nodeServices)) {
+                $.each(nodeServices, function(_, nodeService) {
+                    services.push(nodeService);
+                });
+            }
+        });
+        
+        // get the controller services that are running on the ncm
+        var ncmControllerServices = $.Deferred(function(deferred) {
+            if (nf.Canvas.isClustered()) {
+                $.ajax({
+                    type: 'GET',
+                    url: config.urls.controllerServices + '/' + encodeURIComponent(config.ncm),
+                    dataType: 'json'
+                }).done(function(response) {
+                    var ncmServices = response.controllerServices;
+                    if (nf.Common.isDefinedAndNotNull(ncmServices)) {
+                        $.each(ncmServices, function(_, ncmService) {
+                            services.push(ncmService);
+                        });
+                    }
+                    deferred.resolve();
+                }).fail(function() {
+                    deferred.reject();
+                });
+            } else {
+                deferred.resolve();
             }
+        }).promise();
+        
+        // add all controller services
+        return $.when(nodeControllerServices, ncmControllerServices).done(function() {
+            var controllerServicesElement = $('#controller-services-table');
+            nf.Common.cleanUpTooltips(controllerServicesElement, 'img.has-errors');
+
+            var controllerServicesGrid = controllerServicesElement.data('gridInstance');
+            var controllerServicesData = controllerServicesGrid.getData();
+
+            // update the processors
+            controllerServicesData.setItems(services);
+            controllerServicesData.reSort();
+            controllerServicesGrid.invalidate();
         });
     };