You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by od...@apache.org on 2013/08/30 14:01:44 UTC

[2/2] git commit: AMBARI-2699. API to expose Ambari Server resource. (odiachenko)

AMBARI-2699. API to expose Ambari Server resource. (odiachenko)


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

Branch: refs/heads/trunk
Commit: 8f5b66286be8bf350e9a507edb9e525985499f9c
Parents: bcf4470
Author: Oleksandr Diachenko <od...@hortonworks.com>
Authored: Thu Aug 29 18:45:32 2013 +0300
Committer: Oleksandr Diachenko <od...@hortonworks.com>
Committed: Fri Aug 30 14:56:47 2013 +0300

----------------------------------------------------------------------
 .../resources/ResourceInstanceFactoryImpl.java  |  12 ++
 .../RootServiceComponentResourceDefinition.java |  53 ++++++
 ...tServiceHostComponentResourceDefinition.java |  76 ++++++++
 .../RootServiceResourceDefinition.java          |  56 ++++++
 .../server/api/services/RootServiceService.java | 164 ++++++++++++++++
 .../server/configuration/Configuration.java     |   6 +-
 .../AbstractRootServiceResponseFactory.java     |  63 +++++++
 .../controller/AmbariManagementController.java  |  34 ++++
 .../AmbariManagementControllerImpl.java         |  78 +++++++-
 .../server/controller/ControllerModule.java     |   1 +
 .../controller/RootServiceComponentRequest.java |  39 ++++
 .../RootServiceComponentResponse.java           |  74 ++++++++
 .../RootServiceHostComponentRequest.java        |  37 ++++
 .../RootServiceHostComponentResponse.java       | 105 +++++++++++
 .../server/controller/RootServiceRequest.java   |  37 ++++
 .../server/controller/RootServiceResponse.java  |  55 ++++++
 .../controller/RootServiceResponseFactory.java  | 188 +++++++++++++++++++
 .../AbstractControllerResourceProvider.java     |   6 +
 .../RootServiceComponentResourceProvider.java   | 110 +++++++++++
 ...ootServiceHostComponentResourceProvider.java | 121 ++++++++++++
 .../internal/RootServiceResourceProvider.java   |  96 ++++++++++
 .../ambari/server/controller/spi/Resource.java  |   5 +-
 .../src/main/resources/key_properties.json      |  13 ++
 .../src/main/resources/properties.json          |  15 ++
 .../api/services/RootServiceServiceTest.java    | 145 ++++++++++++++
 .../server/api/services/ServiceServiceTest.java |   2 +-
 .../AmbariManagementControllerTest.java         |  48 +++++
 .../RootServiceResponseFactoryTest.java         | 156 +++++++++++++++
 ...ootServiceComponentResourceProviderTest.java | 105 +++++++++++
 ...erviceHostComponentResourceProviderTest.java | 112 +++++++++++
 .../RootServiceResourceProviderTest.java        | 102 ++++++++++
 31 files changed, 2110 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
index 6b19e49..f3a53be 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
@@ -130,6 +130,18 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
       case TaskAttempt:
         resourceDefinition = new TaskAttemptResourceDefinition();
         break;
