Prechádzať zdrojové kódy

AMBARI-1411. Missing unit test coverage for resource providers

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1445689 13f79535-47bb-0310-9956-ffa450edef68
Tom Beerbower 12 rokov pred
rodič
commit
8874b3728d

+ 2 - 0
CHANGES.txt

@@ -269,6 +269,8 @@ Trunk (unreleased changes):
  AMBARI-1260. Remove hard coded JMX port mappings. (Siddharth Wagle via
  mahadev)
 
+ AMBARI-1411. Missing unit test coverage for resource providers. (tbeerbower)
+
  BUG FIXES
 
  AMBARI-1376. Wrong calculation of duration filter on apps page. (jaimin via

+ 390 - 447
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AbstractResourceProviderTest.java

@@ -18,432 +18,36 @@
 
 package org.apache.ambari.server.controller.internal;
 
-import org.apache.ambari.server.controller.*;
-import org.apache.ambari.server.controller.utilities.PredicateBuilder;
-import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.controller.RequestStatusResponse;
-import org.apache.ambari.server.controller.spi.Predicate;
-import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.ActionRequest;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ClusterRequest;
+import org.apache.ambari.server.controller.ConfigurationRequest;
+import org.apache.ambari.server.controller.HostRequest;
+import org.apache.ambari.server.controller.RequestStatusRequest;
+import org.apache.ambari.server.controller.ServiceComponentHostRequest;
+import org.apache.ambari.server.controller.ServiceComponentRequest;
+import org.apache.ambari.server.controller.ServiceRequest;
+import org.apache.ambari.server.controller.TaskStatusRequest;
+import org.apache.ambari.server.controller.UserRequest;
 import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.easymock.EasyMock;
 import org.easymock.IArgumentMatcher;
 import org.junit.Assert;
 import org.junit.Test;
 
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 
+import static org.easymock.EasyMock.createMock;
+
 /**
  * Resource provider tests.
  */
 public class AbstractResourceProviderTest {
 
-  @Test
-  public void testCreateClusterResources() throws Exception{
-    Resource.Type type = Resource.Type.Cluster;
-
-    AmbariManagementController managementController = createMock(AmbariManagementController.class);
-    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
-
-    managementController.createCluster(Matchers.clusterRequest(null, "Cluster100", "HDP-0.1", null));
-    managementController.createCluster(Matchers.clusterRequest(99L, null, "HDP-0.1", null));
-
-    // replay
-    replay(managementController, response);
-
-    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
-        type,
-        PropertyHelper.getPropertyIds(type),
-        PropertyHelper.getKeyPropertyIds(type),
-        managementController);
-
-    TestObserver observer = new TestObserver();
-
-    ((ObservableResourceProvider)provider).addObserver(observer);
-
-    // add the property map to a set for the request.  add more maps for multiple creates
-    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
-
-    // Cluster 1: create a map of properties for the request
-    Map<String, Object> properties = new LinkedHashMap<String, Object>();
-
-    // add the cluster name to the properties map
-    properties.put(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID, "Cluster100");
-
-    // add the version to the properties map
-    properties.put(ClusterResourceProvider.CLUSTER_VERSION_PROPERTY_ID, "HDP-0.1");
-
-    propertySet.add(properties);
-
-    // Cluster 2: create a map of properties for the request
-    properties = new LinkedHashMap<String, Object>();
-
-    // add the cluster id to the properties map
-    properties.put(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID, 99L);
-
-    // add the version to the properties map
-    properties.put(ClusterResourceProvider.CLUSTER_VERSION_PROPERTY_ID, "HDP-0.1");
-
-    propertySet.add(properties);
-
-    // create the request
-    Request request = PropertyHelper.getCreateRequest(propertySet);
-
-    provider.createResources(request);
-
-    ResourceProviderEvent lastEvent = observer.getLastEvent();
-    Assert.assertNotNull(lastEvent);
-    Assert.assertEquals(Resource.Type.Cluster, lastEvent.getResourceType());
-    Assert.assertEquals(ResourceProviderEvent.Type.Create, lastEvent.getType());
-    Assert.assertEquals(request, lastEvent.getRequest());
-    Assert.assertNull(lastEvent.getPredicate());
-
-    // verify
-    verify(managementController, response);
-  }
-
-  @Test
-  public void testGetClusterResources() throws Exception{
-    Resource.Type type = Resource.Type.Cluster;
-
-    AmbariManagementController managementController = createMock(AmbariManagementController.class);
-
-    Set<ClusterResponse> allResponse = new HashSet<ClusterResponse>();
-    allResponse.add(new ClusterResponse(100L, "Cluster100", null, null));
-    allResponse.add(new ClusterResponse(101L, "Cluster101", null, null));
-    allResponse.add(new ClusterResponse(102L, "Cluster102", null, null));
-    allResponse.add(new ClusterResponse(103L, "Cluster103", null, null));
-    allResponse.add(new ClusterResponse(104L, "Cluster104", null, null));
-
-    Set<ClusterResponse> nameResponse = new HashSet<ClusterResponse>();
-    nameResponse.add(new ClusterResponse(102L, "Cluster102", null, null));
-
-    Set<ClusterResponse> idResponse = new HashSet<ClusterResponse>();
-    idResponse.add(new ClusterResponse(103L, "Cluster103", null, null));
-
-    // set expectations
-    expect(managementController.getClusters(EasyMock.<Set<ClusterRequest>>anyObject())).andReturn(allResponse).once();
-    expect(managementController.getClusters(EasyMock.<Set<ClusterRequest>>anyObject())).andReturn(nameResponse).once();
-    expect(managementController.getClusters(EasyMock.<Set<ClusterRequest>>anyObject())).andReturn(idResponse).once();
-
-    // replay
-    replay(managementController);
-
-    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
-        type,
-        PropertyHelper.getPropertyIds(type),
-        PropertyHelper.getKeyPropertyIds(type),
-        managementController);
-
-    Set<String> propertyIds = new HashSet<String>();
-
-    propertyIds.add(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID);
-    propertyIds.add(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID);
-
-    // create the request
-    Request request = PropertyHelper.getReadRequest(propertyIds);
-
-    // get all ... no predicate
-    Set<Resource> resources = provider.getResources(request, null);
-
-    Assert.assertEquals(5, resources.size());
-    for (Resource resource : resources) {
-      Long id = (Long) resource.getPropertyValue(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID);
-      String name = (String) resource.getPropertyValue(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID);
-      Assert.assertEquals(name, "Cluster" + id);
-    }
-
-    // get cluster named Cluster102
-    Predicate  predicate = new PredicateBuilder().property(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID).equals("Cluster102").toPredicate();
-    resources = provider.getResources(request, predicate);
-
-    Assert.assertEquals(1, resources.size());
-    Assert.assertEquals(102L, resources.iterator().next().getPropertyValue(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID));
-    Assert.assertEquals("Cluster102", resources.iterator().next().getPropertyValue(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID));
-
-    // get cluster with id == 103
-    predicate = new PredicateBuilder().property(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID).equals(103L).toPredicate();
-    resources = provider.getResources(request, predicate);
-
-    Assert.assertEquals(1, resources.size());
-    Assert.assertEquals(103L, resources.iterator().next().getPropertyValue(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID));
-    Assert.assertEquals("Cluster103", resources.iterator().next().getPropertyValue(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID));
-
-    // verify
-    verify(managementController);
-  }
-
-  @Test
-  public void testUpdateClusterResources() throws Exception{
-    Resource.Type type = Resource.Type.Cluster;
-
-    AmbariManagementController managementController = createMock(AmbariManagementController.class);
-    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
-
-    Set<ClusterResponse> nameResponse = new HashSet<ClusterResponse>();
-    nameResponse.add(new ClusterResponse(102L, "Cluster102", null, null));
-
-    // set expectations
-    expect(managementController.getClusters(EasyMock.<Set<ClusterRequest>>anyObject())).andReturn(nameResponse).once();
-    expect(managementController.updateCluster(Matchers.clusterRequest(102L, "Cluster102", "HDP-0.1", null))).andReturn(response).once();
-    expect(managementController.updateCluster(Matchers.clusterRequest(103L, null, "HDP-0.1", null))).andReturn(response).once();
-
-    // replay
-    replay(managementController, response);
-
-    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
-        type,
-        PropertyHelper.getPropertyIds(type),
-        PropertyHelper.getKeyPropertyIds(type),
-        managementController);
-
-    TestObserver observer = new TestObserver();
-
-    ((ObservableResourceProvider)provider).addObserver(observer);
-
-    Map<String, Object> properties = new LinkedHashMap<String, Object>();
-
-    properties.put(ClusterResourceProvider.CLUSTER_VERSION_PROPERTY_ID, "HDP-0.1");
-
-    // create the request
-    Request request = PropertyHelper.getUpdateRequest(properties);
-
-    // update the cluster named Cluster102
-    Predicate  predicate = new PredicateBuilder().property(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID).equals("Cluster102").toPredicate();
-    provider.updateResources(request, predicate);
-
-    // update the cluster where id == 103
-    predicate = new PredicateBuilder().property(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID).equals(103L).toPredicate();
-    provider.updateResources(request, predicate);
-
-    ResourceProviderEvent lastEvent = observer.getLastEvent();
-    Assert.assertNotNull(lastEvent);
-    Assert.assertEquals(Resource.Type.Cluster, lastEvent.getResourceType());
-    Assert.assertEquals(ResourceProviderEvent.Type.Update, lastEvent.getType());
-    Assert.assertEquals(request, lastEvent.getRequest());
-    Assert.assertEquals(predicate, lastEvent.getPredicate());
-
-    // verify
-    verify(managementController, response);
-  }
-
-  @Test
-  public void testDeleteClusterResources() throws Exception{
-    Resource.Type type = Resource.Type.Cluster;
-
-    AmbariManagementController managementController = createMock(AmbariManagementController.class);
-    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
-
-    // set expectations
-    managementController.deleteCluster(Matchers.clusterRequest(null, "Cluster102", null, null));
-    managementController.deleteCluster(Matchers.clusterRequest(103L, null, null, null));
-
-    // replay
-    replay(managementController, response);
-
-    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
-        type,
-        PropertyHelper.getPropertyIds(type),
-        PropertyHelper.getKeyPropertyIds(type),
-        managementController);
-
-    TestObserver observer = new TestObserver();
-
-    ((ObservableResourceProvider)provider).addObserver(observer);
-
-    // delete the cluster named Cluster102
-    Predicate  predicate = new PredicateBuilder().property(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID).equals("Cluster102").toPredicate();
-    provider.deleteResources(predicate);
-
-    // delete the cluster where id == 103
-    predicate = new PredicateBuilder().property(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID).equals(103L).toPredicate();
-    provider.deleteResources(predicate);
-
-    ResourceProviderEvent lastEvent = observer.getLastEvent();
-    Assert.assertNotNull(lastEvent);
-    Assert.assertEquals(Resource.Type.Cluster, lastEvent.getResourceType());
-    Assert.assertEquals(ResourceProviderEvent.Type.Delete, lastEvent.getType());
-    Assert.assertEquals(predicate, lastEvent.getPredicate());
-    Assert.assertNull(lastEvent.getRequest());
-
-    // verify
-    verify(managementController, response);
-  }
-
-  @Test
-  public void testCreateServiceResources() throws Exception{
-    Resource.Type type = Resource.Type.Service;
-
-    AmbariManagementController managementController = createMock(AmbariManagementController.class);
-    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
-
-    managementController.createServices(Matchers.serviceRequestSet("Cluster100", "Service100", null, "DEPLOYED"));
-
-    // replay
-    replay(managementController, response);
-
-    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
-        type,
-        PropertyHelper.getPropertyIds(type),
-        PropertyHelper.getKeyPropertyIds(type),
-        managementController);
-
-    // add the property map to a set for the request.  add more maps for multiple creates
-    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
-
-    // Service 1: create a map of properties for the request
-    Map<String, Object> properties = new LinkedHashMap<String, Object>();
-
-    // add properties to the request map
-    properties.put(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID, "Cluster100");
-    properties.put(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID, "Service100");
-    properties.put(ServiceResourceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID, "DEPLOYED");
-
-    propertySet.add(properties);
-
-    // create the request
-    Request request = PropertyHelper.getCreateRequest(propertySet);
-
-    provider.createResources(request);
-
-    // verify
-    verify(managementController, response);
-  }
-
-  @Test
-  public void testGetServiceResources() throws Exception{
-    Resource.Type type = Resource.Type.Service;
-
-    AmbariManagementController managementController = createMock(AmbariManagementController.class);
-
-    Set<ServiceResponse> allResponse = new HashSet<ServiceResponse>();
-    allResponse.add(new ServiceResponse(100L, "Cluster100", "Service100", null, "HDP-0.1", "DEPLOYED"));
-    allResponse.add(new ServiceResponse(100L, "Cluster100", "Service101", null, "HDP-0.1", "DEPLOYED"));
-    allResponse.add(new ServiceResponse(100L, "Cluster100", "Service102", null, "HDP-0.1", "DEPLOYED"));
-    allResponse.add(new ServiceResponse(100L, "Cluster100", "Service103", null, "HDP-0.1", "DEPLOYED"));
-    allResponse.add(new ServiceResponse(100L, "Cluster100", "Service104", null, "HDP-0.1", "DEPLOYED"));
-
-    Set<ServiceResponse> nameResponse = new HashSet<ServiceResponse>();
-    nameResponse.add(new ServiceResponse(100L, "Cluster100", "Service102", null, "HDP-0.1", "DEPLOYED"));
-
-    Set<ServiceResponse> stateResponse = new HashSet<ServiceResponse>();
-    stateResponse.add(new ServiceResponse(100L, "Cluster100", "Service100", null, "HDP-0.1", "DEPLOYED"));
-    stateResponse.add(new ServiceResponse(100L, "Cluster100", "Service102", null, "HDP-0.1", "DEPLOYED"));
-    stateResponse.add(new ServiceResponse(100L, "Cluster100", "Service104", null, "HDP-0.1", "DEPLOYED"));
-
-    // set expectations
-    expect(managementController.getServices(EasyMock.<Set<ServiceRequest>>anyObject())).andReturn(allResponse).once();
-    expect(managementController.getServices(EasyMock.<Set<ServiceRequest>>anyObject())).andReturn(nameResponse).once();
-    expect(managementController.getServices(EasyMock.<Set<ServiceRequest>>anyObject())).andReturn(stateResponse).once();
-
-    // replay
-    replay(managementController);
-
-    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
-        type,
-        PropertyHelper.getPropertyIds(type),
-        PropertyHelper.getKeyPropertyIds(type),
-        managementController);
-
-    Set<String> propertyIds = new HashSet<String>();
-
-    propertyIds.add(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID);
-    propertyIds.add(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID);
-
-    // create the request
-    Request request = PropertyHelper.getReadRequest(propertyIds);
-    // get all ... no predicate
-    Set<Resource> resources = provider.getResources(request, null);
-
-    Assert.assertEquals(5, resources.size());
-    Set<String> names = new HashSet<String>();
-    for (Resource resource : resources) {
-      String clusterName = (String) resource.getPropertyValue(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID);
-      Assert.assertEquals("Cluster100", clusterName);
-      names.add((String) resource.getPropertyValue(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID));
-    }
-    // Make sure that all of the response objects got moved into resources
-    for (ServiceResponse serviceResponse : allResponse ) {
-      Assert.assertTrue(names.contains(serviceResponse.getServiceName()));
-    }
-
-    // get service named Service102
-    Predicate  predicate = new PredicateBuilder().property(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID).equals("Service102").toPredicate();
-    request = PropertyHelper.getReadRequest("ServiceInfo");
-    resources = provider.getResources(request, predicate);
-
-    Assert.assertEquals(1, resources.size());
-    Assert.assertEquals("Service102", resources.iterator().next().getPropertyValue(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID));
-
-    // get services where state == "DEPLOYED"
-    predicate = new PredicateBuilder().property(ServiceResourceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID).equals("DEPLOYED").toPredicate();
-    request = PropertyHelper.getReadRequest(propertyIds);
-    resources = provider.getResources(request, predicate);
-
-    Assert.assertEquals(3, resources.size());
-    names = new HashSet<String>();
-    for (Resource resource : resources) {
-      String clusterName = (String) resource.getPropertyValue(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID);
-      Assert.assertEquals("Cluster100", clusterName);
-      names.add((String) resource.getPropertyValue(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID));
-    }
-    // Make sure that all of the response objects got moved into resources
-    for (ServiceResponse serviceResponse : stateResponse ) {
-      Assert.assertTrue(names.contains(serviceResponse.getServiceName()));
-    }
-
-    // verify
-    verify(managementController);
-  }
-
-  @Test
-  public void testUpdateServiceResources() throws Exception{
-    Resource.Type type = Resource.Type.Service;
-
-    AmbariManagementController managementController = createMock(AmbariManagementController.class);
-    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
-
-    // set expectations
-    expect(managementController.updateServices(EasyMock.<Set<ServiceRequest>>anyObject())).andReturn(response).once();
-
-    // replay
-    replay(managementController, response);
-
-    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
-        type,
-        PropertyHelper.getPropertyIds(type),
-        PropertyHelper.getKeyPropertyIds(type),
-        managementController);
-
-    // add the property map to a set for the request.
-    Map<String, Object> properties = new LinkedHashMap<String, Object>();
-
-    properties.put(ServiceResourceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID, "DEPLOYED");
-
-    // create the request
-    Request request = PropertyHelper.getUpdateRequest(properties);
-
-    // update the service named Service102
-    Predicate  predicate = new PredicateBuilder().property(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID).equals("Cluster100").
-        and().property(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID).equals("Service102").toPredicate();
-    provider.updateResources(request, predicate);
-
-    // verify
-    verify(managementController, response);
-  }
-
   @Test
   public void testCheckPropertyIds() {
     Set<String> propertyIds = new HashSet<String>();
@@ -513,41 +117,108 @@ public class AbstractResourceProviderTest {
 
   // ----- helper methods ----------------------------------------------------
 
-  public static class Matchers
+  /**
+   * Equals check that accounts for nulls.
+   *
+   * @param left   the left object
+   * @param right  the right object
+   *
+   * @return true if the left and right object are equal or both null
+   */
+  private static boolean eq(Object left, Object right) {
+    return  left == null ? right == null : right != null && left.equals(right);
+  }
+
+
+  // ----- inner classes -----------------------------------------------------
+
+  /**
+   * Utility class for getting various AmbariManagmentController request related matchers.
+   */
+  public static class Matcher
   {
-    public static ClusterRequest clusterRequest(Long clusterId, String clusterName, String stackVersion, Set<String> hostNames)
+    public static ClusterRequest getClusterRequest(
+        Long clusterId, String clusterName, String stackVersion, Set<String> hostNames)
     {
       EasyMock.reportMatcher(new ClusterRequestMatcher(clusterId, clusterName, stackVersion, hostNames));
       return null;
     }
 
-    public static Set<ServiceRequest> serviceRequestSet(String clusterName, String serviceName, Map<String, String> configVersions, String desiredState)
+    public static ConfigurationRequest getConfigurationRequest(
+        String clusterName, String type, String tag, Map<String, String> configs)
     {
-      EasyMock.reportMatcher(new ServiceRequestSetMatcher(clusterName, serviceName, configVersions, desiredState));
+      EasyMock.reportMatcher(new ConfigurationRequestMatcher(clusterName, type, tag, configs));
       return null;
     }
 
-    public static Set<ServiceComponentRequest> componentRequestSet(String clusterName, String serviceName, String componentName,
-                                                           Map<String, String> configVersions, String desiredState)
+    public static RequestStatusRequest getRequestRequest(Long requestId)
     {
-      EasyMock.reportMatcher(new ComponentRequestSetMatcher(clusterName, serviceName, componentName, configVersions, desiredState));
+      EasyMock.reportMatcher(new RequestRequestMatcher(requestId));
       return null;
     }
 
-    public static ConfigurationRequest configurationRequest(String clusterName, String type, String tag, Map<String, String> configs)
+    public static Set<ActionRequest> getActionRequestSet(String clusterName, String serviceName, String actionName)
     {
-      EasyMock.reportMatcher(new ConfigurationRequestMatcher(clusterName, type, tag, configs));
+      EasyMock.reportMatcher(new ActionRequestSetMatcher(clusterName, serviceName, actionName));
       return null;
     }
-  }
 
-  public static boolean eq(Object left, Object right) {
-    return  left == null ? right == null : right != null && left.equals(right);
-  }
+    public static Set<ServiceComponentRequest> getComponentRequestSet(String clusterName, String serviceName,
+                                                                      String componentName,
+                                                                      Map<String, String> configVersions,
+                                                                      String desiredState)
+    {
+      EasyMock.reportMatcher(new ComponentRequestSetMatcher(clusterName, serviceName, componentName,
+          configVersions, desiredState));
+      return null;
+    }
+
+    public static Set<ConfigurationRequest> getConfigurationRequestSet(String clusterName, String type,
+                                                                       String tag, Map<String, String> configs)
+    {
+      EasyMock.reportMatcher(new ConfigurationRequestSetMatcher(clusterName, type, tag, configs));
+      return null;
+    }
 
+    public static Set<HostRequest> getHostRequestSet(String hostname, String clusterName,
+                                                     Map<String, String> hostAttributes)
+    {
+      EasyMock.reportMatcher(new HostRequestSetMatcher(hostname, clusterName, hostAttributes));
+      return null;
+    }
 
-  // ----- inner classes -----------------------------------------------------
+    public static Set<ServiceComponentHostRequest> getHostComponentRequestSet(
+        String clusterName, String serviceName, String componentName, String hostName,
+        Map<String, String> configVersions, String desiredState)
+    {
+      EasyMock.reportMatcher(new HostComponentRequestSetMatcher(
+          clusterName, serviceName, componentName, hostName, configVersions, desiredState));
+      return null;
+    }
 
+    public static Set<ServiceRequest> getServiceRequestSet(String clusterName, String serviceName,
+                                                           Map<String, String> configVersions, String desiredState)
+    {
+      EasyMock.reportMatcher(new ServiceRequestSetMatcher(clusterName, serviceName, configVersions, desiredState));
+      return null;
+    }
+
+    public static Set<TaskStatusRequest> getTaskRequestSet(Long requestId, Long taskId)
+    {
+      EasyMock.reportMatcher(new TaskRequestSetMatcher(requestId, taskId));
+      return null;
+    }
+
+    public static Set<UserRequest> getUserRequestSet(String name)
+    {
+      EasyMock.reportMatcher(new UserRequestSetMatcher(name));
+      return null;
+    }
+  }
+
+  /**
+   * Matcher for a ClusterRequest.
+   */
   public static class ClusterRequestMatcher extends ClusterRequest implements IArgumentMatcher {
 
     public ClusterRequestMatcher(Long clusterId, String clusterName, String stackVersion, Set<String> hostNames) {
@@ -565,17 +236,67 @@ public class AbstractResourceProviderTest {
 
     @Override
     public void appendTo(StringBuffer stringBuffer) {
-      stringBuffer.append("ClusterRequestMatcher(" + "" + ")");
+      stringBuffer.append("ClusterRequestMatcher(" + super.toString() + ")");
     }
   }
 
-  public static class ServiceRequestSetMatcher extends HashSet<ServiceRequest> implements IArgumentMatcher {
+  /**
+   * Matcher for a ConfigurationRequest.
+   */
+  public static class ConfigurationRequestMatcher extends ConfigurationRequest implements IArgumentMatcher {
 
-    private final ServiceRequest serviceRequest;
+    public ConfigurationRequestMatcher(String clusterName, String type, String tag, Map<String, String> configs) {
+      super(clusterName, type, tag, configs);
+    }
 
-    public ServiceRequestSetMatcher(String clusterName, String serviceName, Map<String, String> configVersions, String desiredState) {
-      this.serviceRequest = new ServiceRequest(clusterName, serviceName, configVersions, desiredState);
-      add(this.serviceRequest);
+    @Override
+    public boolean matches(Object o) {
+      return o instanceof ConfigurationRequest &&
+          eq(((ConfigurationRequest) o).getClusterName(), getClusterName()) &&
+          eq(((ConfigurationRequest) o).getType(), getType()) &&
+          eq(((ConfigurationRequest) o).getVersionTag(), getVersionTag()) &&
+          eq(((ConfigurationRequest) o).getConfigs(), getConfigs());
+
+    }
+
+    @Override
+    public void appendTo(StringBuffer stringBuffer) {
+      stringBuffer.append("ConfigurationRequestMatcher(" + super.toString() + ")");
+    }
+  }
+
+  /**
+   * Matcher for a RequestStatusRequest.
+   */
+  public static class RequestRequestMatcher extends RequestStatusRequest implements IArgumentMatcher {
+
+    public RequestRequestMatcher(Long requestId) {
+      super(requestId, "");
+    }
+
+    @Override
+    public boolean matches(Object o) {
+
+      return o instanceof RequestStatusRequest &&
+          eq(((RequestStatusRequest) o).getRequestId(), getRequestId());
+    }
+
+    @Override
+    public void appendTo(StringBuffer stringBuffer) {
+      stringBuffer.append("RequestRequestMatcher(" + super.toString() + ")");
+    }
+  }
+
+  /**
+   * Matcher for a ActionRequest set containing a single request.
+   */
+  public static class ActionRequestSetMatcher extends HashSet<ActionRequest> implements IArgumentMatcher {
+
+    private final ActionRequest actionRequest;
+
+    public ActionRequestSetMatcher(String clusterName, String serviceName, String actionName) {
+      this.actionRequest = new ActionRequest(clusterName, serviceName, actionName, null);
+      add(this.actionRequest);
     }
 
     @Override
@@ -592,26 +313,29 @@ public class AbstractResourceProviderTest {
 
       Object request = set.iterator().next();
 
-      return request instanceof ServiceRequest &&
-          eq(((ServiceRequest) request).getClusterName(), serviceRequest.getClusterName()) &&
-          eq(((ServiceRequest) request).getServiceName(), serviceRequest.getServiceName()) &&
-          eq(((ServiceRequest) request).getConfigVersions(), serviceRequest.getConfigVersions()) &&
-          eq(((ServiceRequest) request).getDesiredState(), serviceRequest.getDesiredState());
+      return request instanceof ActionRequest &&
+          eq(((ActionRequest) request).getClusterName(), actionRequest.getClusterName()) &&
+          eq(((ActionRequest) request).getServiceName(), actionRequest.getServiceName()) &&
+          eq(((ActionRequest) request).getActionName(), actionRequest.getActionName());
     }
 
     @Override
     public void appendTo(StringBuffer stringBuffer) {
-      stringBuffer.append("ServiceRequestSetMatcher(" + "" + ")");
+      stringBuffer.append("ActionRequestSetMatcher(" + actionRequest + ")");
     }
   }
 
+  /**
+   * Matcher for a ServiceComponentRequest set containing a single request.
+   */
   public static class ComponentRequestSetMatcher extends HashSet<ServiceComponentRequest> implements IArgumentMatcher {
 
     private final ServiceComponentRequest serviceComponentRequest;
 
     public ComponentRequestSetMatcher(String clusterName, String serviceName, String componentName,
                                    Map<String, String> configVersions, String desiredState) {
-      this.serviceComponentRequest = new ServiceComponentRequest(clusterName, serviceName, componentName, configVersions, desiredState);
+      this.serviceComponentRequest =
+          new ServiceComponentRequest(clusterName, serviceName, componentName, configVersions, desiredState);
       add(this.serviceComponentRequest);
     }
 
@@ -640,33 +364,252 @@ public class AbstractResourceProviderTest {
 
     @Override
     public void appendTo(StringBuffer stringBuffer) {
-      stringBuffer.append("ComponentRequestMatcher(" + "" + ")");
+      stringBuffer.append("ComponentRequestSetMatcher(" + serviceComponentRequest + ")");
     }
   }
 
-  public static class ConfigurationRequestMatcher extends ConfigurationRequest implements IArgumentMatcher {
+  /**
+   * Matcher for a ConfigurationRequest set containing a single request.
+   */
+  public static class ConfigurationRequestSetMatcher extends HashSet<ConfigurationRequest> implements IArgumentMatcher {
 
-    public ConfigurationRequestMatcher(String clusterName, String type, String tag, Map<String, String> configs) {
-      super(clusterName, type, tag, configs);
+    private final ConfigurationRequest configurationRequest;
+
+    public ConfigurationRequestSetMatcher(String clusterName, String type, String tag, Map<String, String> configs) {
+      this.configurationRequest = new ConfigurationRequest(clusterName, type, tag, configs);
+      add(this.configurationRequest);
     }
 
     @Override
     public boolean matches(Object o) {
-      return o instanceof ConfigurationRequest &&
-          eq(((ConfigurationRequest) o).getClusterName(), getClusterName()) &&
-          eq(((ConfigurationRequest) o).getType(), getType()) &&
-          eq(((ConfigurationRequest) o).getVersionTag(), getVersionTag()) &&
-          eq(((ConfigurationRequest) o).getConfigs(), getConfigs());
 
+      if (!(o instanceof Set)) {
+        return false;
+      }
+
+      Set set = (Set) o;
+
+      if (set.size() != 1) {
+        return false;
+      }
+
+      Object request = set.iterator().next();
+
+      return request instanceof ConfigurationRequest &&
+          eq(((ConfigurationRequest) request).getClusterName(), configurationRequest.getClusterName()) &&
+          eq(((ConfigurationRequest) request).getType(), configurationRequest.getType()) &&
+          eq(((ConfigurationRequest) request).getVersionTag(), configurationRequest.getVersionTag()) &&
+          eq(((ConfigurationRequest) request).getConfigs(), configurationRequest.getConfigs());
+    }
+
+    @Override
+    public void appendTo(StringBuffer stringBuffer) {
+      stringBuffer.append("ConfigurationRequestSetMatcher(" + configurationRequest + ")");
+    }
+  }
+
+  /**
+   * Matcher for a HostRequest set containing a single request.
+   */
+  public static class HostRequestSetMatcher extends HashSet<HostRequest> implements IArgumentMatcher {
+
+    private final HostRequest hostRequest;
+
+    public HostRequestSetMatcher(String hostname, String clusterName, Map<String, String> hostAttributes) {
+      this.hostRequest = new HostRequest(hostname, clusterName, hostAttributes);
+      add(this.hostRequest);
+    }
+
+    @Override
+    public boolean matches(Object o) {
+      if (!(o instanceof Set)) {
+        return false;
+      }
+
+      Set set = (Set) o;
+
+      if (set.size() != 1) {
+        return false;
+      }
+
+      Object request = set.iterator().next();
+
+      return request instanceof HostRequest &&
+          eq(((HostRequest) request).getClusterName(), hostRequest.getClusterName()) &&
+          eq(((HostRequest) request).getHostname(), hostRequest.getHostname()) &&
+          eq(((HostRequest) request).getHostAttributes(), hostRequest.getHostAttributes());
+    }
+
+    @Override
+    public void appendTo(StringBuffer stringBuffer) {
+      stringBuffer.append("HostRequestSetMatcher(" + hostRequest + ")");
+    }
+  }
+
+  /**
+   * Matcher for a ServiceComponentHostRequest set containing a single request.
+   */
+  public static class HostComponentRequestSetMatcher extends HashSet<ServiceComponentHostRequest>
+      implements IArgumentMatcher {
+
+    private final ServiceComponentHostRequest hostComponentRequest;
+
+    public HostComponentRequestSetMatcher(String clusterName, String serviceName, String componentName, String hostName,
+                                      Map<String, String> configVersions, String desiredState) {
+      this.hostComponentRequest =
+          new ServiceComponentHostRequest(clusterName, serviceName, componentName,
+              hostName, configVersions, desiredState);
+      add(this.hostComponentRequest);
+    }
+
+    @Override
+    public boolean matches(Object o) {
+
+      if (!(o instanceof Set)) {
+        return false;
+      }
+
+      Set set = (Set) o;
+
+      if (set.size() != 1) {
+        return false;
+      }
+
+      Object request = set.iterator().next();
+
+      return request instanceof ServiceComponentHostRequest &&
+          eq(((ServiceComponentHostRequest) request).getClusterName(), hostComponentRequest.getClusterName()) &&
+          eq(((ServiceComponentHostRequest) request).getServiceName(), hostComponentRequest.getServiceName()) &&
+          eq(((ServiceComponentHostRequest) request).getComponentName(), hostComponentRequest.getComponentName()) &&
+          eq(((ServiceComponentHostRequest) request).getHostname(), hostComponentRequest.getHostname()) &&
+          eq(((ServiceComponentHostRequest) request).getConfigVersions(), hostComponentRequest.getConfigVersions()) &&
+          eq(((ServiceComponentHostRequest) request).getDesiredState(), hostComponentRequest.getDesiredState());
+    }
+
+    @Override
+    public void appendTo(StringBuffer stringBuffer) {
+      stringBuffer.append("HostComponentRequestSetMatcher(" + hostComponentRequest + ")");
+    }
+  }
+
+  /**
+   * Matcher for a ServiceRequest set containing a single request.
+   */
+  public static class ServiceRequestSetMatcher extends HashSet<ServiceRequest> implements IArgumentMatcher {
+
+    private final ServiceRequest serviceRequest;
+
+    public ServiceRequestSetMatcher(
+        String clusterName, String serviceName, Map<String, String> configVersions, String desiredState) {
+      this.serviceRequest = new ServiceRequest(clusterName, serviceName, configVersions, desiredState);
+      add(this.serviceRequest);
+    }
+
+    @Override
+    public boolean matches(Object o) {
+      if (!(o instanceof Set)) {
+        return false;
+      }
+
+      Set set = (Set) o;
+
+      if (set.size() != 1) {
+        return false;
+      }
+
+      Object request = set.iterator().next();
+
+      return request instanceof ServiceRequest &&
+          eq(((ServiceRequest) request).getClusterName(), serviceRequest.getClusterName()) &&
+          eq(((ServiceRequest) request).getServiceName(), serviceRequest.getServiceName()) &&
+          eq(((ServiceRequest) request).getConfigVersions(), serviceRequest.getConfigVersions()) &&
+          eq(((ServiceRequest) request).getDesiredState(), serviceRequest.getDesiredState());
+    }
+
+    @Override
+    public void appendTo(StringBuffer stringBuffer) {
+      stringBuffer.append("ServiceRequestSetMatcher(" + serviceRequest + ")");
+    }
+  }
+
+  /**
+   * Matcher for a TaskStatusRequest set containing a single request.
+   */
+  public static class TaskRequestSetMatcher extends HashSet<TaskStatusRequest> implements IArgumentMatcher {
+
+    private final TaskStatusRequest taskStatusRequest;
+
+    public TaskRequestSetMatcher(Long requestId, Long taskId) {
+      this.taskStatusRequest = new TaskStatusRequest(requestId, taskId);
+      add(this.taskStatusRequest);
+    }
+
+    @Override
+    public boolean matches(Object o) {
+
+      if (!(o instanceof Set)) {
+        return false;
+      }
+
+      Set set = (Set) o;
+
+      if (set.size() != 1) {
+        return false;
+      }
+
+      Object request = set.iterator().next();
+
+      return request instanceof TaskStatusRequest &&
+          eq(((TaskStatusRequest) request).getRequestId(), taskStatusRequest.getRequestId());
+    }
+
+    @Override
+    public void appendTo(StringBuffer stringBuffer) {
+      stringBuffer.append("TaskRequestSetMatcher(" + taskStatusRequest + ")");
+    }
+  }
+
+  /**
+   * Matcher for a UserRequest set containing a single request.
+   */
+  public static class UserRequestSetMatcher extends HashSet<UserRequest> implements IArgumentMatcher {
+
+    private final UserRequest userRequest;
+
+    public UserRequestSetMatcher(String name) {
+      this.userRequest = new UserRequest(name);
+      add(this.userRequest);
+    }
+
+    @Override
+    public boolean matches(Object o) {
+
+      if (!(o instanceof Set)) {
+        return false;
+      }
+
+      Set set = (Set) o;
+
+      if (set.size() != 1) {
+        return false;
+      }
+
+      Object request = set.iterator().next();
+
+      return request instanceof UserRequest &&
+          eq(((UserRequest) request).getUsername(), userRequest.getUsername());
     }
 
     @Override
     public void appendTo(StringBuffer stringBuffer) {
-      stringBuffer.append("ConfigurationRequestMatcher(" + "" + ")");
+      stringBuffer.append("UserRequestSetMatcher(" + userRequest + ")");
     }
   }
 
-  public class TestObserver implements ResourceProviderObserver {
+  /**
+   * A test observer that records the last event.
+   */
+  public static class TestObserver implements ResourceProviderObserver {
 
     ResourceProviderEvent lastEvent = null;
 

+ 237 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ActionResourceProviderTest.java

@@ -0,0 +1,237 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * ActionResourceProvider tests.
+ */
+public class ActionResourceProviderTest {
+  @Test
+  public void testCreateResources() throws Exception {
+    Resource.Type type = Resource.Type.Action;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    expect(managementController.createActions(AbstractResourceProviderTest.Matcher.getActionRequestSet(
+        "Cluster100", "Service100", "Action100"))).andReturn(response);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.  add more maps for multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+
+    // Service 1: create a map of properties for the request
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // add properties to the request map
+    properties.put(ActionResourceProvider.ACTION_CLUSTER_NAME_PROPERTY_ID, "Cluster100");
+    properties.put(ActionResourceProvider.ACTION_SERVICE_NAME_PROPERTY_ID, "Service100");
+    properties.put(ActionResourceProvider.ACTION_ACTION_NAME_PROPERTY_ID, "Action100");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet);
+
+    provider.createResources(request);
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testGetResources() throws Exception {
+    Resource.Type type = Resource.Type.Action;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    propertyIds.add(ActionResourceProvider.ACTION_CLUSTER_NAME_PROPERTY_ID);
+    propertyIds.add(ActionResourceProvider.ACTION_SERVICE_NAME_PROPERTY_ID);
+    propertyIds.add(ActionResourceProvider.ACTION_ACTION_NAME_PROPERTY_ID);
+
+    // create the request
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+
+    // get all ... no predicate
+    try {
+      provider.getResources(request, null);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController);
+  }
+
+
+  @Test
+  public void testUpdateResources() throws Exception {
+    Resource.Type type = Resource.Type.Action;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // create the request
+    Request request = PropertyHelper.getUpdateRequest(properties);
+
+    Predicate predicate =
+        new PredicateBuilder().property(ActionResourceProvider.ACTION_CLUSTER_NAME_PROPERTY_ID).equals("Cluster100").
+        and().property(ActionResourceProvider.ACTION_SERVICE_NAME_PROPERTY_ID).equals("Service102").
+        and().property(ActionResourceProvider.ACTION_ACTION_NAME_PROPERTY_ID).equals("Action100").toPredicate();
+    try {
+      provider.updateResources(request, predicate);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testDeleteResources() throws Exception {
+    Resource.Type type = Resource.Type.Action;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Predicate  predicate =
+        new PredicateBuilder().property(ActionResourceProvider.ACTION_ACTION_NAME_PROPERTY_ID).equals("Action100").
+            toPredicate();
+    try {
+      provider.deleteResources(predicate);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testCheckPropertyIds() throws Exception {
+    Set<String> propertyIds = new HashSet<String>();
+    propertyIds.add("foo");
+    propertyIds.add("cat1/foo");
+    propertyIds.add("cat2/bar");
+    propertyIds.add("cat2/baz");
+    propertyIds.add("cat3/sub1/bam");
+    propertyIds.add("cat4/sub2/sub3/bat");
+    propertyIds.add("cat5/subcat5/map");
+
+    Map<Resource.Type, String> keyPropertyIds = new HashMap<Resource.Type, String>();
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    AbstractResourceProvider provider =
+        (AbstractResourceProvider) AbstractResourceProvider.getResourceProvider(
+            Resource.Type.Action,
+            propertyIds,
+            keyPropertyIds,
+            managementController);
+
+    Set<String> unsupported = provider.checkPropertyIds(Collections.singleton("foo"));
+    Assert.assertTrue(unsupported.isEmpty());
+
+    // note that key is not in the set of known property ids.  We allow it if its parent is a known property.
+    // this allows for Map type properties where we want to treat the entries as individual properties
+    Assert.assertTrue(provider.checkPropertyIds(Collections.singleton("cat5/subcat5/map/key")).isEmpty());
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("bar"));
+    Assert.assertEquals(1, unsupported.size());
+    Assert.assertTrue(unsupported.contains("bar"));
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("cat1/foo"));
+    Assert.assertTrue(unsupported.isEmpty());
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("cat1"));
+    Assert.assertTrue(unsupported.isEmpty());
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("parameters/unknown_property"));
+    Assert.assertTrue(unsupported.isEmpty());
+  }
+}

+ 301 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java

@@ -0,0 +1,301 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ClusterRequest;
+import org.apache.ambari.server.controller.ClusterResponse;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * ClusterResourceProvider tests.
+ */
+public class ClusterResourceProviderTest {
+  @Test
+  public void testCreateResources() throws Exception{
+    Resource.Type type = Resource.Type.Cluster;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    managementController.createCluster(
+        AbstractResourceProviderTest.Matcher.getClusterRequest(null, "Cluster100", "HDP-0.1", null));
+    managementController.createCluster(
+        AbstractResourceProviderTest.Matcher.getClusterRequest(99L, null, "HDP-0.1", null));
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    AbstractResourceProviderTest.TestObserver observer = new AbstractResourceProviderTest.TestObserver();
+
+    ((ObservableResourceProvider)provider).addObserver(observer);
+
+    // add the property map to a set for the request.  add more maps for multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+
+    // Cluster 1: create a map of properties for the request
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // add the cluster name to the properties map
+    properties.put(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID, "Cluster100");
+
+    // add the version to the properties map
+    properties.put(ClusterResourceProvider.CLUSTER_VERSION_PROPERTY_ID, "HDP-0.1");
+
+    propertySet.add(properties);
+
+    // Cluster 2: create a map of properties for the request
+    properties = new LinkedHashMap<String, Object>();
+
+    // add the cluster id to the properties map
+    properties.put(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID, 99L);
+
+    // add the version to the properties map
+    properties.put(ClusterResourceProvider.CLUSTER_VERSION_PROPERTY_ID, "HDP-0.1");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet);
+
+    provider.createResources(request);
+
+    ResourceProviderEvent lastEvent = observer.getLastEvent();
+    Assert.assertNotNull(lastEvent);
+    Assert.assertEquals(Resource.Type.Cluster, lastEvent.getResourceType());
+    Assert.assertEquals(ResourceProviderEvent.Type.Create, lastEvent.getType());
+    Assert.assertEquals(request, lastEvent.getRequest());
+    Assert.assertNull(lastEvent.getPredicate());
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testGetResources() throws Exception{
+    Resource.Type type = Resource.Type.Cluster;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    Set<ClusterResponse> allResponse = new HashSet<ClusterResponse>();
+    allResponse.add(new ClusterResponse(100L, "Cluster100", null, null));
+    allResponse.add(new ClusterResponse(101L, "Cluster101", null, null));
+    allResponse.add(new ClusterResponse(102L, "Cluster102", null, null));
+    allResponse.add(new ClusterResponse(103L, "Cluster103", null, null));
+    allResponse.add(new ClusterResponse(104L, "Cluster104", null, null));
+
+    Set<ClusterResponse> nameResponse = new HashSet<ClusterResponse>();
+    nameResponse.add(new ClusterResponse(102L, "Cluster102", null, null));
+
+    Set<ClusterResponse> idResponse = new HashSet<ClusterResponse>();
+    idResponse.add(new ClusterResponse(103L, "Cluster103", null, null));
+
+    // set expectations
+    expect(managementController.getClusters(EasyMock.<Set<ClusterRequest>>anyObject())).andReturn(allResponse).once();
+    expect(managementController.getClusters(EasyMock.<Set<ClusterRequest>>anyObject())).andReturn(nameResponse).once();
+    expect(managementController.getClusters(EasyMock.<Set<ClusterRequest>>anyObject())).andReturn(idResponse).once();
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    propertyIds.add(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID);
+    propertyIds.add(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID);
+
+    // create the request
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+
+    // get all ... no predicate
+    Set<Resource> resources = provider.getResources(request, null);
+
+    Assert.assertEquals(5, resources.size());
+    for (Resource resource : resources) {
+      Long id = (Long) resource.getPropertyValue(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID);
+      String name = (String) resource.getPropertyValue(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID);
+      Assert.assertEquals(name, "Cluster" + id);
+    }
+
+    // get cluster named Cluster102
+    Predicate predicate =
+        new PredicateBuilder().property(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID).equals("Cluster102").
+            toPredicate();
+    resources = provider.getResources(request, predicate);
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(102L, resources.iterator().next().
+        getPropertyValue(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID));
+    Assert.assertEquals("Cluster102", resources.iterator().next().
+        getPropertyValue(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID));
+
+    // get cluster with id == 103
+    predicate =
+        new PredicateBuilder().property(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID).equals(103L).toPredicate();
+    resources = provider.getResources(request, predicate);
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals(103L, resources.iterator().next().
+        getPropertyValue(ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID));
+    Assert.assertEquals("Cluster103", resources.iterator().next().
+        getPropertyValue(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID));
+
+    // verify
+    verify(managementController);
+  }
+
+  @Test
+  public void testUpdateResources() throws Exception{
+    Resource.Type type = Resource.Type.Cluster;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    Set<ClusterResponse> nameResponse = new HashSet<ClusterResponse>();
+    nameResponse.add(new ClusterResponse(102L, "Cluster102", null, null));
+
+    // set expectations
+    expect(managementController.getClusters(EasyMock.<Set<ClusterRequest>>anyObject())).andReturn(nameResponse).once();
+    expect(managementController.updateCluster(
+        AbstractResourceProviderTest.Matcher.getClusterRequest(102L, "Cluster102", "HDP-0.1", null))).
+        andReturn(response).once();
+    expect(managementController.updateCluster(
+        AbstractResourceProviderTest.Matcher.getClusterRequest(103L, null, "HDP-0.1", null))).
+        andReturn(response).once();
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    AbstractResourceProviderTest.TestObserver observer = new AbstractResourceProviderTest.TestObserver();
+
+    ((ObservableResourceProvider)provider).addObserver(observer);
+
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    properties.put(ClusterResourceProvider.CLUSTER_VERSION_PROPERTY_ID, "HDP-0.1");
+
+    // create the request
+    Request request = PropertyHelper.getUpdateRequest(properties);
+
+    // update the cluster named Cluster102
+    Predicate  predicate = new PredicateBuilder().property(
+        ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID).equals("Cluster102").toPredicate();
+    provider.updateResources(request, predicate);
+
+    // update the cluster where id == 103
+    predicate = new PredicateBuilder().property(
+        ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID).equals(103L).toPredicate();
+    provider.updateResources(request, predicate);
+
+    ResourceProviderEvent lastEvent = observer.getLastEvent();
+    Assert.assertNotNull(lastEvent);
+    Assert.assertEquals(Resource.Type.Cluster, lastEvent.getResourceType());
+    Assert.assertEquals(ResourceProviderEvent.Type.Update, lastEvent.getType());
+    Assert.assertEquals(request, lastEvent.getRequest());
+    Assert.assertEquals(predicate, lastEvent.getPredicate());
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testDeleteResources() throws Exception{
+    Resource.Type type = Resource.Type.Cluster;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // set expectations
+    managementController.deleteCluster(
+        AbstractResourceProviderTest.Matcher.getClusterRequest(null, "Cluster102", null, null));
+    managementController.deleteCluster(
+        AbstractResourceProviderTest.Matcher.getClusterRequest(103L, null, null, null));
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    AbstractResourceProviderTest.TestObserver observer = new AbstractResourceProviderTest.TestObserver();
+
+    ((ObservableResourceProvider)provider).addObserver(observer);
+
+    // delete the cluster named Cluster102
+    Predicate  predicate = new PredicateBuilder().property(
+        ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID).equals("Cluster102").toPredicate();
+    provider.deleteResources(predicate);
+
+    // delete the cluster where id == 103
+    predicate = new PredicateBuilder().property(
+        ClusterResourceProvider.CLUSTER_ID_PROPERTY_ID).equals(103L).toPredicate();
+    provider.deleteResources(predicate);
+
+    ResourceProviderEvent lastEvent = observer.getLastEvent();
+    Assert.assertNotNull(lastEvent);
+    Assert.assertEquals(Resource.Type.Cluster, lastEvent.getResourceType());
+    Assert.assertEquals(ResourceProviderEvent.Type.Delete, lastEvent.getType());
+    Assert.assertEquals(predicate, lastEvent.getPredicate());
+    Assert.assertNull(lastEvent.getRequest());
+
+    // verify
+    verify(managementController, response);
+  }
+}

+ 142 - 3
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ComponentResourceProviderTest.java

@@ -29,10 +29,12 @@ import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.easymock.EasyMock;
+import org.junit.Assert;
 import org.junit.Test;
 
 import java.util.HashSet;
 import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -46,6 +48,100 @@ import static org.easymock.EasyMock.verify;
  * Tests for the component resource provider.
  */
 public class ComponentResourceProviderTest {
+  @Test
+  public void testCreateResources() throws Exception {
+    Resource.Type type = Resource.Type.Component;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    managementController.createComponents(
+        AbstractResourceProviderTest.Matcher.getComponentRequestSet(
+            "Cluster100", "Service100", "Component100", null, null));
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.  add more maps for multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+
+    // Service 1: create a map of properties for the request
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // add properties to the request map
+    properties.put(ComponentResourceProvider.COMPONENT_CLUSTER_NAME_PROPERTY_ID, "Cluster100");
+    properties.put(ComponentResourceProvider.COMPONENT_SERVICE_NAME_PROPERTY_ID, "Service100");
+    properties.put(ComponentResourceProvider.COMPONENT_COMPONENT_NAME_PROPERTY_ID, "Component100");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet);
+
+    provider.createResources(request);
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testGetResources() throws Exception {
+    Resource.Type type = Resource.Type.Component;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    Set<ServiceComponentResponse> allResponse = new HashSet<ServiceComponentResponse>();
+    allResponse.add(new ServiceComponentResponse(100L, "Cluster100", "Service100", "Component100", null, null, ""));
+    allResponse.add(new ServiceComponentResponse(100L, "Cluster100", "Service100", "Component101", null, null, ""));
+    allResponse.add(new ServiceComponentResponse(100L, "Cluster100", "Service100", "Component102", null, null, ""));
+
+    // set expectations
+    expect(managementController.getComponents(
+        AbstractResourceProviderTest.Matcher.getComponentRequestSet(
+            "Cluster100", null, null, null, null))).andReturn(allResponse).once();
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    propertyIds.add(ComponentResourceProvider.COMPONENT_CLUSTER_NAME_PROPERTY_ID);
+    propertyIds.add(ComponentResourceProvider.COMPONENT_COMPONENT_NAME_PROPERTY_ID);
+
+    Predicate predicate = new PredicateBuilder().property(ComponentResourceProvider.COMPONENT_CLUSTER_NAME_PROPERTY_ID).
+        equals("Cluster100").toPredicate();
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+    Set<Resource> resources = provider.getResources(request, predicate);
+
+    Assert.assertEquals(3, resources.size());
+    Set<String> names = new HashSet<String>();
+    for (Resource resource : resources) {
+      String clusterName = (String) resource.getPropertyValue(
+          ComponentResourceProvider.COMPONENT_CLUSTER_NAME_PROPERTY_ID);
+      Assert.assertEquals("Cluster100", clusterName);
+      names.add((String) resource.getPropertyValue(ComponentResourceProvider.COMPONENT_COMPONENT_NAME_PROPERTY_ID));
+    }
+    // Make sure that all of the response objects got moved into resources
+    for (ServiceComponentResponse response : allResponse ) {
+      Assert.assertTrue(names.contains(response.getComponentName()));
+    }
+
+    // verify
+    verify(managementController);
+  }
+
   @Test
   public void testUpdateResources() throws Exception {
     Resource.Type type = Resource.Type.Component;
@@ -57,9 +153,11 @@ public class ComponentResourceProviderTest {
     nameResponse.add(new ServiceComponentResponse(102L, "Cluster102", "Service", "Component", null, "1", "STARTED"));
 
     // set expectations
-    expect(managementController.getComponents(EasyMock.<Set<ServiceComponentRequest>>anyObject())).andReturn(nameResponse).once();
+    expect(managementController.getComponents(EasyMock.<Set<ServiceComponentRequest>>anyObject())).
+        andReturn(nameResponse).once();
     expect(managementController.updateComponents(
-        AbstractResourceProviderTest.Matchers.componentRequestSet("Cluster102", "Service", "Component", null, "STARTED"))).andReturn(response).once();
+        AbstractResourceProviderTest.Matcher.getComponentRequestSet(
+            "Cluster102", "Service", "Component", null, "STARTED"))).andReturn(response).once();
 
     // replay
     replay(managementController, response);
@@ -78,10 +176,51 @@ public class ComponentResourceProviderTest {
     Request request = PropertyHelper.getUpdateRequest(properties);
 
     // update the cluster named Cluster102
-    Predicate predicate = new PredicateBuilder().property(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID).equals("Cluster102").toPredicate();
+    Predicate predicate = new PredicateBuilder().property(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID).
+        equals("Cluster102").toPredicate();
     provider.updateResources(request, predicate);
 
     // verify
     verify(managementController, response);
   }
+
+  @Test
+  public void testDeleteResources() throws Exception {
+    Resource.Type type = Resource.Type.Component;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // set expectations
+    expect(managementController.deleteComponents(AbstractResourceProviderTest.Matcher.
+        getComponentRequestSet(null, null, "Component100", null, null))).andReturn(response);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    AbstractResourceProviderTest.TestObserver observer = new AbstractResourceProviderTest.TestObserver();
+
+    ((ObservableResourceProvider)provider).addObserver(observer);
+
+    Predicate  predicate = new PredicateBuilder().property(
+        ComponentResourceProvider.COMPONENT_COMPONENT_NAME_PROPERTY_ID).equals("Component100").toPredicate();
+    provider.deleteResources(predicate);
+
+
+    ResourceProviderEvent lastEvent = observer.getLastEvent();
+    Assert.assertNotNull(lastEvent);
+    Assert.assertEquals(Resource.Type.Component, lastEvent.getResourceType());
+    Assert.assertEquals(ResourceProviderEvent.Type.Delete, lastEvent.getType());
+    Assert.assertEquals(predicate, lastEvent.getPredicate());
+    Assert.assertNull(lastEvent.getRequest());
+
+    // verify
+    verify(managementController, response);
+  }
 }

+ 127 - 1
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ConfigurationResourceProviderTest.java

@@ -19,13 +19,20 @@
 package org.apache.ambari.server.controller.internal;
 
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ConfigurationResponse;
 import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.junit.Assert;
 import org.junit.Test;
 
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.Map;
@@ -33,6 +40,7 @@ import java.util.Set;
 
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 
@@ -46,7 +54,7 @@ public class ConfigurationResourceProviderTest {
     AmbariManagementController managementController = createMock(AmbariManagementController.class);
     RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
 
-    managementController.createConfiguration(AbstractResourceProviderTest.Matchers.configurationRequest(
+    managementController.createConfiguration(AbstractResourceProviderTest.Matcher.getConfigurationRequest(
         "Cluster100", "type", "tag", new HashMap<String, String>()));
 
     // replay
@@ -75,4 +83,122 @@ public class ConfigurationResourceProviderTest {
     // verify
     verify(managementController, response);
   }
+
+  @Test
+  public void testGetResources() throws Exception {
+    Resource.Type type = Resource.Type.Configuration;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    Set<ConfigurationResponse> allResponse = new HashSet<ConfigurationResponse>();
+    allResponse.add(new ConfigurationResponse("Cluster100", "type", "tag1", null));
+    allResponse.add(new ConfigurationResponse("Cluster100", "type", "tag2", null));
+    allResponse.add(new ConfigurationResponse("Cluster100", "type", "tag3", null));
+
+    // set expectations
+    expect(managementController.getConfigurations(
+        AbstractResourceProviderTest.Matcher.getConfigurationRequestSet(
+            "Cluster100", null, null, Collections.<String, String>emptyMap()))).andReturn(allResponse).once();
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    propertyIds.add(ConfigurationResourceProvider.CONFIGURATION_CLUSTER_NAME_PROPERTY_ID);
+    propertyIds.add(ConfigurationResourceProvider.CONFIGURATION_CONFIG_TAG_PROPERTY_ID);
+
+    Predicate predicate = new PredicateBuilder().property(
+        ConfigurationResourceProvider.CONFIGURATION_CLUSTER_NAME_PROPERTY_ID).equals("Cluster100").toPredicate();
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+    Set<Resource> resources = provider.getResources(request, predicate);
+
+    Assert.assertEquals(3, resources.size());
+    Set<String> tags = new HashSet<String>();
+    for (Resource resource : resources) {
+      String clusterName = (String) resource.getPropertyValue(
+          ConfigurationResourceProvider.CONFIGURATION_CLUSTER_NAME_PROPERTY_ID);
+      Assert.assertEquals("Cluster100", clusterName);
+      tags.add((String) resource.getPropertyValue(
+          ConfigurationResourceProvider.CONFIGURATION_CONFIG_TAG_PROPERTY_ID));
+    }
+    // Make sure that all of the response objects got moved into resources
+    for (ConfigurationResponse response : allResponse ) {
+      Assert.assertTrue(tags.contains(response.getVersionTag()));
+    }
+
+    // verify
+    verify(managementController);
+
+  }
+
+  @Test
+  public void testUpdateResources() throws Exception {
+    Resource.Type type = Resource.Type.Configuration;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // create the request
+    Request request = PropertyHelper.getUpdateRequest(properties);
+
+    Predicate predicate = new PredicateBuilder().property(
+        ConfigurationResourceProvider.CONFIGURATION_CONFIG_TAG_PROPERTY_ID).equals("Configuration100").toPredicate();
+
+    try {
+      provider.updateResources(request, predicate);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testDeleteResources() throws Exception {
+    Resource.Type type = Resource.Type.Configuration;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Predicate predicate = new PredicateBuilder().property(
+        ConfigurationResourceProvider.CONFIGURATION_CONFIG_TAG_PROPERTY_ID).equals("Configuration100").toPredicate();
+    try {
+      provider.deleteResources(predicate);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController);
+  }
 }

+ 282 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java

@@ -0,0 +1,282 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.ServiceComponentHostRequest;
+import org.apache.ambari.server.controller.ServiceComponentHostResponse;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * HostComponentResourceProvider tests.
+ */
+public class HostComponentResourceProviderTest {
+  @Test
+  public void testCreateResources() throws Exception {
+    Resource.Type type = Resource.Type.HostComponent;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    managementController.createHostComponents(
+        AbstractResourceProviderTest.Matcher.getHostComponentRequestSet(
+            "Cluster100", "Service100", "Component100", "Host100", null, null));
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.  add more maps for multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+
+    // Service 1: create a map of properties for the request
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // add properties to the request map
+    properties.put(HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID, "Cluster100");
+    properties.put(HostComponentResourceProvider.HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID, "Service100");
+    properties.put(HostComponentResourceProvider.HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID, "Component100");
+    properties.put(HostComponentResourceProvider.HOST_COMPONENT_HOST_NAME_PROPERTY_ID, "Host100");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet);
+
+    provider.createResources(request);
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testGetResources() throws Exception {
+    Resource.Type type = Resource.Type.HostComponent;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    Set<ServiceComponentHostResponse> allResponse = new HashSet<ServiceComponentHostResponse>();
+    allResponse.add(new ServiceComponentHostResponse(
+        "Cluster100", "Service100", "Component100", "Host100", null, null, "", "", "" ));
+    allResponse.add(new ServiceComponentHostResponse(
+        "Cluster100", "Service100", "Component101", "Host100", null, null, "", "", "" ));
+    allResponse.add(new ServiceComponentHostResponse(
+        "Cluster100", "Service100", "Component102", "Host100", null, null, "", "", "" ));
+
+    // set expectations
+    expect(managementController.getHostComponents(
+        AbstractResourceProviderTest.Matcher.getHostComponentRequestSet(
+            "Cluster100", null, null, null, null, null))).andReturn(allResponse).once();
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    propertyIds.add(HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID);
+    propertyIds.add(HostComponentResourceProvider.HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID);
+
+    Predicate predicate = new PredicateBuilder().property(
+        HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID).equals("Cluster100").toPredicate();
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+    Set<Resource> resources = provider.getResources(request, predicate);
+
+    Assert.assertEquals(3, resources.size());
+    Set<String> names = new HashSet<String>();
+    for (Resource resource : resources) {
+      String clusterName = (String) resource.getPropertyValue(
+          HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID);
+      Assert.assertEquals("Cluster100", clusterName);
+      names.add((String) resource.getPropertyValue(
+          HostComponentResourceProvider.HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID));
+    }
+    // Make sure that all of the response objects got moved into resources
+    for (ServiceComponentHostResponse response : allResponse ) {
+      Assert.assertTrue(names.contains(response.getComponentName()));
+    }
+
+    // verify
+    verify(managementController);
+  }
+
+  @Test
+  public void testUpdateResources() throws Exception {
+    Resource.Type type = Resource.Type.HostComponent;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    Set<ServiceComponentHostResponse> nameResponse = new HashSet<ServiceComponentHostResponse>();
+    nameResponse.add(new ServiceComponentHostResponse(
+        "Cluster102", "Service100", "Component100", "Host100", null, null, "STARTED", "", ""));
+
+    // set expectations
+    expect(managementController.getHostComponents(
+        EasyMock.<Set<ServiceComponentHostRequest>>anyObject())).andReturn(nameResponse).once();
+    expect(managementController.updateHostComponents(
+        AbstractResourceProviderTest.Matcher.getHostComponentRequestSet(
+            "Cluster102", null, "Component100", "Host100", null, "STARTED"))).andReturn(response).once();
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    properties.put(HostComponentResourceProvider.HOST_COMPONENT_STATE_PROPERTY_ID, "STARTED");
+
+    // create the request
+    Request request = PropertyHelper.getUpdateRequest(properties);
+
+    // update the cluster named Cluster102
+    Predicate predicate = new PredicateBuilder().property(
+        HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID).equals("Cluster102").toPredicate();
+    provider.updateResources(request, predicate);
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testDeleteResources() throws Exception {
+    Resource.Type type = Resource.Type.HostComponent;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // set expectations
+    expect(managementController.deleteHostComponents(
+        AbstractResourceProviderTest.Matcher.getHostComponentRequestSet(
+            null, null, "Component100", "Host100", null, null))).andReturn(response);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    AbstractResourceProviderTest.TestObserver observer = new AbstractResourceProviderTest.TestObserver();
+
+    ((ObservableResourceProvider)provider).addObserver(observer);
+
+    Predicate predicate = new PredicateBuilder().
+        property(HostComponentResourceProvider.HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID).equals("Component100").and().
+        property(HostComponentResourceProvider.HOST_COMPONENT_HOST_NAME_PROPERTY_ID).equals("Host100").toPredicate();
+    provider.deleteResources(predicate);
+
+
+    ResourceProviderEvent lastEvent = observer.getLastEvent();
+    Assert.assertNotNull(lastEvent);
+    Assert.assertEquals(Resource.Type.HostComponent, lastEvent.getResourceType());
+    Assert.assertEquals(ResourceProviderEvent.Type.Delete, lastEvent.getType());
+    Assert.assertEquals(predicate, lastEvent.getPredicate());
+    Assert.assertNull(lastEvent.getRequest());
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testCheckPropertyIds() throws Exception {
+    Set<String> propertyIds = new HashSet<String>();
+    propertyIds.add("foo");
+    propertyIds.add("cat1/foo");
+    propertyIds.add("cat2/bar");
+    propertyIds.add("cat2/baz");
+    propertyIds.add("cat3/sub1/bam");
+    propertyIds.add("cat4/sub2/sub3/bat");
+    propertyIds.add("cat5/subcat5/map");
+
+    Map<Resource.Type, String> keyPropertyIds = new HashMap<Resource.Type, String>();
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    AbstractResourceProvider provider =
+        (AbstractResourceProvider) AbstractResourceProvider.getResourceProvider(
+            Resource.Type.HostComponent,
+            propertyIds,
+            keyPropertyIds,
+            managementController);
+
+    Set<String> unsupported = provider.checkPropertyIds(Collections.singleton("foo"));
+    Assert.assertTrue(unsupported.isEmpty());
+
+    // note that key is not in the set of known property ids.  We allow it if its parent is a known property.
+    // this allows for Map type properties where we want to treat the entries as individual properties
+    Assert.assertTrue(provider.checkPropertyIds(Collections.singleton("cat5/subcat5/map/key")).isEmpty());
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("bar"));
+    Assert.assertEquals(1, unsupported.size());
+    Assert.assertTrue(unsupported.contains("bar"));
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("cat1/foo"));
+    Assert.assertTrue(unsupported.isEmpty());
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("cat1"));
+    Assert.assertTrue(unsupported.isEmpty());
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("config"));
+    Assert.assertTrue(unsupported.isEmpty());
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("config/unknown_property"));
+    Assert.assertTrue(unsupported.isEmpty());
+  }
+}

+ 234 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostResourceProviderTest.java

@@ -0,0 +1,234 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.HostRequest;
+import org.apache.ambari.server.controller.HostResponse;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.state.HostHealthStatus;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * HostResourceProvider tests.
+ */
+public class HostResourceProviderTest {
+  @Test
+  public void testCreateResources() throws Exception {
+    Resource.Type type = Resource.Type.Host;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    managementController.createHosts(
+        AbstractResourceProviderTest.Matcher.getHostRequestSet("Host100", "Cluster100", null));
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.  add more maps for multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // add properties to the request map
+    properties.put(HostResourceProvider.HOST_CLUSTER_NAME_PROPERTY_ID, "Cluster100");
+    properties.put(HostResourceProvider.HOST_NAME_PROPERTY_ID, "Host100");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet);
+
+    provider.createResources(request);
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testGetResources() throws Exception {
+    Resource.Type type = Resource.Type.Host;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    Set<HostResponse> allResponse = new HashSet<HostResponse>();
+    allResponse.add(new HostResponse("Host100", "Cluster100",
+        "", "", 2, "", "", "", 100000L, 200000L, null, 10L,
+        0L, "rack info", null, null,
+        new HostHealthStatus(HostHealthStatus.HealthStatus.HEALTHY, "HEALTHY"), "HEALTHY"));
+    allResponse.add(new HostResponse("Host101", "Cluster100",
+        "", "", 2, "", "", "", 100000L, 200000L, null, 10L,
+        0L, "rack info", null, null,
+        new HostHealthStatus(HostHealthStatus.HealthStatus.HEALTHY, "HEALTHY"), "HEALTHY"));
+    allResponse.add(new HostResponse("Host102", "Cluster100",
+        "", "", 2, "", "", "", 100000L, 200000L, null, 10L,
+        0L, "rack info", null, null,
+        new HostHealthStatus(HostHealthStatus.HealthStatus.HEALTHY, "HEALTHY"), "HEALTHY"));
+
+    // set expectations
+    expect(managementController.getHosts(
+        AbstractResourceProviderTest.Matcher.getHostRequestSet(null, "Cluster100", null))).
+        andReturn(allResponse).once();
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    propertyIds.add(HostResourceProvider.HOST_CLUSTER_NAME_PROPERTY_ID);
+    propertyIds.add(HostResourceProvider.HOST_NAME_PROPERTY_ID);
+
+    Predicate predicate =
+        new PredicateBuilder().property(HostResourceProvider.HOST_CLUSTER_NAME_PROPERTY_ID).equals("Cluster100").
+            toPredicate();
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+    Set<Resource> resources = provider.getResources(request, predicate);
+
+    Assert.assertEquals(3, resources.size());
+    Set<String> names = new HashSet<String>();
+    for (Resource resource : resources) {
+      String clusterName = (String) resource.getPropertyValue(HostResourceProvider.HOST_CLUSTER_NAME_PROPERTY_ID);
+      Assert.assertEquals("Cluster100", clusterName);
+      names.add((String) resource.getPropertyValue(HostResourceProvider.HOST_NAME_PROPERTY_ID));
+    }
+    // Make sure that all of the response objects got moved into resources
+    for (HostResponse response : allResponse ) {
+      Assert.assertTrue(names.contains(response.getHostname()));
+    }
+
+    // verify
+    verify(managementController);
+  }
+
+  @Test
+  public void testUpdateResources() throws Exception {
+    Resource.Type type = Resource.Type.Host;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    Set<HostResponse> hostResponseSet = new HashSet<HostResponse>();
+    hostResponseSet.add(new HostResponse("Host100", "Cluster100",
+        "", "", 2, "", "", "", 100000L, 200000L, null, 10L,
+        0L, "rack info", null, null,
+        new HostHealthStatus(HostHealthStatus.HealthStatus.HEALTHY, "HEALTHY"), "HEALTHY"));
+
+    // set expectations
+    expect(managementController.getHosts(
+        AbstractResourceProviderTest.Matcher.getHostRequestSet("Host100", "Cluster100", null))).
+        andReturn(hostResponseSet);
+    managementController.updateHosts(EasyMock.<Set<HostRequest>>anyObject());
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    properties.put(HostResourceProvider.HOST_RACK_INFO_PROPERTY_ID, "rack info");
+
+    // create the request
+    Request request = PropertyHelper.getUpdateRequest(properties);
+
+    Predicate  predicate = new PredicateBuilder().property(HostResourceProvider.HOST_CLUSTER_NAME_PROPERTY_ID).
+        equals("Cluster100").
+        and().property(HostResourceProvider.HOST_NAME_PROPERTY_ID).equals("Host100").toPredicate();
+    provider.updateResources(request, predicate);
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testDeleteResources() throws Exception {
+    Resource.Type type = Resource.Type.Host;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    // set expectations
+    managementController.deleteHosts(AbstractResourceProviderTest.Matcher.getHostRequestSet("Host100", null, null));
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    AbstractResourceProviderTest.TestObserver observer = new AbstractResourceProviderTest.TestObserver();
+
+    ((ObservableResourceProvider)provider).addObserver(observer);
+
+    Predicate predicate = new PredicateBuilder().property(HostResourceProvider.HOST_NAME_PROPERTY_ID).equals("Host100").
+        toPredicate();
+    provider.deleteResources(predicate);
+
+
+    ResourceProviderEvent lastEvent = observer.getLastEvent();
+    Assert.assertNotNull(lastEvent);
+    Assert.assertEquals(Resource.Type.Host, lastEvent.getResourceType());
+    Assert.assertEquals(ResourceProviderEvent.Type.Delete, lastEvent.getType());
+    Assert.assertEquals(predicate, lastEvent.getPredicate());
+    Assert.assertNull(lastEvent.getRequest());
+
+    // verify
+    verify(managementController);
+  }
+}

+ 191 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java

@@ -0,0 +1,191 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * RequestResourceProvider tests.
+ */
+public class RequestResourceProviderTest {
+  @Test
+  public void testCreateResources() throws Exception {
+    Resource.Type type = Resource.Type.Request;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.  add more maps for multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // add properties to the request map
+    properties.put(RequestResourceProvider.REQUEST_ID_PROPERTY_ID, "Request100");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet);
+
+    try {
+      provider.createResources(request);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testGetResources() throws Exception {
+    Resource.Type type = Resource.Type.Request;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    Set<RequestStatusResponse> allResponse = new HashSet<RequestStatusResponse>();
+    allResponse.add(new RequestStatusResponse(100L));
+
+    // set expectations
+    expect(managementController.getRequestStatus(AbstractResourceProviderTest.Matcher.getRequestRequest(100L))).
+        andReturn(allResponse).once();
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    propertyIds.add(RequestResourceProvider.REQUEST_ID_PROPERTY_ID);
+
+    Predicate predicate = new PredicateBuilder().property(RequestResourceProvider.REQUEST_ID_PROPERTY_ID).equals("100").
+        toPredicate();
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+    Set<Resource> resources = provider.getResources(request, predicate);
+
+    Assert.assertEquals(1, resources.size());
+    for (Resource resource : resources) {
+      long userName = (Long) resource.getPropertyValue(RequestResourceProvider.REQUEST_ID_PROPERTY_ID);
+      Assert.assertEquals(100L, userName);
+    }
+
+    // verify
+    verify(managementController);  }
+
+  @Test
+  public void testUpdateResources() throws Exception {
+    Resource.Type type = Resource.Type.Request;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // create the request
+    Request request = PropertyHelper.getUpdateRequest(properties);
+
+    Predicate predicate = new PredicateBuilder().property(RequestResourceProvider.REQUEST_ID_PROPERTY_ID).
+        equals("Request100").toPredicate();
+
+    try {
+      provider.updateResources(request, predicate);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testDeleteResources() throws Exception {
+    Resource.Type type = Resource.Type.Request;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Predicate predicate = new PredicateBuilder().property(RequestResourceProvider.REQUEST_ID_PROPERTY_ID).
+        equals("Request100").toPredicate();
+    try {
+      provider.deleteResources(predicate);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController);
+  }
+}

+ 300 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ServiceResourceProviderTest.java

@@ -0,0 +1,300 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.ServiceRequest;
+import org.apache.ambari.server.controller.ServiceResponse;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * ServiceResourceProvider tests.
+ */
+public class ServiceResourceProviderTest {
+
+  @Test
+  public void testCreateResources() throws Exception{
+    Resource.Type type = Resource.Type.Service;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    managementController.createServices(AbstractResourceProviderTest.Matcher.getServiceRequestSet("Cluster100", "Service100", null, "DEPLOYED"));
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.  add more maps for multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+
+    // Service 1: create a map of properties for the request
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // add properties to the request map
+    properties.put(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID, "Cluster100");
+    properties.put(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID, "Service100");
+    properties.put(ServiceResourceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID, "DEPLOYED");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet);
+
+    provider.createResources(request);
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testGetResources() throws Exception{
+    Resource.Type type = Resource.Type.Service;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    Set<ServiceResponse> allResponse = new HashSet<ServiceResponse>();
+    allResponse.add(new ServiceResponse(100L, "Cluster100", "Service100", null, "HDP-0.1", "DEPLOYED"));
+    allResponse.add(new ServiceResponse(100L, "Cluster100", "Service101", null, "HDP-0.1", "DEPLOYED"));
+    allResponse.add(new ServiceResponse(100L, "Cluster100", "Service102", null, "HDP-0.1", "DEPLOYED"));
+    allResponse.add(new ServiceResponse(100L, "Cluster100", "Service103", null, "HDP-0.1", "DEPLOYED"));
+    allResponse.add(new ServiceResponse(100L, "Cluster100", "Service104", null, "HDP-0.1", "DEPLOYED"));
+
+    Set<ServiceResponse> nameResponse = new HashSet<ServiceResponse>();
+    nameResponse.add(new ServiceResponse(100L, "Cluster100", "Service102", null, "HDP-0.1", "DEPLOYED"));
+
+    Set<ServiceResponse> stateResponse = new HashSet<ServiceResponse>();
+    stateResponse.add(new ServiceResponse(100L, "Cluster100", "Service100", null, "HDP-0.1", "DEPLOYED"));
+    stateResponse.add(new ServiceResponse(100L, "Cluster100", "Service102", null, "HDP-0.1", "DEPLOYED"));
+    stateResponse.add(new ServiceResponse(100L, "Cluster100", "Service104", null, "HDP-0.1", "DEPLOYED"));
+
+    // set expectations
+    expect(managementController.getServices(EasyMock.<Set<ServiceRequest>>anyObject())).andReturn(allResponse).once();
+    expect(managementController.getServices(EasyMock.<Set<ServiceRequest>>anyObject())).andReturn(nameResponse).once();
+    expect(managementController.getServices(EasyMock.<Set<ServiceRequest>>anyObject())).andReturn(stateResponse).once();
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    propertyIds.add(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID);
+    propertyIds.add(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID);
+
+    // create the request
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+    // get all ... no predicate
+    Set<Resource> resources = provider.getResources(request, null);
+
+    Assert.assertEquals(5, resources.size());
+    Set<String> names = new HashSet<String>();
+    for (Resource resource : resources) {
+      String clusterName = (String) resource.getPropertyValue(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID);
+      Assert.assertEquals("Cluster100", clusterName);
+      names.add((String) resource.getPropertyValue(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID));
+    }
+    // Make sure that all of the response objects got moved into resources
+    for (ServiceResponse serviceResponse : allResponse ) {
+      Assert.assertTrue(names.contains(serviceResponse.getServiceName()));
+    }
+
+    // get service named Service102
+    Predicate predicate = new PredicateBuilder().property(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID).equals("Service102").toPredicate();
+    request = PropertyHelper.getReadRequest("ServiceInfo");
+    resources = provider.getResources(request, predicate);
+
+    Assert.assertEquals(1, resources.size());
+    Assert.assertEquals("Service102", resources.iterator().next().getPropertyValue(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID));
+
+    // get services where state == "DEPLOYED"
+    predicate = new PredicateBuilder().property(ServiceResourceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID).equals("DEPLOYED").toPredicate();
+    request = PropertyHelper.getReadRequest(propertyIds);
+    resources = provider.getResources(request, predicate);
+
+    Assert.assertEquals(3, resources.size());
+    names = new HashSet<String>();
+    for (Resource resource : resources) {
+      String clusterName = (String) resource.getPropertyValue(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID);
+      Assert.assertEquals("Cluster100", clusterName);
+      names.add((String) resource.getPropertyValue(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID));
+    }
+    // Make sure that all of the response objects got moved into resources
+    for (ServiceResponse serviceResponse : stateResponse ) {
+      Assert.assertTrue(names.contains(serviceResponse.getServiceName()));
+    }
+
+    // verify
+    verify(managementController);
+  }
+
+  @Test
+  public void testUpdateResources() throws Exception{
+    Resource.Type type = Resource.Type.Service;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // set expectations
+    expect(managementController.updateServices(EasyMock.<Set<ServiceRequest>>anyObject())).andReturn(response).once();
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    properties.put(ServiceResourceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID, "DEPLOYED");
+
+    // create the request
+    Request request = PropertyHelper.getUpdateRequest(properties);
+
+    // update the service named Service102
+    Predicate  predicate = new PredicateBuilder().property(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID).equals("Cluster100").
+        and().property(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID).equals("Service102").toPredicate();
+    provider.updateResources(request, predicate);
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testDeleteResources() throws Exception{
+    Resource.Type type = Resource.Type.Service;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // set expectations
+    expect(managementController.deleteServices(AbstractResourceProviderTest.Matcher.getServiceRequestSet(null, "Service100", null, null))).andReturn(response);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    AbstractResourceProviderTest.TestObserver observer = new AbstractResourceProviderTest.TestObserver();
+
+    ((ObservableResourceProvider)provider).addObserver(observer);
+
+    // delete the service named Service100
+    Predicate  predicate = new PredicateBuilder().property(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID).equals("Service100").toPredicate();
+    provider.deleteResources(predicate);
+
+
+    ResourceProviderEvent lastEvent = observer.getLastEvent();
+    Assert.assertNotNull(lastEvent);
+    Assert.assertEquals(Resource.Type.Service, lastEvent.getResourceType());
+    Assert.assertEquals(ResourceProviderEvent.Type.Delete, lastEvent.getType());
+    Assert.assertEquals(predicate, lastEvent.getPredicate());
+    Assert.assertNull(lastEvent.getRequest());
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testCheckPropertyIds() throws Exception {
+    Set<String> propertyIds = new HashSet<String>();
+    propertyIds.add("foo");
+    propertyIds.add("cat1/foo");
+    propertyIds.add("cat2/bar");
+    propertyIds.add("cat2/baz");
+    propertyIds.add("cat3/sub1/bam");
+    propertyIds.add("cat4/sub2/sub3/bat");
+    propertyIds.add("cat5/subcat5/map");
+
+    Map<Resource.Type, String> keyPropertyIds = new HashMap<Resource.Type, String>();
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    AbstractResourceProvider provider =
+        (AbstractResourceProvider) AbstractResourceProvider.getResourceProvider(
+            Resource.Type.Service,
+            propertyIds,
+            keyPropertyIds,
+            managementController);
+
+    Set<String> unsupported = provider.checkPropertyIds(Collections.singleton("foo"));
+    Assert.assertTrue(unsupported.isEmpty());
+
+    // note that key is not in the set of known property ids.  We allow it if its parent is a known property.
+    // this allows for Map type properties where we want to treat the entries as individual properties
+    Assert.assertTrue(provider.checkPropertyIds(Collections.singleton("cat5/subcat5/map/key")).isEmpty());
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("bar"));
+    Assert.assertEquals(1, unsupported.size());
+    Assert.assertTrue(unsupported.contains("bar"));
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("cat1/foo"));
+    Assert.assertTrue(unsupported.isEmpty());
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("cat1"));
+    Assert.assertTrue(unsupported.isEmpty());
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("config"));
+    Assert.assertTrue(unsupported.isEmpty());
+
+    unsupported = provider.checkPropertyIds(Collections.singleton("config/unknown_property"));
+    Assert.assertTrue(unsupported.isEmpty());
+  }
+}

+ 195 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/TaskResourceProviderTest.java

@@ -0,0 +1,195 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.TaskStatusResponse;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * TaskResourceProvider tests.
+ */
+public class TaskResourceProviderTest {
+  @Test
+  public void testCreateResources() throws Exception {
+    Resource.Type type = Resource.Type.Task;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.  add more maps for multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // add properties to the request map
+    properties.put(TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID, 100);
+    properties.put(TaskResourceProvider.TASK_ID_PROPERTY_ID, 100);
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet);
+
+    try {
+      provider.createResources(request);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testGetResources() throws Exception {
+    Resource.Type type = Resource.Type.Task;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    Set<TaskStatusResponse> allResponse = new HashSet<TaskStatusResponse>();
+    allResponse.add(new TaskStatusResponse(100L, 100, 100L, "HostName100", "", "", "", 0, "", "", 0L, (short) 0));
+
+    // set expectations
+    expect(managementController.getTaskStatus(AbstractResourceProviderTest.Matcher.getTaskRequestSet(100L, 100L))).
+        andReturn(allResponse).once();
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    propertyIds.add(TaskResourceProvider.TASK_ID_PROPERTY_ID);
+    propertyIds.add(TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID);
+
+    Predicate predicate = new PredicateBuilder().property(TaskResourceProvider.TASK_ID_PROPERTY_ID).equals("100").
+                          and().property(TaskResourceProvider.TASK_REQUEST_ID_PROPERTY_ID).equals("100").toPredicate();
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+    Set<Resource> resources = provider.getResources(request, predicate);
+
+    Assert.assertEquals(1, resources.size());
+    for (Resource resource : resources) {
+      long taskId = (Long) resource.getPropertyValue(TaskResourceProvider.TASK_ID_PROPERTY_ID);
+      Assert.assertEquals(100L, taskId);
+    }
+
+    // verify
+    verify(managementController);
+  }
+
+  @Test
+  public void testUpdateResources() throws Exception {
+    Resource.Type type = Resource.Type.Task;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // create the request
+    Request request = PropertyHelper.getUpdateRequest(properties);
+
+    Predicate predicate = new PredicateBuilder().property(TaskResourceProvider.TASK_ID_PROPERTY_ID).equals("Task100").
+        toPredicate();
+
+    try {
+      provider.updateResources(request, predicate);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testDeleteResources() throws Exception {
+    Resource.Type type = Resource.Type.Task;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Predicate predicate = new PredicateBuilder().property(TaskResourceProvider.TASK_ID_PROPERTY_ID).equals("Task100").
+        toPredicate();
+    try {
+      provider.deleteResources(predicate);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController);
+  }
+}

+ 191 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderTest.java

@@ -0,0 +1,191 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.UserRequest;
+import org.apache.ambari.server.controller.UserResponse;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * UserResourceProvider tests.
+ */
+public class UserResourceProviderTest {
+  @Test
+  public void testCreateResources() throws Exception {
+    Resource.Type type = Resource.Type.User;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    managementController.createUsers(AbstractResourceProviderTest.Matcher.getUserRequestSet("User100"));
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.  add more maps for multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // add properties to the request map
+    properties.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "User100");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet);
+
+    provider.createResources(request);
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testGetResources() throws Exception {
+    Resource.Type type = Resource.Type.User;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    Set<UserResponse> allResponse = new HashSet<UserResponse>();
+    allResponse.add(new UserResponse("User100", false));
+
+    // set expectations
+    expect(managementController.getUsers(AbstractResourceProviderTest.Matcher.getUserRequestSet("User100"))).
+        andReturn(allResponse).once();
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Set<String> propertyIds = new HashSet<String>();
+
+    propertyIds.add(UserResourceProvider.USER_USERNAME_PROPERTY_ID);
+    propertyIds.add(UserResourceProvider.USER_PASSWORD_PROPERTY_ID);
+
+    Predicate predicate = new PredicateBuilder().property(UserResourceProvider.USER_USERNAME_PROPERTY_ID).
+        equals("User100").toPredicate();
+    Request request = PropertyHelper.getReadRequest(propertyIds);
+    Set<Resource> resources = provider.getResources(request, predicate);
+
+    Assert.assertEquals(1, resources.size());
+    for (Resource resource : resources) {
+      String userName = (String) resource.getPropertyValue(UserResourceProvider.USER_USERNAME_PROPERTY_ID);
+      Assert.assertEquals("User100", userName);
+    }
+
+    // verify
+    verify(managementController);
+  }
+
+  @Test
+  public void testUpdateResources() throws Exception {
+    Resource.Type type = Resource.Type.User;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // set expectations
+    managementController.updateUsers(EasyMock.<Set<UserRequest>>anyObject());
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    properties.put(UserResourceProvider.USER_PASSWORD_PROPERTY_ID, "password");
+
+    // create the request
+    Request request = PropertyHelper.getUpdateRequest(properties);
+
+    Predicate  predicate = new PredicateBuilder().property(UserResourceProvider.USER_USERNAME_PROPERTY_ID).
+        equals("User100").toPredicate();
+    provider.updateResources(request, predicate);
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testDeleteResources() throws Exception {
+    Resource.Type type = Resource.Type.User;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // set expectations
+    managementController.deleteUsers(AbstractResourceProviderTest.Matcher.getUserRequestSet("User100"));
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Predicate predicate = new PredicateBuilder().property(UserResourceProvider.USER_USERNAME_PROPERTY_ID).
+        equals("User100").toPredicate();
+    provider.deleteResources(predicate);
+
+    // verify
+    verify(managementController, response);
+  }
+}