You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ma...@apache.org on 2012/09/23 20:01:54 UTC

svn commit: r1389109 [3/6] - in /incubator/ambari/branches/AMBARI-666: ./ ambari-api/ ambari-api/src/ ambari-api/src/main/ ambari-api/src/main/java/ ambari-api/src/main/java/org/ ambari-api/src/main/java/org/apache/ ambari-api/src/main/java/org/apache/...

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/QueryImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/QueryImpl.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/QueryImpl.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/query/QueryImpl.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,171 @@
+/**
+ * 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.api.query;
+
+import org.apache.ambari.api.controller.internal.PropertyIdImpl;
+import org.apache.ambari.api.controller.internal.RequestImpl;
+import org.apache.ambari.api.controller.predicate.AndPredicate;
+import org.apache.ambari.api.controller.predicate.BasePredicate;
+import org.apache.ambari.api.controller.predicate.EqualsPredicate;
+import org.apache.ambari.api.controller.utilities.ClusterControllerHelper;
+import org.apache.ambari.api.services.Result;
+import org.apache.ambari.api.services.ResultImpl;
+import org.apache.ambari.api.controller.spi.*;
+import org.apache.ambari.api.resource.ResourceDefinition;
+
+import java.util.*;
+
+/**
+ *
+ */
+public class QueryImpl implements Query {
+  ResourceDefinition m_resourceDefinition;
+  Predicate m_predicate;
+  private Map<String, Set<String>> m_mapProperties = new HashMap<String, Set<String>>();
+  private Map<ResourceDefinition, Query> m_mapSubQueries = new HashMap<ResourceDefinition, Query>();
+
+
+  public QueryImpl(ResourceDefinition resourceDefinition) {
+    m_resourceDefinition = resourceDefinition;
+  }
+
+  @Override
+  public Result execute() {
+    initialize();
+
+    Result result = createResult();
+    Iterable<Resource> iterResource = getClusterController().getResources(
+        m_resourceDefinition.getType(), createRequest(), m_predicate);
+
+    List<Resource> listResources = new ArrayList<Resource>();
+    for (Resource resource : iterResource) {
+      listResources.add(resource);
+    }
+    //todo: tree?
+    result.addResources("/", listResources);
+
+    for (Map.Entry<ResourceDefinition, Query> entry : m_mapSubQueries.entrySet()) {
+      Query query = entry.getValue();
+      ResourceDefinition resDef = entry.getKey();
+
+      //todo: this ensures that the sub query is only executed if needed.  Refactor.
+      if (m_mapProperties.isEmpty() || m_mapProperties.containsKey(resDef.getId() == null ?
+          resDef.getPluralName() : resDef.getSingularName())) {
+        Map<String, List<Resource>> mapSubResults = query.execute().getResources();
+        //todo: only getting sub-resource one level deep at this time
+        List<Resource> listSubResources = mapSubResults.get("/");
+        String subResourceName = resDef.getId() == null ? resDef.getPluralName() : resDef.getSingularName();
+        result.addResources(subResourceName, listSubResources);
+      }
+    }
+
+    return result;
+  }
+
+  //todo: refactor
+  public void initialize() {
+    m_predicate = createPredicate(m_resourceDefinition);
+
+    if (m_resourceDefinition.getId() != null) {
+      //sub-resource queries
+      for (ResourceDefinition resource : m_resourceDefinition.getChildren()) {
+        m_mapSubQueries.put(resource, resource.getQuery());
+      }
+      for (ResourceDefinition resource : m_resourceDefinition.getRelations()) {
+        m_mapSubQueries.put(resource, resource.getQuery());
+      }
+    }
+  }
+
+  @Override
+  public void addAllProperties(Map<String, Set<String>> mapProperties) {
+    m_mapProperties.putAll(mapProperties);
+  }
+
+  @Override
+  public void addProperty(String path, String property) {
+    Set<String> setProps = m_mapProperties.get(path);
+    if (setProps == null) {
+      setProps = new HashSet<String>();
+      m_mapProperties.put(path, setProps);
+    }
+    setProps.add(property);
+  }
+
+  @Override
+  public void addProperty(PropertyId property) {
+    addProperty(property.getCategory(), property.getName());
+  }
+
+  @Override
+  public void retainAllProperties(Set<String> setFields) {
+    //todo
+  }
+
+  @Override
+  public void clearAllProperties() {
+    m_mapProperties.clear();
+  }
+
+  private Predicate createPredicate(ResourceDefinition resourceDefinition) {
+    //todo: account for user predicates
+    Resource.Type resourceType = resourceDefinition.getType();
+    Map<Resource.Type, String> mapResourceIds = resourceDefinition.getResourceIds();
+    Schema schema = getClusterController().getSchema(resourceType);
+
+    BasePredicate[] predicates = new BasePredicate[mapResourceIds.size()];
+    int count = 0;
+    for (Map.Entry<Resource.Type, String> entry : mapResourceIds.entrySet()) {
+      predicates[count++] = new EqualsPredicate(schema.getKeyPropertyId(entry.getKey()), entry.getValue());
+    }
+
+    if (predicates.length == 1) {
+      return predicates[0];
+    } else if (predicates.length > 1) {
+      return new AndPredicate(predicates);
+    } else {
+      return null;
+    }
+  }
+
+  //todo: how to get Controller?
+  ClusterController getClusterController() {
+    return ClusterControllerHelper.getClusterController();
+  }
+
+  //todo
+  Request createRequest() {
+    Set<PropertyId> setProperties = new HashSet<PropertyId>();
+    //todo: convert property names to PropertyId's.
+    for (Map.Entry<String, Set<String>> entry : m_mapProperties.entrySet()) {
+      String group = entry.getKey();
+      for (String property : entry.getValue()) {
+        setProperties.add(new PropertyIdImpl(property, group, false));
+      }
+    }
+    return new RequestImpl(setProperties);
+  }
+
+  //todo
+  Result createResult() {
+    return new ResultImpl();
+  }
+
+
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/BaseResourceDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/BaseResourceDefinition.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/BaseResourceDefinition.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/BaseResourceDefinition.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,104 @@
+/**
+ * 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.api.resource;
+
+
+import org.apache.ambari.api.controller.utilities.ClusterControllerHelper;
+import org.apache.ambari.api.query.Query;
+import org.apache.ambari.api.query.QueryImpl;
+import org.apache.ambari.api.controller.spi.ClusterController;
+import org.apache.ambari.api.controller.spi.Resource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+public abstract class BaseResourceDefinition implements ResourceDefinition {
+
+  private Resource.Type m_type;
+  private String m_id;
+  private Query m_query = new QueryImpl(this);
+  Map<Resource.Type, String> m_mapResourceIds = new HashMap<Resource.Type, String>();
+
+  public BaseResourceDefinition(Resource.Type resourceType, String id) {
+    m_type = resourceType;
+    m_id = id;
+
+    if (id != null) {
+      setResourceId(resourceType, id);
+    }
+  }
+
+  @Override
+  public String getId() {
+    return m_id;
+  }
+
+  @Override
+  public Resource.Type getType() {
+    return m_type;
+  }
+
+
+  @Override
+  public Query getQuery() {
+    return m_query;
+  }
+
+  protected void setResourceId(Resource.Type resourceType, String val) {
+    //todo: hack for case where service id is null when getting a component from hostComponent
+    if (val != null) {
+      m_mapResourceIds.put(resourceType, val);
+    }
+  }
+
+  @Override
+  public Map<Resource.Type, String> getResourceIds() {
+    return m_mapResourceIds;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof BaseResourceDefinition)) return false;
+
+    BaseResourceDefinition that = (BaseResourceDefinition) o;
+
+    if (m_id != null ? !m_id.equals(that.m_id) : that.m_id != null) return false;
+    if (m_mapResourceIds != null ? !m_mapResourceIds.equals(that.m_mapResourceIds) : that.m_mapResourceIds != null)
+      return false;
+    if (m_type != that.m_type) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = m_type != null ? m_type.hashCode() : 0;
+    result = 31 * result + (m_id != null ? m_id.hashCode() : 0);
+    result = 31 * result + (m_mapResourceIds != null ? m_mapResourceIds.hashCode() : 0);
+    return result;
+  }
+
+  ClusterController getClusterController() {
+    return ClusterControllerHelper.getClusterController();
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ClusterResourceDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ClusterResourceDefinition.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ClusterResourceDefinition.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ClusterResourceDefinition.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,84 @@
+/**
+ * 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.api.resource;
+
+import org.apache.ambari.api.services.formatters.ClusterInstanceFormatter;
+import org.apache.ambari.api.services.formatters.CollectionFormatter;
+import org.apache.ambari.api.services.formatters.ResultFormatter;
+import org.apache.ambari.api.controller.spi.PropertyId;
+import org.apache.ambari.api.controller.spi.Resource;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ */
+public class ClusterResourceDefinition extends BaseResourceDefinition {
+
+  public ClusterResourceDefinition(String id) {
+    super(Resource.Type.Cluster, id);
+
+    if (id == null) {
+      getQuery().addProperty(getClusterController().getSchema(
+          Resource.Type.Cluster).getKeyPropertyId(Resource.Type.Cluster));
+    }
+  }
+
+  @Override
+  public String getPluralName() {
+    return "clusters";
+  }
+
+  @Override
+  public String getSingularName() {
+    return "cluster";
+  }
+
+  @Override
+  public Set<ResourceDefinition> getChildren() {
+    Set<ResourceDefinition> setChildren = new HashSet<ResourceDefinition>();
+
+    ServiceResourceDefinition serviceResource = new ServiceResourceDefinition(null, getId());
+    PropertyId serviceIdProperty = getClusterController().getSchema(
+        Resource.Type.Service).getKeyPropertyId(Resource.Type.Service);
+    serviceResource.getQuery().addProperty(serviceIdProperty);
+    setChildren.add(serviceResource);
+
+    HostResourceDefinition hostResource = new HostResourceDefinition(null, getId());
+    PropertyId hostIdProperty = getClusterController().getSchema(
+        Resource.Type.Host).getKeyPropertyId(Resource.Type.Host);
+    hostResource.getQuery().addProperty(hostIdProperty);
+    setChildren.add(hostResource);
+
+    return setChildren;
+  }
+
+  @Override
+  public Set<ResourceDefinition> getRelations() {
+    return Collections.emptySet();
+  }
+
+  @Override
+  public ResultFormatter getResultFormatter() {
+    //todo: instance formatter
+    return getId() == null ? new CollectionFormatter(this) : new ClusterInstanceFormatter(this);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ComponentResourceDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ComponentResourceDefinition.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ComponentResourceDefinition.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ComponentResourceDefinition.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,80 @@
+/**
+ * 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.api.resource;
+
+import org.apache.ambari.api.services.formatters.CollectionFormatter;
+import org.apache.ambari.api.services.formatters.ComponentInstanceFormatter;
+import org.apache.ambari.api.services.formatters.ResultFormatter;
+import org.apache.ambari.api.controller.spi.PropertyId;
+import org.apache.ambari.api.controller.spi.Resource;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ */
+public class ComponentResourceDefinition extends BaseResourceDefinition {
+
+  private String m_clusterId;
+  private String m_serviceId;
+
+  @Override
+  public String getPluralName() {
+    return "components";
+  }
+
+  @Override
+  public String getSingularName() {
+    return "component";
+  }
+
+  public ComponentResourceDefinition(String id, String clusterId, String serviceId) {
+    super(Resource.Type.Component, id);
+    m_clusterId = clusterId;
+    m_serviceId = serviceId;
+    setResourceId(Resource.Type.Cluster, m_clusterId);
+    setResourceId(Resource.Type.Service, m_serviceId);
+  }
+
+  @Override
+  public Set<ResourceDefinition> getChildren() {
+    return Collections.emptySet();
+  }
+
+  @Override
+  public Set<ResourceDefinition> getRelations() {
+    Set<ResourceDefinition> setResourceDefinitions = new HashSet<ResourceDefinition>();
+    // for host_component collection need host id property
+    HostComponentResourceDefinition hostComponentResource = new HostComponentResourceDefinition(
+        getId(), m_clusterId, null);
+    PropertyId hostIdProperty = getClusterController().getSchema(
+        Resource.Type.HostComponent).getKeyPropertyId(Resource.Type.Host);
+    hostComponentResource.getQuery().addProperty(hostIdProperty);
+    setResourceDefinitions.add(hostComponentResource);
+    return setResourceDefinitions;
+  }
+
+  @Override
+  public ResultFormatter getResultFormatter() {
+    //todo: instance formatter
+    return getId() == null ? new CollectionFormatter(this) : new ComponentInstanceFormatter(this);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/HostComponentResourceDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/HostComponentResourceDefinition.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/HostComponentResourceDefinition.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/HostComponentResourceDefinition.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,84 @@
+/**
+ * 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.api.resource;
+
+import org.apache.ambari.api.services.formatters.CollectionFormatter;
+import org.apache.ambari.api.services.formatters.HostComponentInstanceFormatter;
+import org.apache.ambari.api.services.formatters.ResultFormatter;
+import org.apache.ambari.api.controller.spi.PropertyId;
+import org.apache.ambari.api.controller.spi.Resource;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ */
+public class HostComponentResourceDefinition extends BaseResourceDefinition {
+
+  private String m_clusterId;
+  private String m_hostId;
+
+  @Override
+  public String getPluralName() {
+    return "host_components";
+  }
+
+  @Override
+  public String getSingularName() {
+    return "host_component";
+  }
+
+  public HostComponentResourceDefinition(String id, String clusterId, String hostId) {
+    super(Resource.Type.HostComponent, id);
+    m_clusterId = clusterId;
+    m_hostId = hostId;
+    setResourceId(Resource.Type.Cluster, m_clusterId);
+    setResourceId(Resource.Type.Host, m_hostId);
+  }
+
+  @Override
+  public Set<ResourceDefinition> getChildren() {
+    return Collections.emptySet();
+  }
+
+  @Override
+  public Set<ResourceDefinition> getRelations() {
+    Set<ResourceDefinition> setRelated = new HashSet<ResourceDefinition>();
+    // already have all information necessary for host
+    //todo: adding host here causes a cycle
+    //setRelated.add(new HostResourceDefinition(m_hostId, m_clusterId));
+    // for component need service id property
+    ComponentResourceDefinition componentResource = new ComponentResourceDefinition(
+        getId(), m_clusterId, null);
+    PropertyId serviceIdProperty = getClusterController().getSchema(
+        Resource.Type.Component).getKeyPropertyId(Resource.Type.Service);
+    componentResource.getQuery().addProperty(serviceIdProperty);
+    setRelated.add(componentResource);
+
+    return setRelated;
+  }
+
+  @Override
+  public ResultFormatter getResultFormatter() {
+    //todo: instance formatter
+    return getId() == null ? new CollectionFormatter(this) : new HostComponentInstanceFormatter(this);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/HostResourceDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/HostResourceDefinition.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/HostResourceDefinition.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/HostResourceDefinition.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,77 @@
+/**
+ * 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.api.resource;
+
+import org.apache.ambari.api.services.formatters.CollectionFormatter;
+import org.apache.ambari.api.services.formatters.HostInstanceFormatter;
+import org.apache.ambari.api.services.formatters.ResultFormatter;
+import org.apache.ambari.api.controller.spi.PropertyId;
+import org.apache.ambari.api.controller.spi.Resource;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ */
+public class HostResourceDefinition extends BaseResourceDefinition {
+
+  private String m_clusterId;
+
+  @Override
+  public String getPluralName() {
+    return "hosts";
+  }
+
+  @Override
+  public String getSingularName() {
+    return "host";
+  }
+
+  public HostResourceDefinition(String id, String clusterId) {
+    super(Resource.Type.Host, id);
+    m_clusterId = clusterId;
+    setResourceId(Resource.Type.Cluster, m_clusterId);
+  }
+
+  @Override
+  public Set<ResourceDefinition> getChildren() {
+    Set<ResourceDefinition> setChildren = new HashSet<ResourceDefinition>();
+
+    HostComponentResourceDefinition hostComponentResource = new HostComponentResourceDefinition(
+        null, m_clusterId, getId());
+    PropertyId hostComponentIdProperty = getClusterController().getSchema(
+        Resource.Type.HostComponent).getKeyPropertyId(Resource.Type.HostComponent);
+    hostComponentResource.getQuery().addProperty(hostComponentIdProperty);
+    setChildren.add(hostComponentResource);
+    return setChildren;
+  }
+
+  @Override
+  public Set<ResourceDefinition> getRelations() {
+    return Collections.emptySet();
+  }
+
+  @Override
+  public ResultFormatter getResultFormatter() {
+    //todo: instance formatter
+    return getId() == null ? new CollectionFormatter(this) : new HostInstanceFormatter(this);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ResourceDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ResourceDefinition.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ResourceDefinition.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ResourceDefinition.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,49 @@
+/**
+ * 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.api.resource;
+
+import org.apache.ambari.api.query.Query;
+import org.apache.ambari.api.services.formatters.ResultFormatter;
+import org.apache.ambari.api.controller.spi.Resource;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ */
+public interface ResourceDefinition {
+  public String getPluralName();
+
+  public String getSingularName();
+
+  public String getId();
+
+  public Set<ResourceDefinition> getChildren();
+
+  public Set<ResourceDefinition> getRelations();
+
+  public Map<Resource.Type, String> getResourceIds();
+
+  public ResultFormatter getResultFormatter();
+
+  public Resource.Type getType();
+
+  public Query getQuery();
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ServiceResourceDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ServiceResourceDefinition.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ServiceResourceDefinition.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/resource/ServiceResourceDefinition.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,77 @@
+/**
+ * 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.api.resource;
+
+import org.apache.ambari.api.services.formatters.CollectionFormatter;
+import org.apache.ambari.api.services.formatters.ResultFormatter;
+import org.apache.ambari.api.services.formatters.ServiceInstanceFormatter;
+import org.apache.ambari.api.controller.spi.PropertyId;
+import org.apache.ambari.api.controller.spi.Resource;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ */
+public class ServiceResourceDefinition extends BaseResourceDefinition {
+
+  private String m_clusterId;
+
+  @Override
+  public String getPluralName() {
+    return "services";
+  }
+
+  @Override
+  public String getSingularName() {
+    return "service";
+  }
+
+  public ServiceResourceDefinition(String id, String clusterId) {
+    super(Resource.Type.Service, id);
+    m_clusterId = clusterId;
+    setResourceId(Resource.Type.Cluster, m_clusterId);
+  }
+
+  @Override
+  public Set<ResourceDefinition> getChildren() {
+    Set<ResourceDefinition> setChildren = new HashSet<ResourceDefinition>();
+    // for component collection need id property
+    ComponentResourceDefinition componentResourceDefinition =
+        new ComponentResourceDefinition(null, m_clusterId, getId());
+    PropertyId componentIdProperty = getClusterController().getSchema(
+        Resource.Type.Component).getKeyPropertyId(Resource.Type.Component);
+    componentResourceDefinition.getQuery().addProperty(componentIdProperty);
+    setChildren.add(componentResourceDefinition);
+    return setChildren;
+  }
+
+  @Override
+  public Set<ResourceDefinition> getRelations() {
+    return Collections.emptySet();
+  }
+
+  @Override
+  public ResultFormatter getResultFormatter() {
+    //todo: instance formatter
+    return getId() == null ? new CollectionFormatter(this) : new ServiceInstanceFormatter(this);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/BaseService.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/BaseService.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/BaseService.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/BaseService.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,54 @@
+/**
+ * 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.api.services;
+
+import org.apache.ambari.api.handlers.DelegatingRequestHandler;
+import org.apache.ambari.api.handlers.RequestHandler;
+import org.apache.ambari.api.resource.ResourceDefinition;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+/**
+ *
+ */
+public class BaseService {
+
+  protected Response handleRequest(HttpHeaders headers, UriInfo uriInfo, Request.RequestType requestType,
+                                   ResourceDefinition resourceDefinition) {
+
+    Request req = getRequestFactory().createRequest(headers, uriInfo, requestType, resourceDefinition);
+    Result result = getRequestHandler().handleRequest(req);
+    Object formattedResult = resourceDefinition.getResultFormatter().format(result, uriInfo);
+    return getResponseFactory().createResponse(req.getSerializer().serialize(formattedResult));
+  }
+
+  RequestFactory getRequestFactory() {
+    return new RequestFactory();
+  }
+
+  ResponseFactory getResponseFactory() {
+    return new ResponseFactory();
+  }
+
+  RequestHandler getRequestHandler() {
+    return new DelegatingRequestHandler();
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ClusterService.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ClusterService.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ClusterService.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ClusterService.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,99 @@
+/**
+ * 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.api.services;
+
+import org.apache.ambari.api.resource.ClusterResourceDefinition;
+import org.apache.ambari.api.resource.ResourceDefinition;
+
+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.*;
+
+/**
+ * Service responsible for cluster resource requests.
+ */
+@Path("/clusters/")
+public class ClusterService extends BaseService {
+
+  /**
+   * Handles URL: /clusters/{clusterID}
+   * Get a specific cluster.
+   *
+   * @param headers     http headers
+   * @param ui          uri info
+   * @param clusterName cluster id
+   * @return cluster instance representation
+   */
+  @GET
+  @Path("{clusterName}")
+  @Produces("text/plain")
+  public Response getCluster(@Context HttpHeaders headers, @Context UriInfo ui,
+                             @PathParam("clusterName") String clusterName) {
+
+    return handleRequest(headers, ui, Request.RequestType.GET, createResourceDefinition(clusterName));
+  }
+
+  /**
+   * Handles URL:  /clusters
+   * Get all clusters.
+   *
+   * @param headers http headers
+   * @param ui      uri info
+   * @return cluster collection resource representation
+   */
+  @GET
+  @Produces("text/plain")
+  public Response getClusters(@Context HttpHeaders headers, @Context UriInfo ui) {
+    return handleRequest(headers, ui, Request.RequestType.GET, createResourceDefinition(null));
+  }
+
+  /**
+   * Get the hosts sub-resource
+   *
+   * @param clusterName cluster id
+   * @return the hosts service
+   */
+  @Path("{clusterName}/hosts")
+  public HostService getHostHandler(@PathParam("clusterName") String clusterName) {
+    return new HostService(clusterName);
+  }
+
+  /**
+   * Get the services sub-resource
+   *
+   * @param clusterName cluster id
+   * @return the services service
+   */
+  @Path("{clusterName}/services")
+  public ServiceService getServiceHandler(@PathParam("clusterName") String clusterName) {
+    return new ServiceService(clusterName);
+  }
+
+  /**
+   * Create a cluster resource definition.
+   *
+   * @param clusterName cluster name
+   * @return a cluster resource definition
+   */
+  ResourceDefinition createResourceDefinition(String clusterName) {
+    return new ClusterResourceDefinition(clusterName);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ComponentService.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ComponentService.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ComponentService.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ComponentService.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,100 @@
+/**
+ * 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.api.services;
+
+import org.apache.ambari.api.resource.ComponentResourceDefinition;
+import org.apache.ambari.api.resource.ResourceDefinition;
+
+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.*;
+
+/**
+ * Service responsible for components resource requests.
+ */
+public class ComponentService extends BaseService {
+  /**
+   * Parent cluster id.
+   */
+  private String m_clusterName;
+
+  /**
+   * Parent service id.
+   */
+  private String m_serviceName;
+
+  /**
+   * Constructor.
+   *
+   * @param clusterName cluster id
+   * @param serviceName service id
+   */
+  public ComponentService(String clusterName, String serviceName) {
+    m_clusterName = clusterName;
+    m_serviceName = serviceName;
+  }
+
+  /**
+   * Handles URL: /clusters/{clusterID}/services/{serviceID}/components/{componentID}
+   * Get a specific component.
+   *
+   * @param headers       http headers
+   * @param ui            uri info
+   * @param componentName component id
+   * @return a component resource representation
+   */
+  @GET
+  @Path("{componentName}")
+  @Produces("text/plain")
+  public Response getComponent(@Context HttpHeaders headers, @Context UriInfo ui,
+                               @PathParam("componentName") String componentName) {
+
+    return handleRequest(headers, ui, Request.RequestType.GET,
+        createResourceDefinition(componentName, m_clusterName, m_serviceName));
+  }
+
+  /**
+   * Handles URL: /clusters/{clusterID}/services/{serviceID}/components
+   * Get all components for a service.
+   *
+   * @param headers http headers
+   * @param ui      uri info
+   * @return component collection resource representation
+   */
+  @GET
+  @Produces("text/plain")
+  public Response getComponents(@Context HttpHeaders headers, @Context UriInfo ui) {
+    return handleRequest(headers, ui, Request.RequestType.GET,
+        createResourceDefinition(null, m_clusterName, m_serviceName));
+  }
+
+  /**
+   * Create a component resource definition.
+   *
+   * @param clusterName   cluster name
+   * @param serviceName   service name
+   * @param componentName component name
+   * @return a component resource definition
+   */
+  ResourceDefinition createResourceDefinition(String clusterName, String serviceName, String componentName) {
+    return new ComponentResourceDefinition(clusterName, serviceName, componentName);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/HostComponentService.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/HostComponentService.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/HostComponentService.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/HostComponentService.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,100 @@
+/**
+ * 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.api.services;
+
+import org.apache.ambari.api.resource.HostComponentResourceDefinition;
+import org.apache.ambari.api.resource.ResourceDefinition;
+
+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.*;
+
+/**
+ * Service responsible for host_components resource requests.
+ */
+public class HostComponentService extends BaseService {
+  /**
+   * Parent cluster id.
+   */
+  private String m_clusterName;
+
+  /**
+   * Parent host id.
+   */
+  private String m_hostName;
+
+  /**
+   * Constructor.
+   *
+   * @param clusterName cluster id
+   * @param hostName    host id
+   */
+  public HostComponentService(String clusterName, String hostName) {
+    m_clusterName = clusterName;
+    m_hostName = hostName;
+  }
+
+  /**
+   * Handles URL: /clusters/{clusterID}/hosts/{hostID}/host_components/{hostComponentID}
+   * Get a specific host_component.
+   *
+   * @param headers           http headers
+   * @param ui                uri info
+   * @param hostComponentName host_component id
+   * @return host_component resource representation
+   */
+  @GET
+  @Path("{hostComponentName}")
+  @Produces("text/plain")
+  public Response getHostComponent(@Context HttpHeaders headers, @Context UriInfo ui,
+                                   @PathParam("hostComponentName") String hostComponentName) {
+
+    return handleRequest(headers, ui, Request.RequestType.GET,
+        createResourceDefinition(hostComponentName, m_clusterName, m_hostName));
+  }
+
+  /**
+   * Handles URL: /clusters/{clusterID}/hosts/{hostID}/host_components/
+   * Get all host components for a host.
+   *
+   * @param headers http headers
+   * @param ui      uri info
+   * @return host_component collection resource representation
+   */
+  @GET
+  @Produces("text/plain")
+  public Response getHostComponents(@Context HttpHeaders headers, @Context UriInfo ui) {
+    return handleRequest(headers, ui, Request.RequestType.GET,
+        createResourceDefinition(null, m_clusterName, m_hostName));
+  }
+
+  /**
+   * Create a host_component resource definition.
+   *
+   * @param hostComponentName host_component name
+   * @param clusterName       cluster name
+   * @param hostName          host name
+   * @return a host resource definition
+   */
+  ResourceDefinition createResourceDefinition(String hostComponentName, String clusterName, String hostName) {
+    return new HostComponentResourceDefinition(hostComponentName, clusterName, hostName);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/HostService.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/HostService.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/HostService.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/HostService.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,103 @@
+/**
+ * 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.api.services;
+
+import org.apache.ambari.api.resource.HostResourceDefinition;
+import org.apache.ambari.api.resource.ResourceDefinition;
+
+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.*;
+
+/**
+ * Service responsible for hosts resource requests.
+ */
+public class HostService extends BaseService {
+
+  /**
+   * Parent cluster id.
+   */
+  private String m_clusterName;
+
+  /**
+   * Constructor.
+   *
+   * @param clusterName cluster id
+   */
+  public HostService(String clusterName) {
+    m_clusterName = clusterName;
+  }
+
+  /**
+   * Handles URL: /clusters/{clusterID}/hosts/{hostID}
+   * Get a specific host.
+   *
+   * @param headers  http headers
+   * @param ui       uri info
+   * @param hostName host id
+   * @return host resource representation
+   */
+  @GET
+  @Path("{hostName}")
+  @Produces("text/plain")
+  public Response getHost(@Context HttpHeaders headers, @Context UriInfo ui,
+                          @PathParam("hostName") String hostName) {
+
+    return handleRequest(headers, ui, Request.RequestType.GET,
+        createResourceDefinition(hostName, m_clusterName));
+  }
+
+  /**
+   * Handles URL: /clusters/{clusterID}/hosts or /clusters/hosts
+   * Get all hosts for a cluster.
+   *
+   * @param headers http headers
+   * @param ui      uri info
+   * @return host collection resource representation
+   */
+  @GET
+  @Produces("text/plain")
+  public Response getHosts(@Context HttpHeaders headers, @Context UriInfo ui) {
+    return handleRequest(headers, ui, Request.RequestType.GET, createResourceDefinition(null, m_clusterName));
+  }
+
+  /**
+   * Get the host_components sub-resource.
+   *
+   * @param hostName host id
+   * @return the host_components service
+   */
+  @Path("{hostName}/host_components")
+  public HostComponentService getHostComponentHandler(@PathParam("hostName") String hostName) {
+    return new HostComponentService(m_clusterName, hostName);
+  }
+
+  /**
+   * Create a host resource definition.
+   *
+   * @param hostName    host name
+   * @param clusterName cluster name
+   * @return a host resource definition
+   */
+  ResourceDefinition createResourceDefinition(String hostName, String clusterName) {
+    return new HostResourceDefinition(hostName, clusterName);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/JSONSerializer.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/JSONSerializer.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/JSONSerializer.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/JSONSerializer.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,49 @@
+/**
+ * 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.api.services;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+
+import java.io.IOException;
+
+/**
+ * Provides JSON serialization.
+ */
+public class JSONSerializer implements Serializer {
+  /**
+   * Serialize the result into JSON representation.
+   *
+   * @param result the object to serialize
+   * @return the JSON representation of the result
+   */
+  @Override
+  public Object serialize(Object result) {
+    ObjectMapper mapper = new ObjectMapper();
+    mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
+    mapper.configure(SerializationConfig.Feature.USE_ANNOTATIONS, true);
+    try {
+
+      return mapper.writeValueAsString(result);
+    } catch (IOException e) {
+      //todo
+      throw new RuntimeException("Unable to serialize json: " + e, e);
+    }
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Request.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Request.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Request.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Request.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,66 @@
+/**
+ * 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.api.services;
+
+import org.apache.ambari.api.resource.ResourceDefinition;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ */
+public interface Request {
+
+  public enum RequestType {
+    GET,
+    PUT,
+    POST,
+    DELETE
+  }
+
+  public enum ResponseType {JSON}
+
+  public ResourceDefinition getResource();
+
+  public URI getURI();
+
+  public RequestType getRequestType();
+
+  public int getAPIVersion();
+
+  public Map<String, List<String>> getQueryParameters();
+
+  public Map<String, List<String>> getQueryPredicates();
+
+  public Set<String> getPartialResponseFields();
+
+  public Set<String> getExpandEntities();
+
+  public Map<String, List<String>> getHeaders();
+
+  public String getBody();
+
+  public Serializer getSerializer();
+
+  //todo: temporal information.  For now always specify in PR for each field.  Could use *[...] ?
+  //public Map<String, TemporalData> getTemporalFields();
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/RequestFactory.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/RequestFactory.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/RequestFactory.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/RequestFactory.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,35 @@
+/**
+ * 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.api.services;
+
+import org.apache.ambari.api.resource.ResourceDefinition;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+
+/**
+ *
+ */
+public class RequestFactory {
+  public Request createRequest(HttpHeaders headers, UriInfo uriInfo, Request.RequestType requestType,
+                               ResourceDefinition resourceDefinition) {
+
+    return new RequestImpl(headers, uriInfo, requestType, resourceDefinition);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/RequestImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/RequestImpl.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/RequestImpl.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/RequestImpl.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,103 @@
+/**
+ * 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.api.services;
+
+import org.apache.ambari.api.resource.*;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ */
+public class RequestImpl implements Request {
+
+  private UriInfo m_uriInfo;
+  private HttpHeaders m_headers;
+  private RequestType m_requestType;
+  private ResourceDefinition m_resourceDefinition;
+
+
+  public RequestImpl(HttpHeaders headers, UriInfo uriInfo, RequestType requestType, ResourceDefinition resourceDefinition) {
+    m_uriInfo = uriInfo;
+    m_headers = headers;
+    m_requestType = requestType;
+    m_resourceDefinition = resourceDefinition;
+  }
+
+  @Override
+  public ResourceDefinition getResource() {
+    return m_resourceDefinition;
+  }
+
+  @Override
+  public URI getURI() {
+    return m_uriInfo.getRequestUri();
+  }
+
+  @Override
+  public RequestType getRequestType() {
+    return m_requestType;
+  }
+
+  @Override
+  public int getAPIVersion() {
+    return 0;
+  }
+
+  @Override
+  public Map<String, List<String>> getQueryParameters() {
+    return m_uriInfo.getQueryParameters();
+  }
+
+  @Override
+  public Map<String, List<String>> getQueryPredicates() {
+    //todo: handle expand/fields ...
+    return getQueryParameters();
+  }
+
+  @Override
+  public Set<String> getPartialResponseFields() {
+    return null;
+  }
+
+  @Override
+  public Set<String> getExpandEntities() {
+    return null;  //To change body of implemented methods use File | Settings | File Templates.
+  }
+
+  @Override
+  public Map<String, List<String>> getHeaders() {
+    return m_headers.getRequestHeaders();
+  }
+
+  @Override
+  public String getBody() {
+    return null;
+  }
+
+  @Override
+  public Serializer getSerializer() {
+    return new JSONSerializer();
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ResponseFactory.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ResponseFactory.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ResponseFactory.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ResponseFactory.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,30 @@
+/**
+ * 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.api.services;
+
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ */
+public class ResponseFactory {
+  public Response createResponse(Object result) {
+    return Response.ok(result).build();
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Result.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Result.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Result.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Result.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.api.services;
+
+
+import org.apache.ambari.api.controller.spi.Resource;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ */
+public interface Result {
+  public void addResources(String groupName, List<Resource> listResources);
+
+  public Map<String, List<Resource>> getResources();
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ResultImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ResultImpl.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ResultImpl.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ResultImpl.java Sun Sep 23 18:01:49 2012
@@ -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.api.services;
+
+
+import org.apache.ambari.api.controller.spi.Resource;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ */
+//todo: at the moment only supports one level of nesting.
+//todo: need to allow arbitrary nesting depth for expansion.
+//todo: consider building a tree structure.
+public class ResultImpl implements Result {
+
+  private Map<String, List<Resource>> m_mapResources = new HashMap<String, List<Resource>>();
+
+  @Override
+  public void addResources(String groupName, List<Resource> listResources) {
+    List<Resource> resources = m_mapResources.get(groupName);
+    if (resources == null) {
+      m_mapResources.put(groupName, listResources);
+    } else {
+      resources.addAll(listResources);
+    }
+  }
+
+  @Override
+  public Map<String, List<Resource>> getResources() {
+    return m_mapResources;
+  }
+}
+

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Serializer.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Serializer.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Serializer.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/Serializer.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.api.services;
+
+/**
+ * Serialize the result according to the request.
+ */
+public interface Serializer {
+  /**
+   * Serialize the given object returning the serialized form.
+   *
+   * @param result the object to serialize
+   * @return the serialized form of the result object
+   */
+  public Object serialize(Object result);
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ServiceService.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ServiceService.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ServiceService.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/ServiceService.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,104 @@
+/**
+ * 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.api.services;
+
+import org.apache.ambari.api.resource.ResourceDefinition;
+import org.apache.ambari.api.resource.ServiceResourceDefinition;
+
+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.*;
+
+/**
+ * Service responsible for services resource requests.
+ */
+public class ServiceService extends BaseService {
+  /**
+   * Parent cluster name.
+   */
+  private String m_clusterName;
+
+  /**
+   * Constructor.
+   *
+   * @param clusterName cluster id
+   */
+  public ServiceService(String clusterName) {
+    m_clusterName = clusterName;
+  }
+
+  /**
+   * Handles URL: /clusters/{clusterID}/services/{serviceID}
+   * Get a specific service.
+   *
+   * @param headers     http headers
+   * @param ui          uri info
+   * @param serviceName service id
+   * @return service resource representation
+   */
+  @GET
+  @Path("{serviceName}")
+  @Produces("text/plain")
+  public Response getService(@Context HttpHeaders headers, @Context UriInfo ui,
+                             @PathParam("serviceName") String serviceName) {
+
+    return handleRequest(headers, ui, Request.RequestType.GET,
+        createResourceDefinition(serviceName, m_clusterName));
+  }
+
+  /**
+   * Handles URL: /clusters/{clusterID}/services
+   * Get all services for a cluster.
+   *
+   * @param headers http headers
+   * @param ui      uri info
+   * @return service collection resource representation
+   */
+  @GET
+  @Produces("text/plain")
+  public Response getServices(@Context HttpHeaders headers, @Context UriInfo ui) {
+    return handleRequest(headers, ui, Request.RequestType.GET,
+        createResourceDefinition(null, m_clusterName));
+  }
+
+  /**
+   * Get the components sub-resource.
+   *
+   * @param serviceName service id
+   * @return the components service
+   */
+  @Path("{serviceName}/components")
+  public ComponentService getComponentHandler(@PathParam("serviceName") String serviceName) {
+
+    return new ComponentService(m_clusterName, serviceName);
+  }
+
+  /**
+   * Create a service resource definition.
+   *
+   * @param serviceName host name
+   * @param clusterName cluster name
+   * @return a service resource definition
+   */
+  ResourceDefinition createResourceDefinition(String serviceName, String clusterName) {
+    return new ServiceResourceDefinition(serviceName, clusterName);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/BaseFormatter.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/BaseFormatter.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/BaseFormatter.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/BaseFormatter.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,220 @@
+/**
+ * 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.api.services.formatters;
+
+
+import org.apache.ambari.api.controller.utilities.ClusterControllerHelper;
+import org.apache.ambari.api.resource.ResourceDefinition;
+import org.apache.ambari.api.services.Result;
+import org.apache.ambari.api.controller.spi.Resource;
+import org.apache.ambari.api.controller.spi.Schema;
+
+import javax.ws.rs.core.UriInfo;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Base result formatter.
+ */
+public abstract class BaseFormatter implements ResultFormatter {
+  /**
+   * Request url.
+   */
+  public String href;
+
+  /**
+   * properties collection
+   */
+  public Map<String, Map<String, String>> properties = new HashMap<String, Map<String, String>>();
+
+  /**
+   * Resource definition.
+   */
+  private ResourceDefinition m_resourceDefinition;
+
+  /**
+   * Constructor.
+   *
+   * @param resourceDefinition the resource definition
+   */
+  BaseFormatter(ResourceDefinition resourceDefinition) {
+    m_resourceDefinition = resourceDefinition;
+  }
+
+  /**
+   * Format the given result to a format expected by client.
+   *
+   * @param result  internal result       the internal result
+   * @param uriInfo URL info for request  url info for the request
+   * @return the formatted result
+   */
+  @Override
+  public Object format(Result result, UriInfo uriInfo) {
+    href = uriInfo.getAbsolutePath().toString();
+
+    Map<String, List<Resource>> mapResults = result.getResources();
+    handleProperties(mapResults);
+
+    String baseHref = href.endsWith("/") ? href : href + '/';
+    handleResources(result.getResources().get("/"), baseHref);
+    handleChildren(m_resourceDefinition.getChildren(), mapResults, baseHref);
+    handleRelations(m_resourceDefinition.getRelations(), mapResults, baseHref);
+
+    return this;
+  }
+
+  /**
+   * Handle resource properties.
+   *
+   * @param mapResults results
+   */
+  void handleProperties(Map<String, List<Resource>> mapResults) {
+    List<Resource> listProperties = mapResults.get("/");
+    Resource propsResource = listProperties.get(0);
+    properties = propsResource.getCategories();
+  }
+
+  /**
+   * Handle collection resources
+   *
+   * @param listResources list of resources in collection
+   * @param baseHref      the base url
+   */
+  void handleResources(List<Resource> listResources, String baseHref) {
+    // only format resources for collection resources
+    if (m_resourceDefinition.getId() != null) return;
+    Schema schema = ClusterControllerHelper.getClusterController().getSchema(m_resourceDefinition.getType());
+    for (Resource r : listResources) {
+      addSubResource(new HrefEntry(baseHref + r.getPropertyValue(schema.getKeyPropertyId(
+          m_resourceDefinition.getType()))), r);
+    }
+  }
+
+  /**
+   * Handle child resources.
+   *
+   * @param setChildren set of child resources
+   * @param mapResults  results
+   * @param baseHref    base url
+   */
+  void handleChildren(Set<ResourceDefinition> setChildren, Map<String, List<Resource>> mapResults, String baseHref) {
+    for (ResourceDefinition resource : setChildren) {
+      String resourceName = resource.getPluralName();
+      List<Resource> listResources = mapResults.get(resourceName);
+      if (listResources != null) {
+        for (Resource r : listResources) {
+          handleChild(r, baseHref, resourceName);
+        }
+      }
+    }
+  }
+
+  /**
+   * Handle a single child resource.
+   *
+   * @param child        child resource
+   * @param baseHref     base url
+   * @param resourceName child resource name
+   */
+  void handleChild(Resource child, String baseHref, String resourceName) {
+    Schema schema = ClusterControllerHelper.getClusterController().getSchema(child.getType());
+    addSubResource(new HrefEntry(baseHref + resourceName + '/' +
+        child.getPropertyValue(schema.getKeyPropertyId(child.getType()))), child);
+  }
+
+  /**
+   * Handle relation resources.  These are associated resources that are not children.
+   *
+   * @param setRelations set of related resources
+   * @param mapResults   results
+   * @param baseHref     base url
+   */
+  void handleRelations(Set<ResourceDefinition> setRelations, Map<String, List<Resource>> mapResults, String baseHref) {
+    for (ResourceDefinition resourceDef : setRelations) {
+      String resourceName = resourceDef.getSingularName();
+      List<Resource> listResources = mapResults.get(resourceName);
+      if (listResources != null) {
+        for (Resource r : listResources) {
+          handleRelation(r, baseHref);
+        }
+      }
+    }
+  }
+
+  /**
+   * Handle a single relation resource.
+   *
+   * @param relation relation resource
+   * @param baseHref base url
+   */
+  void handleRelation(Resource relation, String baseHref) {
+    Schema schema = ClusterControllerHelper.getClusterController().getSchema(relation.getType());
+    String relationUrl = buildRelationHref(baseHref, schema, relation);
+
+    addSubResource(new HrefEntry(relationUrl), relation);
+  }
+
+  /**
+   * Build a relation href.
+   *
+   * @param baseHref the base href
+   * @param schema   associated schema
+   * @param relation the relation resource
+   * @return href for the given relation resource
+   */
+  String buildRelationHref(String baseHref, Schema schema, Resource relation) {
+    //todo: should not be called in this class
+    return "";
+  }
+
+  /**
+   * Get the resource definition.
+   *
+   * @return the resource definition
+   */
+  ResourceDefinition getResourceDefinition() {
+    return m_resourceDefinition;
+  }
+
+  /**
+   * Add a sub resource.  This can be a child, relation or resource in the collection.
+   *
+   * @param href the href to add
+   * @param r    the resource being added
+   */
+  public abstract void addSubResource(HrefEntry href, Resource r);
+
+  /**
+   * An href.
+   */
+  public static class HrefEntry {
+    public String href;
+
+    /**
+     * Constructor.
+     *
+     * @param href the href
+     */
+    public HrefEntry(String href) {
+      this.href = href;
+    }
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/ClusterInstanceFormatter.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/ClusterInstanceFormatter.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/ClusterInstanceFormatter.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/ClusterInstanceFormatter.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,64 @@
+/**
+ * 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.api.services.formatters;
+
+import org.apache.ambari.api.resource.ResourceDefinition;
+import org.apache.ambari.api.controller.spi.Resource;
+
+import java.util.*;
+
+/**
+ * Formatter for cluster instance resources.
+ */
+public class ClusterInstanceFormatter extends BaseFormatter {
+
+  /**
+   * services collection
+   */
+  public List<HrefEntry> services = new ArrayList<HrefEntry>();
+
+  /**
+   * hosts collection
+   */
+  public List<HrefEntry> hosts = new ArrayList<HrefEntry>();
+
+  /**
+   * Constructor.
+   *
+   * @param resourceDefinition resource definition
+   */
+  public ClusterInstanceFormatter(ResourceDefinition resourceDefinition) {
+    super(resourceDefinition);
+  }
+
+  /**
+   * Add services and hosts href's.
+   *
+   * @param href the href to add
+   * @param r    the resource being added
+   */
+  @Override
+  public void addSubResource(HrefEntry href, Resource r) {
+    if (r.getType() == Resource.Type.Service) {
+      services.add(href);
+    } else {
+      hosts.add(href);
+    }
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/CollectionFormatter.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/CollectionFormatter.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/CollectionFormatter.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/CollectionFormatter.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,66 @@
+/**
+ * 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.api.services.formatters;
+
+import org.apache.ambari.api.resource.ResourceDefinition;
+import org.apache.ambari.api.controller.spi.Resource;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Result formatter for collection resources.
+ */
+public class CollectionFormatter extends BaseFormatter {
+  /**
+   * Items collection
+   */
+  public List<HrefEntry> items = new ArrayList<HrefEntry>();
+
+  /**
+   * Constructor.
+   *
+   * @param resourceDefinition resource definition
+   */
+  public CollectionFormatter(ResourceDefinition resourceDefinition) {
+    super(resourceDefinition);
+  }
+
+  /**
+   * Add an item.
+   *
+   * @param href the href to add
+   * @param r    the resource being added
+   */
+  @Override
+  public void addSubResource(HrefEntry href, Resource r) {
+    items.add(href);
+  }
+
+  /**
+   * No-op.  Collections do not have properties.
+   *
+   * @param mapResults results
+   */
+  @Override
+  void handleProperties(Map<String, List<Resource>> mapResults) {
+    // no-op no properties for collection resources
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/ComponentInstanceFormatter.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/ComponentInstanceFormatter.java?rev=1389109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/ComponentInstanceFormatter.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-api/src/main/java/org/apache/ambari/api/services/formatters/ComponentInstanceFormatter.java Sun Sep 23 18:01:49 2012
@@ -0,0 +1,73 @@
+/**
+ * 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.api.services.formatters;
+
+import org.apache.ambari.api.resource.ResourceDefinition;
+import org.apache.ambari.api.controller.spi.Resource;
+import org.apache.ambari.api.controller.spi.Schema;
+
+import java.util.*;
+
+/**
+ * Component instance formatter.
+ */
+public class ComponentInstanceFormatter extends BaseFormatter {
+
+  /**
+   * host_components collection
+   */
+  public List<HrefEntry> host_components = new ArrayList<HrefEntry>();
+
+  /**
+   * Constructor.
+   *
+   * @param resourceDefinition resource definition
+   */
+  public ComponentInstanceFormatter(ResourceDefinition resourceDefinition) {
+    super(resourceDefinition);
+  }
+
+  /**
+   * Add host_components href's.
+   *
+   * @param href the href to add
+   * @param r    the type of resource being added
+   */
+  @Override
+  public void addSubResource(HrefEntry href, Resource r) {
+    host_components.add(href);
+  }
+
+  /**
+   * Build hosts_component href's.
+   *
+   * @param baseHref the base URL
+   * @param schema   associated schema
+   * @param relation the host_component resource
+   * @return href for a host_component
+   */
+  @Override
+  String buildRelationHref(String baseHref, Schema schema, Resource relation) {
+    ResourceDefinition resourceDefinition = getResourceDefinition();
+    String clusterId = resourceDefinition.getResourceIds().get(Resource.Type.Cluster);
+    return baseHref.substring(0, baseHref.indexOf(clusterId) + clusterId.length() + 1) +
+        "hosts/" + relation.getPropertyValue(schema.getKeyPropertyId(Resource.Type.Host)) +
+        "/host_components/" + resourceDefinition.getId();
+  }
+}