+        
+      case RootService:
+        resourceDefinition = new RootServiceResourceDefinition();
+        break;
+        
+      case RootServiceComponent:
+        resourceDefinition = new RootServiceComponentResourceDefinition();
+        break;
+        
+      case RootServiceHostComponent:
+        resourceDefinition = new RootServiceHostComponentResourceDefinition();
+        break;
 
       default:
         throw new IllegalArgumentException("Unsupported resource type: " + type);

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceComponentResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceComponentResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceComponentResourceDefinition.java
new file mode 100644
index 0000000..3f6b685
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceComponentResourceDefinition.java
@@ -0,0 +1,53 @@
+/**
+ * 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.api.resources;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+
+public class RootServiceComponentResourceDefinition extends
+    BaseResourceDefinition {
+
+  public RootServiceComponentResourceDefinition(Type resourceType) {
+    super(resourceType);
+  }
+
+  public RootServiceComponentResourceDefinition() {
+    super(Resource.Type.RootServiceComponent);
+  }
+
+  @Override
+  public String getPluralName() {
+    return "components";
+  }
+
+  @Override
+  public String getSingularName() {
+    return "component";
+  }
+  
+  @Override
+  public Set<SubResourceDefinition> getSubResourceDefinitions() {
+    return Collections.singleton(new SubResourceDefinition(
+        Resource.Type.RootServiceHostComponent, Collections.singleton(Resource.Type.Host), true));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceHostComponentResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceHostComponentResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceHostComponentResourceDefinition.java
new file mode 100644
index 0000000..b8252fa
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceHostComponentResourceDefinition.java
@@ -0,0 +1,76 @@
+/**
+ * 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.api.resources;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Schema;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
+
+public class RootServiceHostComponentResourceDefinition extends
+    BaseResourceDefinition {
+
+  public RootServiceHostComponentResourceDefinition(Type resourceType) {
+    super(resourceType);
+  }
+
+  public RootServiceHostComponentResourceDefinition() {
+    super(Resource.Type.RootServiceHostComponent);
+  }
+
+  @Override
+  public String getPluralName() {
+    return "hostComponents";
+  }
+
+  @Override
+  public String getSingularName() {
+    return "hostComponent";
+  }
+  
+  @Override
+  public List<PostProcessor> getPostProcessors() {
+    List<PostProcessor> listProcessors = new ArrayList<PostProcessor>();
+    listProcessors.add(new RootServiceHostComponentHrefProcessor());
+
+    return listProcessors;
+  }
+  
+  private class RootServiceHostComponentHrefProcessor extends BaseHrefPostProcessor {
+    @Override
+    public void process(Request request, TreeNode<Resource> resultNode, String href) {
+      Resource r = resultNode.getObject();
+      Schema schema = ClusterControllerHelper.getClusterController().getSchema(r.getType());
+      Object host = r.getPropertyValue(schema.getKeyPropertyId(Resource.Type.Host));
+      Object hostComponent = r.getPropertyValue(schema.getKeyPropertyId(r.getType()));
+
+      int idx = href.indexOf("services/") + "services/".length();
+      idx = href.indexOf("/", idx) + 1;
+
+      href = href.substring(0, idx) + "hosts/" + host + "/hostComponents/" + hostComponent;
+
+      resultNode.setProperty("href", href);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceResourceDefinition.java
new file mode 100644
index 0000000..b323d9d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/RootServiceResourceDefinition.java
@@ -0,0 +1,56 @@
+/**
+ * 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.api.resources;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+
+public class RootServiceResourceDefinition extends BaseResourceDefinition {
+
+  public RootServiceResourceDefinition(Type resourceType) {
+    super(resourceType);
+  }
+
+  public RootServiceResourceDefinition() {
+    super(Resource.Type.RootService);
+  }
+
+  @Override
+  public String getPluralName() {
+    return "rootServices";
+  }
+
+  @Override
+  public String getSingularName() {
+    return "rootService";
+  }
+  
+  @Override
+  public Set<SubResourceDefinition> getSubResourceDefinitions() {
+    
+    Set<SubResourceDefinition> setChildren = new HashSet<SubResourceDefinition>();
+    setChildren.add(new SubResourceDefinition(Resource.Type.RootServiceComponent));
+
+    return setChildren;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceService.java
new file mode 100644
index 0000000..34ebc15
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceService.java
@@ -0,0 +1,164 @@
+/**
+ * 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.api.services;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+
+@Path("/services/")
+public class RootServiceService extends BaseService {
+  
+  @GET
+  @Produces("text/plain")
+  public Response getServices(@Context HttpHeaders headers, @Context UriInfo ui) {
+
+    return handleRequest(headers, null, ui, Request.Type.GET,
+      createServiceResource(null));
+  }
+  
+  @GET
+  @Path("{serviceName}")
+  @Produces("text/plain")
+  public Response getService(@Context HttpHeaders headers, @Context UriInfo ui,
+      @PathParam("serviceName") String serviceName) {
+
+    return handleRequest(headers, null, ui, Request.Type.GET,
+      createServiceResource(serviceName));
+  }
+
+  @GET
+  @Path("{serviceName}/components/{componentName}/hostComponents")
+  @Produces("text/plain")
+  public Response getRootHostComponents(@Context HttpHeaders headers, @Context UriInfo ui,
+      @PathParam("serviceName") String serviceName,
+      @PathParam("componentName") String componentName) {
+
+    return handleRequest(headers, null, ui, Request.Type.GET,
+      createHostComponentResource(serviceName, null, componentName));
+  }
+  
+  
+  @GET
+  @Path("{serviceName}/hosts/")
+  @Produces("text/plain")
+  public Response getRootHosts(@Context HttpHeaders headers, @Context UriInfo ui) {
+
+    return handleRequest(headers, null, ui, Request.Type.GET,
+      createHostResource(null));
+  }
+  
+  @GET
+  @Path("{serviceName}/hosts/{hostName}")
+  @Produces("text/plain")
+  public Response getRootHost(@Context HttpHeaders headers, @Context UriInfo ui,
+      @PathParam("hostName") String hostName) {
+
+    return handleRequest(headers, null, ui, Request.Type.GET,
+      createHostResource(hostName));
+  }
+  
+  
+  protected ResourceInstance createHostResource(String hostName) {
+    return createResource(Resource.Type.Host, Collections.<Resource.Type, String>singletonMap(Resource.Type.Host, hostName));
+  }
+
+  
+  @GET
+  @Path("{serviceName}/hosts/{hostName}/hostComponents/")
+  @Produces("text/plain")
+  public Response getRootHostComponent(@Context HttpHeaders headers, @Context UriInfo ui,
+      @PathParam("serviceName") String serviceName,
+      @PathParam("hostName") String hostName) {
+
+    return handleRequest(headers, null, ui, Request.Type.GET,
+      createHostComponentResource(serviceName, hostName, null));
+  }
+  
+  @GET
+  @Path("{serviceName}/hosts/{hostName}/hostComponents/{hostComponent}")
+  @Produces("text/plain")
+  public Response getRootHostComponent(@Context HttpHeaders headers, @Context UriInfo ui,
+      @PathParam("serviceName") String serviceName,
+      @PathParam("hostName") String hostName,
+      @PathParam("hostComponent") String hostComponent) {
+
+    return handleRequest(headers, null, ui, Request.Type.GET,
+      createHostComponentResource(serviceName, hostName, hostComponent));
+  }
+  
+  
+  protected ResourceInstance createHostComponentResource(String serviceName, String hostName, String componentName) {
+    
+    Map<Resource.Type,String> mapIds = new HashMap<Resource.Type, String>();
+    mapIds.put(Resource.Type.RootService, serviceName);
+    mapIds.put(Resource.Type.Host, hostName);
+    mapIds.put(Resource.Type.RootServiceComponent, componentName);
+
+    return createResource(Resource.Type.RootServiceHostComponent, mapIds);
+  }
+
+  @GET
+  @Path("{serviceName}/components/")
+  @Produces("text/plain")
+  public Response getServiceComponents(@Context HttpHeaders headers, @Context UriInfo ui,
+      @PathParam("serviceName") String serviceName) {
+
+    return handleRequest(headers, null, ui, Request.Type.GET,
+      createServiceComponentResource(serviceName, null));
+  }
+  
+  @GET
+  @Path("{serviceName}/components/{componentName}")
+  @Produces("text/plain")
+  public Response getServiceComponent(@Context HttpHeaders headers, @Context UriInfo ui,
+      @PathParam("serviceName") String serviceName,
+      @PathParam("componentName") String componentName) {
+
+    return handleRequest(headers, null, ui, Request.Type.GET,
+        createServiceComponentResource(serviceName, componentName));
+  }
+  
+  protected ResourceInstance createServiceResource(String serviceName) {
+    return createResource(Resource.Type.RootService,
+        Collections.singletonMap(Resource.Type.RootService, serviceName));
+  }
+  
+  protected ResourceInstance createServiceComponentResource(String serviceName,
+      String componentName) {
+    
+    Map<Resource.Type,String> mapIds = new HashMap<Resource.Type, String>();
+    mapIds.put(Resource.Type.RootService, serviceName);
+    mapIds.put(Resource.Type.RootServiceComponent, componentName);
+
+    return createResource(Resource.Type.RootServiceComponent, mapIds);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index 18bbe19..2df5f11 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -36,7 +36,6 @@ import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
-import java.util.Set;
 import java.util.Map.Entry;
 
 
@@ -77,6 +76,7 @@ public class Configuration {
   public static final String METADETA_DIR_PATH = "metadata.path";
   public static final String SERVER_VERSION_FILE = "server.version.file";
   public static final String SERVER_VERSION_KEY = "version";
+  public static final String JAVA_HOME_KEY = "java.home";
 
   public static final String CLIENT_SECURITY_KEY = "client.security";
   public static final String CLIENT_API_PORT_KEY = "client.api.port";
@@ -200,6 +200,8 @@ public class Configuration {
   private static final String PASSPHRASE_ENV_DEFAULT = "AMBARI_PASSPHRASE";
   private static final String RESOURCES_DIR_DEFAULT =
       "/var/share/ambari/resources/";
+  
+  public static final String JAVA_HOME_DEFAULT = "/usr/jdk64/jdk1.6.0_31";
 
   private static final String  ANONYMOUS_AUDIT_NAME_KEY = "anonymous.audit.name";
       
@@ -305,6 +307,8 @@ public class Configuration {
       CLIENT_API_SSL_KEY_NAME_KEY, CLIENT_API_SSL_KEY_NAME_DEFAULT));
     configsMap.put(CLIENT_API_SSL_CRT_NAME_KEY, properties.getProperty(
       CLIENT_API_SSL_CRT_NAME_KEY, CLIENT_API_SSL_CRT_NAME_DEFAULT));
+    configsMap.put(JAVA_HOME_KEY, properties.getProperty(
+        JAVA_HOME_KEY, JAVA_HOME_DEFAULT));
 
     File passFile = new File(configsMap.get(SRVR_KSTR_DIR_KEY) + File.separator
         + configsMap.get(SRVR_CRT_PASS_FILE_KEY));

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/AbstractRootServiceResponseFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AbstractRootServiceResponseFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AbstractRootServiceResponseFactory.java
new file mode 100644
index 0000000..a45825d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AbstractRootServiceResponseFactory.java
@@ -0,0 +1,63 @@
+/**
+ * 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;
+
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+
+public abstract class AbstractRootServiceResponseFactory {
+
+  /**
+   * Get all root services.
+   * 
+   * @param request the root services 
+   * 
+   * @return a set of root services 
+   * 
+   * @throws  AmbariException if the resources cannot be read
+   */
+  public abstract Set<RootServiceResponse> getRootServices(RootServiceRequest request) throws AmbariException;
+  
+  /**
+   * Get all components of root services.
+   * 
+   * @param request the host components of root services
+   * 
+   * @return a set of components of root services
+   * 
+   * @throws  AmbariException if the resources cannot be read
+   */
+  public abstract Set<RootServiceComponentResponse> getRootServiceComponents(RootServiceComponentRequest request) throws AmbariException;
+  
+  /**
+   * Get all components of root services related to hosts.
+   * 
+   * @param request the host components of root services related to hosts
+   * @param hosts the list of hosts
+   * 
+   * 
+   * @return a set of components of root services related to hosts
+   * 
+   * @throws  AmbariException if the resources cannot be read
+   */
+  public abstract Set<RootServiceHostComponentResponse> getRootServiceHostComponent(RootServiceHostComponentRequest request,
+      Set<HostResponse> hosts) throws AmbariException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index 4d7a55e..553217f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -511,4 +511,38 @@ public interface AmbariManagementController {
    * @throws  AmbariException if the resources cannot be read
    */
   public Set<OperatingSystemResponse> getStackOperatingSystems(Set<OperatingSystemRequest> requests) throws AmbariException;
+
+  /**
+   * Get all top-level services of Ambari, not related to certain cluster.
+   * 
+   * @param requests the top-level services 
+   * 
+   * @return a set of top-level services 
+   * 
+   * @throws  AmbariException if the resources cannot be read
+   */
+  
+  public Set<RootServiceResponse> getRootServices(Set<RootServiceRequest> requests) throws AmbariException;
+  /**
+   * Get all components of top-level services of Ambari, not related to certain cluster.
+   * 
+   * @param requests the components of top-level services 
+   * 
+   * @return a set of components 
+   * 
+   * @throws  AmbariException if the resources cannot be read
+   */
+  public Set<RootServiceComponentResponse> getRootServiceComponents(Set<RootServiceComponentRequest> requests) throws AmbariException;
+
+  /**
+   * Get all hosts components of top-level services of Ambari, not related to certain cluster.
+   * 
+   * @param requests the host components of top-level services 
+   * 
+   * @return a set of host components 
+   * 
+   * @throws  AmbariException if the resources cannot be read
+   */
+  public Set<RootServiceHostComponentResponse> getRootServiceHostComponents(Set<RootServiceHostComponentRequest> requests) throws AmbariException;
 }
+  

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index c41f89c..49d353f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -145,6 +145,8 @@ public class AmbariManagementControllerImpl implements
   private HostsMap hostsMap;
   @Inject
   private Configuration configs;
+  @Inject
+  private AbstractRootServiceResponseFactory rootServiceResponseFactory;
 
   final private String masterHostname;
   final private Integer masterPort;
@@ -4624,5 +4626,79 @@ public class AmbariManagementControllerImpl implements
   private String getAuthName() {
     return AuthorizationHelper.getAuthenticatedName(configs.getAnonymousAuditName());
   }
-  
+
+  @Override
+  public Set<RootServiceResponse> getRootServices(
+      Set<RootServiceRequest> requests) throws AmbariException {
+    Set<RootServiceResponse> response = new HashSet<RootServiceResponse>();
+    for (RootServiceRequest request : requests) {
+      try {
+        response.addAll(getRootServices(request));
+      } catch (AmbariException e) {
+        if (requests.size() == 1) {
+          // only throw exception if 1 request.
+          // there will be > 1 request in case of OR predicate
+          throw e;
+        }
+      }
+    }
+    return response;
+  }
+
+  private Set<RootServiceResponse> getRootServices (RootServiceRequest request)
+      throws AmbariException{
+    Set<RootServiceResponse> response = this.rootServiceResponseFactory.getRootServices(request);
+    return response;
+  }
+
+  @Override
+  public Set<RootServiceComponentResponse> getRootServiceComponents(
+      Set<RootServiceComponentRequest> requests) throws AmbariException {
+    Set<RootServiceComponentResponse> response = new HashSet<RootServiceComponentResponse>();
+    for (RootServiceComponentRequest request : requests) {
+      try {
+        response.addAll(getRootServiceComponents(request));
+      } catch (AmbariException e) {
+        if (requests.size() == 1) {
+          // only throw exception if 1 request.
+          // there will be > 1 request in case of OR predicate
+          throw e;
+        }
+      }
+    }
+    return response;
+  }
+
+  private Set<RootServiceComponentResponse> getRootServiceComponents(
+      RootServiceComponentRequest request) throws AmbariException{
+    Set<RootServiceComponentResponse> response = this.rootServiceResponseFactory.getRootServiceComponents(request);
+    return response;
+  }
+
+  @Override
+  public Set<RootServiceHostComponentResponse> getRootServiceHostComponents(
+      Set<RootServiceHostComponentRequest> requests) throws AmbariException {
+    Set<RootServiceHostComponentResponse> response = new HashSet<RootServiceHostComponentResponse>();
+    for (RootServiceHostComponentRequest request : requests) {
+      try {
+        response.addAll(getRootServiceHostComponents(request));
+      } catch (AmbariException e) {
+        if (requests.size() == 1) {
+          // only throw exception if 1 request.
+          // there will be > 1 request in case of OR predicate
+          throw e;
+        }
+      }
+    }
+    return response;
+  }
+
+  private Set<RootServiceHostComponentResponse> getRootServiceHostComponents(RootServiceHostComponentRequest request) throws AmbariException{
+
+    //Get all hosts of all clusters
+    Set<HostResponse> hosts = getHosts(new HostRequest(request.getHostName(), null, null));
+    
+    Set<RootServiceHostComponentResponse> response = this.rootServiceResponseFactory.getRootServiceHostComponent(request, hosts);
+    return response;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 7479cc9..dea6a50 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -81,6 +81,7 @@ public class ControllerModule extends AbstractModule {
     bindConstant().annotatedWith(Names.named("actionTimeout")).to(600000L);
     bind(AmbariManagementController.class)
         .to(AmbariManagementControllerImpl.class);
+    bind(AbstractRootServiceResponseFactory.class).to(RootServiceResponseFactory.class);
     bind(HBaseMasterPortScanner.class).in(Singleton.class);
     bind(ServerActionManager.class).to(ServerActionManagerImpl.class);
   }

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceComponentRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceComponentRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceComponentRequest.java
new file mode 100644
index 0000000..4c55048
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceComponentRequest.java
@@ -0,0 +1,39 @@
+/**
+ * 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;
+
+
+public class RootServiceComponentRequest extends RootServiceRequest{
+
+  private String componentName;
+
+  public RootServiceComponentRequest(String serviceName, String componentName) {
+    super(serviceName);
+    this.componentName = componentName;
+  }
+
+  public String getComponentName() {
+    return componentName;
+  }
+
+  public void setComponentName(String componentName) {
+    this.componentName = componentName;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceComponentResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceComponentResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceComponentResponse.java
new file mode 100644
index 0000000..da25494
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceComponentResponse.java
@@ -0,0 +1,74 @@
+/**
+ * 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;
+
+import java.util.Map;
+
+public class RootServiceComponentResponse {
+
+  private String componentName;
+  private Map<String, String> properties;
+
+  public RootServiceComponentResponse(String componentName, Map<String, String> properties) {
+    this.componentName = componentName;
+    this.setProperties(properties);
+  }
+
+  public String getComponentName() {
+    return componentName;
+  }
+
+  public Map<String, String> getProperties() {
+    return properties;
+  }
+
+  public void setProperties(Map<String, String> properties) {
+    this.properties = properties;
+  }
+  
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    RootServiceComponentResponse that = (RootServiceComponentResponse) o;
+
+    if (componentName != null ?
+        !componentName.equals(that.componentName) : that.componentName != null) {
+      return false;
+    }
+    
+    if (properties != null ?
+        !properties.equals(that.properties) : that.properties != null) {
+      return false;
+    }
+    
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = 1;
+    result = 31 + (componentName != null ? componentName.hashCode() : 0);
+    return result;
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceHostComponentRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceHostComponentRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceHostComponentRequest.java
new file mode 100644
index 0000000..11c32ad
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceHostComponentRequest.java
@@ -0,0 +1,37 @@
+/**
+ * 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;
+
+public class RootServiceHostComponentRequest extends RootServiceComponentRequest{
+
+  private String hostName;
+
+  public RootServiceHostComponentRequest(String serviceName, String hostName, String componentName) {
+    super(serviceName, componentName);
+    this.hostName = hostName;
+  }
+  
+  public String getHostName() {
+    return hostName;
+  }
+
+  public void setHostName(String hostName) {
+    this.hostName = hostName;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceHostComponentResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceHostComponentResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceHostComponentResponse.java
new file mode 100644
index 0000000..9669289
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceHostComponentResponse.java
@@ -0,0 +1,105 @@
+/**
+ * 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;
+
+import java.util.Map;
+
+public class RootServiceHostComponentResponse {
+
+  private String hostName;
+  private String componentName;
+  private String componentState;
+  private Map<String, String> properties;
+
+  public RootServiceHostComponentResponse(String hostName, String componentName, String componentState,
+      Map<String, String> properties) {
+    this.hostName = hostName;
+    this.componentName = componentName;
+    this.componentState = componentState;
+    this.properties = properties;
+  }
+
+  public String getHostName() {
+    return hostName;
+  }
+
+  public String getComponentName() {
+    return componentName;
+  }
+
+  public void setComponentName(String componentName) {
+    this.componentName = componentName;
+  }
+
+  public Map<String, String> getProperties() {
+    return properties;
+  }
+
+  public void setProperties(Map<String, String> properties) {
+    this.properties = properties;
+  }
+  
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    RootServiceHostComponentResponse that = (RootServiceHostComponentResponse) o;
+
+    if (hostName != null ?
+        !hostName.equals(that.hostName) : that.hostName != null) {
+      return false;
+    }
+    
+    if (componentName != null ?
+        !componentName.equals(that.componentName) : that.componentName != null) {
+      return false;
+    }
+    
+    if (componentState != null ?
+        !componentState.equals(that.componentState) : that.componentState != null) {
+      return false;
+    }
+    
+    if (properties != null ?
+        !properties.equals(that.properties) : that.properties != null) {
+      return false;
+    }
+    
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = 1;
+    result = 31 + (hostName != null ? hostName.hashCode() : 0);
+    result = result + (componentName != null ? componentName.hashCode() : 0);
+    result = result + (componentState != null ? componentState.hashCode() : 0);
+    return result;
+  }
+
+  public String getComponentState() {
+    return componentState;
+  }
+
+  public void setComponentState(String componentState) {
+    this.componentState = componentState;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceRequest.java
new file mode 100644
index 0000000..879129d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceRequest.java
@@ -0,0 +1,37 @@
+/**
+ * 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;
+
+public class RootServiceRequest {
+  
+  private String serviceName;
+
+  public RootServiceRequest(String serviceName) {
+    this.serviceName = serviceName;
+  }
+
+  public String getServiceName() {
+    return serviceName;
+  }
+
+  public void setServiceName(String serviceName) {
+    this.serviceName = serviceName;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceResponse.java
new file mode 100644
index 0000000..736ffff
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceResponse.java
@@ -0,0 +1,55 @@
+/**
+ * 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;
+
+public class RootServiceResponse {
+
+  private String serviceName;
+
+  public RootServiceResponse(String serviceName) {
+    this.serviceName = serviceName;
+  }
+
+  public String getServiceName() {
+    return serviceName;
+  }
+  
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    RootServiceResponse that = (RootServiceResponse) o;
+
+    if (serviceName != null ?
+        !serviceName.equals(that.serviceName) : that.serviceName != null) {
+      return false;
+    }
+    
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = 1;
+    result = 31 + (serviceName != null ? serviceName.hashCode() : 0);
+    return result;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceResponseFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceResponseFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceResponseFactory.java
new file mode 100644
index 0000000..3c44127
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/RootServiceResponseFactory.java
@@ -0,0 +1,188 @@
+/**
+ * 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;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ObjectNotFoundException;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.utils.StageUtils;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.Predicate;
+import org.apache.commons.lang.ArrayUtils;
+
+import com.google.inject.Inject;
+
+public class RootServiceResponseFactory extends
+    AbstractRootServiceResponseFactory {
+
+  private static final String RUNNING_STATE = "RUNNING";
+  @Inject
+  private Configuration configs;
+  
+  @Override
+  public Set<RootServiceResponse> getRootServices(RootServiceRequest request) throws ObjectNotFoundException {
+    
+    Set<RootServiceResponse> response;
+    
+    String serviceName = null;
+    
+    if (request != null)
+      serviceName = request.getServiceName();
+
+    if (serviceName != null) {
+      Services service;
+      try {
+        service = Services.valueOf(serviceName);
+      }
+      catch (IllegalArgumentException ex) {
+        throw new ObjectNotFoundException("Root service name: " + serviceName);
+      }
+      
+      response = Collections.singleton(new RootServiceResponse(service.toString()));
+    } else {
+      response = new HashSet<RootServiceResponse>();
+      
+      for (Services service: Services.values())    
+        response.add(new RootServiceResponse(service.toString()));
+    }    
+    return response;
+  }
+  
+  @Override
+  public Set<RootServiceComponentResponse> getRootServiceComponents(
+      RootServiceComponentRequest request) throws ObjectNotFoundException {
+    Set<RootServiceComponentResponse> response = new HashSet<RootServiceComponentResponse>();
+    
+    String serviceName = request.getServiceName();
+    String componentName = request.getComponentName();
+    Services service;
+
+    try {
+      service = Services.valueOf(serviceName);
+    }
+    catch (IllegalArgumentException ex) {
+      throw new ObjectNotFoundException("Root service name: " + serviceName);
+    }
+    catch (NullPointerException np) {
+      throw new ObjectNotFoundException("Root service name: null");
+    }
+    
+    if (componentName != null) {
+      Components component;
+      try {
+        component = Components.valueOf(componentName);
+        if (!ArrayUtils.contains(service.getComponents(), component))
+          throw new ObjectNotFoundException("No component name: " + componentName + "in service: " + serviceName);
+      }
+      catch (IllegalArgumentException ex) {
+        throw new ObjectNotFoundException("Component name: " + componentName);
+      }
+      response = Collections.singleton(new RootServiceComponentResponse(component.toString(),
+                                       getComponentProperties(componentName)));
+    } else {
+    
+      for (Components component: service.getComponents())    
+        response.add(new RootServiceComponentResponse(component.toString(),
+                     getComponentProperties(component.name())));
+      }
+    return response;
+  }
+
+  private Map<String, String> getComponentProperties(String componentName){
+    
+    Map<String, String> response;
+    Components component = null;
+
+    if (componentName != null) {
+      component = Components.valueOf(componentName);
+      
+      switch (component) {
+      case AMBARI_SERVER:
+        response = configs.getConfigsMap();
+        break;
+
+      default:
+        response = Collections.emptyMap();
+      }
+    }
+    else
+      response = Collections.emptyMap();
+
+    return response;
+  }
+
+  
+  public enum Services {
+    AMBARI(Components.values());
+    private Components[] components;
+
+    Services(Components[] components) {
+      this.components = components;
+    }
+
+    public Components[] getComponents() {
+      return components;
+    }
+  }
+  
+  public enum Components {
+    AMBARI_SERVER, AMBARI_AGENT
+  }
+
+  @Override
+  public Set<RootServiceHostComponentResponse> getRootServiceHostComponent(RootServiceHostComponentRequest request, Set<HostResponse> hosts) throws AmbariException {
+    Set<RootServiceHostComponentResponse> response = new HashSet<RootServiceHostComponentResponse>();
+
+    Set<RootServiceComponentResponse> rootServiceComponents = 
+        getRootServiceComponents(new RootServiceComponentRequest(request.getServiceName(), request.getComponentName()));
+
+    //Cartesian product with hosts and components
+    for (RootServiceComponentResponse component : rootServiceComponents) {
+      
+      Set<HostResponse> filteredHosts = new HashSet<HostResponse>(hosts);      
+      
+      //Make some filtering of hosts if need
+      if (component.getComponentName().equals(Components.AMBARI_SERVER.name()))
+        CollectionUtils.filter(filteredHosts, new Predicate() {
+          @Override
+          public boolean evaluate(Object arg0) {
+            HostResponse hostResponse = (HostResponse) arg0;
+            return hostResponse.getHostname().equals(StageUtils.getHostName());
+          }
+        });
+      
+      for (HostResponse host : filteredHosts) {
+        
+        if (component.getComponentName().equals(Components.AMBARI_SERVER.name()))
+          response.add(new RootServiceHostComponentResponse(host.getHostname(), component.getComponentName(),
+            RUNNING_STATE, component.getProperties()));
+        else
+          response.add(new RootServiceHostComponentResponse(host.getHostname(), component.getComponentName(),
+            host.getHostState(), component.getProperties()));
+      }
+    }
+    
+    return response;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index cc1ce0d..1a5a38b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -119,6 +119,12 @@ public abstract class AbstractControllerResourceProvider extends AbstractResourc
         return new OperatingSystemResourceProvider(propertyIds, keyPropertyIds, managementController);
       case Repository:
         return new RepositoryResourceProvider(propertyIds, keyPropertyIds, managementController);
+      case RootService:
+        return new RootServiceResourceProvider(propertyIds, keyPropertyIds, managementController);
+      case RootServiceComponent:
+        return new RootServiceComponentResourceProvider(propertyIds, keyPropertyIds, managementController);
+      case RootServiceHostComponent:
+        return new RootServiceHostComponentResourceProvider(propertyIds, keyPropertyIds, managementController);
       default:
         throw new IllegalArgumentException("Unknown type " + type);
     }

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentResourceProvider.java
new file mode 100644
index 0000000..c90f65d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentResourceProvider.java
@@ -0,0 +1,110 @@
+/**
+ * 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 java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.RootServiceComponentRequest;
+import org.apache.ambari.server.controller.RootServiceComponentResponse;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+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.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+
+public class RootServiceComponentResourceProvider extends
+    ReadOnlyResourceProvider {
+  
+  public static final String SERVICE_NAME_PROPERTY_ID = PropertyHelper
+      .getPropertyId("RootServiceComponents", "service_name");
+  
+  public static final String COMPONENT_NAME_PROPERTY_ID = PropertyHelper
+      .getPropertyId("RootServiceComponents", "component_name");
+  
+  public static final String PROPERTIES_PROPERTY_ID = PropertyHelper
+      .getPropertyId("RootServiceComponents", "properties");
+  
+  private Set<String> pkPropertyIds = new HashSet<String>(
+      Arrays.asList(new String[] { SERVICE_NAME_PROPERTY_ID, COMPONENT_NAME_PROPERTY_ID }));
+
+  protected RootServiceComponentResourceProvider(Set<String> propertyIds,
+      Map<Type, String> keyPropertyIds,
+      AmbariManagementController managementController) {
+    super(propertyIds, keyPropertyIds, managementController);
+  }
+  
+  @Override
+  public Set<Resource> getResources(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException,
+      NoSuchResourceException, NoSuchParentResourceException {
+
+    final RootServiceComponentRequest rootServiceComponentRequest = getRequest(PredicateHelper
+        .getProperties(predicate));
+    Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+
+    Set<RootServiceComponentResponse> responses = getResources(new Command<Set<RootServiceComponentResponse>>() {
+      @Override
+      public Set<RootServiceComponentResponse> invoke() throws AmbariException {
+        return getManagementController().getRootServiceComponents(
+            Collections.singleton(rootServiceComponentRequest));
+      }
+    });
+
+    Set<Resource> resources = new HashSet<Resource>();
+
+    for (RootServiceComponentResponse response : responses) {
+      Resource resource = new ResourceImpl(Resource.Type.RootServiceComponent);
+
+      setResourceProperty(resource, SERVICE_NAME_PROPERTY_ID,
+          rootServiceComponentRequest.getServiceName(), requestedIds);
+      
+      setResourceProperty(resource, COMPONENT_NAME_PROPERTY_ID,
+          response.getComponentName(), requestedIds);
+      
+      setResourceProperty(resource, PROPERTIES_PROPERTY_ID,
+          response.getProperties(), requestedIds);
+
+      resources.add(resource);
+    }
+
+    return resources;
+  }
+
+  private RootServiceComponentRequest getRequest(Map<String, Object> properties) {
+    return new RootServiceComponentRequest((String) properties.get(SERVICE_NAME_PROPERTY_ID),
+                                           (String) properties.get(COMPONENT_NAME_PROPERTY_ID));
+  }
+
+  @Override
+  protected Set<String> getPKPropertyIds() {
+    return pkPropertyIds;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceHostComponentResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceHostComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceHostComponentResourceProvider.java
new file mode 100644
index 0000000..e76dc96
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceHostComponentResourceProvider.java
@@ -0,0 +1,121 @@
+/**
+ * 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 java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.RootServiceHostComponentRequest;
+import org.apache.ambari.server.controller.RootServiceHostComponentResponse;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+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.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+
+public class RootServiceHostComponentResourceProvider extends
+    ReadOnlyResourceProvider {
+  
+  public static final String SERVICE_NAME_PROPERTY_ID = PropertyHelper
+      .getPropertyId("RootServiceHostComponents", "service_name");
+  public static final String HOST_NAME_PROPERTY_ID = PropertyHelper
+      .getPropertyId("RootServiceHostComponents", "host_name");
+  public static final String COMPONENT_NAME_PROPERTY_ID = PropertyHelper
+      .getPropertyId("RootServiceHostComponents", "component_name");
+  public static final String COMPONENT_STATE_PROPERTY_ID = PropertyHelper
+      .getPropertyId("RootServiceHostComponents", "component_state");
+  public static final String PROPERTIES_PROPERTY_ID = PropertyHelper
+      .getPropertyId("RootServiceHostComponents", "properties");
+  
+  
+  private Set<String> pkPropertyIds = new HashSet<String>(
+      Arrays.asList(new String[] { SERVICE_NAME_PROPERTY_ID, HOST_NAME_PROPERTY_ID, COMPONENT_NAME_PROPERTY_ID }));
+
+
+  public RootServiceHostComponentResourceProvider(Set<String> propertyIds,
+      Map<Type, String> keyPropertyIds,
+      AmbariManagementController managementController) {
+    super(propertyIds, keyPropertyIds, managementController);
+  }
+
+  
+  @Override
+  public Set<Resource> getResources(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException,
+      NoSuchResourceException, NoSuchParentResourceException {
+
+    final RootServiceHostComponentRequest rootServiceComponentRequest = getRequest(PredicateHelper.getProperties(predicate));
+    Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+
+    Set<RootServiceHostComponentResponse> responses = getResources(new Command<Set<RootServiceHostComponentResponse>>() {
+      @Override
+      public Set<RootServiceHostComponentResponse> invoke() throws AmbariException {
+        return getManagementController().getRootServiceHostComponents(
+            Collections.singleton(rootServiceComponentRequest));
+      }
+    });
+
+    Set<Resource> resources = new HashSet<Resource>();
+
+    for (RootServiceHostComponentResponse response : responses) {
+      Resource resource = new ResourceImpl(Resource.Type.RootServiceHostComponent);
+
+      setResourceProperty(resource, SERVICE_NAME_PROPERTY_ID,
+          rootServiceComponentRequest.getServiceName(), requestedIds);
+      
+      setResourceProperty(resource, HOST_NAME_PROPERTY_ID,
+          response.getHostName(), requestedIds);
+      
+      setResourceProperty(resource, COMPONENT_NAME_PROPERTY_ID,
+          response.getComponentName(), requestedIds);
+      
+      setResourceProperty(resource, COMPONENT_STATE_PROPERTY_ID,
+          response.getComponentState(), requestedIds);
+      
+      setResourceProperty(resource, PROPERTIES_PROPERTY_ID,
+          response.getProperties(), requestedIds);
+
+      resources.add(resource);
+    }
+
+    return resources;
+  }
+  
+  private RootServiceHostComponentRequest getRequest(Map<String, Object> properties) {
+    return new RootServiceHostComponentRequest((String) properties.get(SERVICE_NAME_PROPERTY_ID),
+                                               (String) properties.get(HOST_NAME_PROPERTY_ID),
+                                               (String) properties.get(COMPONENT_NAME_PROPERTY_ID));
+  }
+
+  @Override
+  protected Set<String> getPKPropertyIds() {
+    return pkPropertyIds;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceResourceProvider.java
new file mode 100644
index 0000000..1dfde5a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceResourceProvider.java
@@ -0,0 +1,96 @@
+/**
+ * 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 java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.RootServiceRequest;
+import org.apache.ambari.server.controller.RootServiceResponse;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+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.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+
+public class RootServiceResourceProvider extends ReadOnlyResourceProvider {
+  
+  public static final String SERVICE_NAME_PROPERTY_ID = PropertyHelper
+      .getPropertyId("RootService", "service_name");
+
+  private Set<String> pkPropertyIds = new HashSet<String>(
+      Arrays.asList(new String[] { SERVICE_NAME_PROPERTY_ID }));
+
+  protected RootServiceResourceProvider(Set<String> propertyIds,
+      Map<Type, String> keyPropertyIds,
+      AmbariManagementController managementController) {
+    super(propertyIds, keyPropertyIds, managementController);
+  }
+  
+  @Override
+  public Set<Resource> getResources(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException,
+      NoSuchResourceException, NoSuchParentResourceException {
+
+    final RootServiceRequest ambariServiceRequest = getRequest(PredicateHelper
+        .getProperties(predicate));
+    Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+
+    Set<RootServiceResponse> responses = getResources(new Command<Set<RootServiceResponse>>() {
+      @Override
+      public Set<RootServiceResponse> invoke() throws AmbariException {
+        return getManagementController().getRootServices(
+            Collections.singleton(ambariServiceRequest));
+      }
+    });
+
+    Set<Resource> resources = new HashSet<Resource>();
+
+    for (RootServiceResponse response : responses) {
+      Resource resource = new ResourceImpl(Resource.Type.RootService);
+
+      setResourceProperty(resource, SERVICE_NAME_PROPERTY_ID,
+          response.getServiceName(), requestedIds);
+
+      resources.add(resource);
+    }
+
+    return resources;
+  }
+
+  private RootServiceRequest getRequest(Map<String, Object> properties) {
+    return new RootServiceRequest((String) properties.get(SERVICE_NAME_PROPERTY_ID));
+  }
+
+  @Override
+  protected Set<String> getPKPropertyIds() {
+    return pkPropertyIds ;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
index 8ead815..e45d59d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
@@ -92,6 +92,9 @@ public interface Resource {
     DRInstance,
     Workflow,
     Job,
-    TaskAttempt
+    TaskAttempt,
+    RootService,
+    RootServiceComponent,
+    RootServiceHostComponent
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/resources/key_properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/key_properties.json b/ambari-server/src/main/resources/key_properties.json
index cb9fdad..090feaa 100644
--- a/ambari-server/src/main/resources/key_properties.json
+++ b/ambari-server/src/main/resources/key_properties.json
@@ -87,5 +87,18 @@
   "DRInstance":{
     "DRFeed":"Instance/feedName",
     "DRInstance":"Instance/id"
+  },
+  "RootService":{
+    "RootService":"RootService/service_name"
+  },
+  "RootServiceComponent":{
+    "RootService":"RootServiceComponents/service_name",
+    "RootServiceComponent":"RootServiceComponents/component_name"
+  },
+  "RootServiceHostComponent":{
+    "RootService":"RootServiceHostComponents/service_name",
+    "Host":"RootServiceHostComponents/host_name",
+    "RootServiceComponent":"RootServiceHostComponents/component_name",
+    "RootServiceHostComponent":"RootServiceHostComponents/component_name"
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/properties.json b/ambari-server/src/main/resources/properties.json
index 028d448..a0aa464 100644
--- a/ambari-server/src/main/resources/properties.json
+++ b/ambari-server/src/main/resources/properties.json
@@ -238,5 +238,20 @@
         "TaskAttempt/output_bytes",
         "TaskAttempt/status",
         "TaskAttempt/locality"
+     ],
+     "RootService":[
+        "RootService/service_name"
+     ],
+    "RootServiceComponent":[
+        "RootServiceComponents/service_name",
+        "RootServiceComponents/component_name",
+        "RootServiceComponents/properties"
+     ],
+    "RootServiceHostComponent":[
+        "RootServiceHostComponents/service_name",
+        "RootServiceHostComponents/component_name",
+        "RootServiceHostComponents/host_name",
+        "RootServiceHostComponents/component_state",
+        "RootServiceHostComponents/properties"
      ]
 }

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/test/java/org/apache/ambari/server/api/services/RootServiceServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/RootServiceServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/RootServiceServiceTest.java
new file mode 100644
index 0000000..b2306b4
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/RootServiceServiceTest.java
@@ -0,0 +1,145 @@
+/**
+ * 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.api.services;
+
+import static org.junit.Assert.assertEquals;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.api.services.parsers.RequestBodyParser;
+import org.apache.ambari.server.api.services.serializers.ResultSerializer;
+
+/**
+* Unit tests for RootServiceService.
+*/
+public class RootServiceServiceTest extends BaseServiceTest {
+
+  @Override
+  public List<ServiceTestInvocation> getTestInvocations() throws Exception {
+    List<ServiceTestInvocation> listInvocations = new ArrayList<ServiceTestInvocation>();
+    
+    //getServices
+    RootServiceService service = new TestRootServiceService(null, null, null);
+    Method m = service.getClass().getMethod("getServices", HttpHeaders.class, UriInfo.class);
+    Object[] args = new Object[] {getHttpHeaders(), getUriInfo()};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
+    
+    //getService
+    service = new TestRootServiceService("AMBARI", null, null);
+    m = service.getClass().getMethod("getService", HttpHeaders.class, UriInfo.class, String.class);
+    args = new Object[] {getHttpHeaders(), getUriInfo(), "AMBARI"};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
+    
+    //getServiceComponents
+    service = new TestRootServiceService("AMBARI", null, null);
+    m = service.getClass().getMethod("getServiceComponents", HttpHeaders.class, UriInfo.class, String.class);
+    args = new Object[] {getHttpHeaders(), getUriInfo(), "AMBARI"};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
+    
+    //getServiceComponent
+    service = new TestRootServiceService("AMBARI", "AMBARI_SERVER", null);
+    m = service.getClass().getMethod("getServiceComponent", HttpHeaders.class, UriInfo.class, String.class, String.class);
+    args = new Object[] {getHttpHeaders(), getUriInfo(), "AMBARI", "AMBARI_SERVER"};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
+    
+    //getRootHostComponents
+    service = new TestRootServiceService("AMBARI", "AMBARI_SERVER", null);
+    m = service.getClass().getMethod("getRootHostComponents", HttpHeaders.class, UriInfo.class, String.class, String.class);
+    args = new Object[] {getHttpHeaders(), getUriInfo(), "AMBARI", "AMBARI_SERVER"};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
+    
+    //getRootHosts
+    service = new TestRootServiceService("AMBARI", "AMBARI_SERVER", null);
+    m = service.getClass().getMethod("getRootHosts", HttpHeaders.class, UriInfo.class);
+    args = new Object[] {getHttpHeaders(), getUriInfo()};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
+    
+    //getRootHost
+    service = new TestRootServiceService("AMBARI", "AMBARI_SERVER", "host1");
+    m = service.getClass().getMethod("getRootHost", HttpHeaders.class, UriInfo.class, String.class);
+    args = new Object[] {getHttpHeaders(), getUriInfo(), "host1"};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
+    
+    
+    return listInvocations;
+  }
+  
+  private class TestRootServiceService extends RootServiceService {
+
+    private String m_serviceName;
+    private String m_componentName;
+    private String m_hostName;
+
+    private TestRootServiceService(String serviceName, String componentName, String hostName) {
+      m_serviceName = serviceName;
+      m_componentName = componentName;
+      m_hostName = hostName;
+    }
+
+    @Override
+    protected ResourceInstance createServiceResource(String serviceName) {
+      assertEquals(m_serviceName, serviceName);
+      return getTestResource();
+    }
+    
+    @Override
+    protected ResourceInstance createServiceComponentResource(String serviceName, String componentName) {
+      assertEquals(m_serviceName, serviceName);
+      assertEquals(m_componentName, componentName);
+      return getTestResource();
+    }
+
+    @Override
+    protected ResourceInstance createHostComponentResource(String serviceName, String hostName, String componentName) {
+      assertEquals(m_serviceName, serviceName);
+      assertEquals(m_hostName, hostName);
+      assertEquals(m_componentName, componentName);
+      return getTestResource();
+    }
+    
+    @Override
+    protected ResourceInstance createHostResource(String hostName) {
+      assertEquals(m_hostName, hostName);
+      return getTestResource();
+    }
+    
+    
+    @Override
+    RequestFactory getRequestFactory() {
+      return getTestRequestFactory();
+    }
+
+    @Override
+    protected RequestBodyParser getBodyParser() {
+      return getTestBodyParser();
+    }
+
+    @Override
+    protected ResultSerializer getResultSerializer() {
+      return getTestResultSerializer();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/test/java/org/apache/ambari/server/api/services/ServiceServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/ServiceServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/ServiceServiceTest.java
index 05c8c06..ec92b4e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/ServiceServiceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/ServiceServiceTest.java
@@ -45,7 +45,7 @@ public class ServiceServiceTest extends BaseServiceTest {
     Object[] args = new Object[] {getHttpHeaders(), getUriInfo(), "serviceName"};
     listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
 
-    //getService
+    //getServices
     service = new TestServiceService("clusterName", null);
     m = service.getClass().getMethod("getServices", HttpHeaders.class, UriInfo.class);
     args = new Object[] {getHttpHeaders(), getUriInfo()};

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/8f5b6628/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index ea65794..b0e9801 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -122,6 +122,8 @@ public class AmbariManagementControllerTest {
   
   private static final String REQUEST_CONTEXT_PROPERTY = "context";
 
+  private static final int CONFIG_MAP_CNT = 21;
+
   private AmbariManagementController controller;
   private Clusters clusters;
   private ActionDBAccessor actionDB;
@@ -6989,4 +6991,50 @@ public class AmbariManagementControllerTest {
 
   }
   
+  @Test
+  public void testGetRootServices() throws Exception {
+
+    RootServiceRequest request = new RootServiceRequest(null);
+    Set<RootServiceResponse> responses = controller.getRootServices(Collections.singleton(request));
+    Assert.assertEquals(RootServiceResponseFactory.Services.values().length, responses.size());
+
+    RootServiceRequest requestWithParams = new RootServiceRequest(RootServiceResponseFactory.Services.AMBARI.toString());
+    Set<RootServiceResponse> responsesWithParams = controller.getRootServices(Collections.singleton(requestWithParams));
+    Assert.assertEquals(1, responsesWithParams.size());
+    for (RootServiceResponse responseWithParams: responsesWithParams) {
+      Assert.assertEquals(responseWithParams.getServiceName(), RootServiceResponseFactory.Services.AMBARI.toString());
+    }
+
+    RootServiceRequest invalidRequest = new RootServiceRequest(NON_EXT_VALUE);
+    try {
+      controller.getRootServices(Collections.singleton(invalidRequest));
+    } catch (ObjectNotFoundException e) {
+      Assert.assertTrue(e instanceof ObjectNotFoundException);
+    }
+  }
+  
+  @Test
+  public void testGetRootServiceComponents() throws Exception {
+
+    RootServiceComponentRequest request = new RootServiceComponentRequest(RootServiceResponseFactory.Services.AMBARI.toString(), null);
+    Set<RootServiceComponentResponse> responses = controller.getRootServiceComponents(Collections.singleton(request));
+    Assert.assertEquals(RootServiceResponseFactory.Services.AMBARI.getComponents().length, responses.size());
+
+    RootServiceComponentRequest requestWithParams = new RootServiceComponentRequest(
+        RootServiceResponseFactory.Services.AMBARI.toString(),
+        RootServiceResponseFactory.Services.AMBARI.getComponents()[0].toString());
+    
+    Set<RootServiceComponentResponse> responsesWithParams = controller.getRootServiceComponents(Collections.singleton(requestWithParams));
+    Assert.assertEquals(1, responsesWithParams.size());
+    for (RootServiceComponentResponse responseWithParams: responsesWithParams) {
+      Assert.assertEquals(responseWithParams.getComponentName(), RootServiceResponseFactory.Services.AMBARI.getComponents()[0].toString());
+    }
+
+    RootServiceComponentRequest invalidRequest = new RootServiceComponentRequest(NON_EXT_VALUE, NON_EXT_VALUE);
+    try {
+      controller.getRootServiceComponents(Collections.singleton(invalidRequest));
+    } catch (ObjectNotFoundException e) {
+      Assert.assertTrue(e instanceof ObjectNotFoundException);
+    }
+  }
 }