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/10/09 19:02:02 UTC

svn commit: r1396109 [3/7] - in /incubator/ambari/branches/AMBARI-666: ./ ambari-api/ ambari-project/ ambari-server/ ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ ambari-server/src/main/java/org/apache/ambari/server/api/query/ amba...

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaMetric.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaMetric.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaMetric.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaMetric.java Tue Oct  9 17:01:58 2012
@@ -0,0 +1,125 @@
+/**
+ * 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.ganglia;
+
+
+/**
+ *
+ */
+public class GangliaMetric {
+
+  private String ds_name;
+  private String cluster_name;
+  private String graph_type;
+  private String host_name;
+  private String metric_name;
+
+  private double[][] datapoints;
+
+  public String getDs_name() {
+    return ds_name;
+  }
+
+  public void setDs_name(String ds_name) {
+    this.ds_name = ds_name;
+  }
+
+  public String getCluster_name() {
+    return cluster_name;
+  }
+
+  public void setCluster_name(String cluster_name) {
+    this.cluster_name = cluster_name;
+  }
+
+  public String getGraph_type() {
+    return graph_type;
+  }
+
+  public void setGraph_type(String graph_type) {
+    this.graph_type = graph_type;
+  }
+
+  public String getHost_name() {
+    return host_name;
+  }
+
+  public void setHost_name(String host_name) {
+    this.host_name = host_name;
+  }
+
+  public String getMetric_name() {
+    return metric_name;
+  }
+
+  public void setMetric_name(String metric_name) {
+    this.metric_name = metric_name;
+  }
+
+  public double[][] getDatapoints() {
+    return datapoints;
+  }
+
+  public void setDatapoints(double[][] datapoints) {
+    this.datapoints = datapoints;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder stringBuilder = new StringBuilder();
+
+    stringBuilder.append("\n");
+    stringBuilder.append("name=");
+    stringBuilder.append(ds_name);
+    stringBuilder.append("\n");
+    stringBuilder.append("cluster name=");
+    stringBuilder.append(cluster_name);
+    stringBuilder.append("\n");
+    stringBuilder.append("graph type=");
+    stringBuilder.append(graph_type);
+    stringBuilder.append("\n");
+    stringBuilder.append("host name=");
+    stringBuilder.append(host_name);
+    stringBuilder.append("\n");
+    stringBuilder.append("api name=");
+    stringBuilder.append(metric_name);
+    stringBuilder.append("\n");
+
+    stringBuilder.append("datapoints (value/timestamp):");
+    stringBuilder.append("\n");
+
+
+    boolean first = true;
+    stringBuilder.append("[");
+    for (double[] m : datapoints) {
+      if (!first) {
+        stringBuilder.append(",");
+      }
+      stringBuilder.append("[");
+      stringBuilder.append(m[0]);
+      stringBuilder.append(",");
+      stringBuilder.append((long) m[1]);
+      stringBuilder.append("]");
+      first = false;
+    }
+    stringBuilder.append("]");
+
+    return stringBuilder.toString();
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaPropertyProvider.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaPropertyProvider.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaPropertyProvider.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaPropertyProvider.java Tue Oct  9 17:01:58 2012
@@ -0,0 +1,176 @@
+/**
+ * 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.ganglia;
+
+import org.apache.ambari.server.controller.internal.PropertyIdImpl;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Property provider implementation for a Ganglia source.
+ */
+public class GangliaPropertyProvider implements PropertyProvider {
+
+  /**
+   * Map of property ids supported by this provider.
+   */
+  private static final Set<PropertyId> PROPERTY_IDS = new HashSet<PropertyId>();
+
+  static {
+    PROPERTY_IDS.add(new PropertyIdImpl("cpu_nice", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("cpu_nice", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("cpu_wio", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("cpu_user", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("cpu_idle", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("cpu_system", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("cpu_aidle", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("disk_free", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("disk_total", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("part_max_used", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("load_one", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("load_five", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("load_fifteen", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("swap_free", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("mem_cached", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("mem_free", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("mem_buffers", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("mem_shared", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("bytes_out", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("bytes_in", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("pkts_in", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("pkts_out", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("proc_run", null, true));
+    PROPERTY_IDS.add(new PropertyIdImpl("proc_total", null, true));
+  }
+
+  /**
+   * The Ganglia source.
+   * //TODO : where do we get this from?
+   */
+  private static final String GANGLIA_SOURCE = "ec2-107-22-86-120.compute-1.amazonaws.com";
+
+
+  /**
+   * Map of Ganglia cluster names keyed by component type.
+   */
+  private static final Map<String, String> COMPONENT_MAP = new HashMap<String, String>();
+
+  static {
+    COMPONENT_MAP.put("NAMENODE", "HDPNameNode");
+    COMPONENT_MAP.put("JOBTRACKER", "HDPJobTracker");
+//        COMPONENT_MAP.put("???", "HDPSlaves");
+  }
+
+  @Override
+  public Set<Resource> populateResources(Set<Resource> resources, Request request, Predicate predicate) {
+    Set<Resource> keepers = new HashSet<Resource>();
+    for (Resource resource : resources) {
+      if (populateResource(resource, request, predicate)) {
+        keepers.add(resource);
+      }
+    }
+    return keepers;
+  }
+
+  @Override
+  public Set<PropertyId> getPropertyIds() {
+    return PROPERTY_IDS;
+  }
+
+  private boolean populateResource(Resource resource, Request request, Predicate predicate) {
+
+    Set<PropertyId> ids = new HashSet<PropertyId>(request.getPropertyIds());
+    if (ids == null || ids.isEmpty()) {
+      ids = getPropertyIds();
+    } else {
+      if (predicate != null) {
+        ids.addAll(PredicateHelper.getPropertyIds(predicate));
+      }
+      ids.retainAll(getPropertyIds());
+    }
+
+    String host = resource.getPropertyValue(new PropertyIdImpl("host_name", "HostRoles", false));
+    String component = resource.getPropertyValue(new PropertyIdImpl("component_name", "HostRoles", false));
+
+    // ---- TODO : HACK to fix host name that's been made all lower case... Ganglia doesn't like!!
+    host = hackHostName(host);
+    // -----
+
+    String cluster = COMPONENT_MAP.get(component);
+
+    if (cluster == null) {
+      return true;
+    }
+
+    for (PropertyId propertyId : ids) {
+
+      String property = (propertyId.getCategory() == null ? "" : propertyId.getCategory() + ".") +
+          propertyId.getName();
+
+      List<GangliaMetric> properties = GangliaHelper.getGangliaProperty(GANGLIA_SOURCE, cluster, host, property);
+
+      double[][] dataPoints = properties.get(0).getDatapoints();
+
+      resource.setProperty(propertyId, getTemporalValue(dataPoints));
+    }
+    return true;
+  }
+
+  private String getTemporalValue(double[][] dataPoints) {
+    boolean first = true;
+    StringBuilder stringBuilder = new StringBuilder();
+    stringBuilder.append("[");
+    for (double[] m : dataPoints) {
+      if (!first) {
+        stringBuilder.append(",");
+      }
+      stringBuilder.append("[");
+      stringBuilder.append(m[0]);
+      stringBuilder.append(",");
+      stringBuilder.append((long) m[1]);
+      stringBuilder.append("]");
+      first = false;
+    }
+    stringBuilder.append("]");
+    return stringBuilder.toString();
+  }
+
+  private String hackHostName(String host) {
+    int first_dash = host.indexOf('-');
+    int first_dot = host.indexOf('.');
+    String segment1 = host.substring(0, first_dash);
+    if (segment1.equals("domu")) {
+      segment1 = "domU";
+    }
+    String segment2 = host.substring(first_dash, first_dot).toUpperCase();
+    host = segment1 + segment2 + host.substring(first_dot);
+    return host;
+  }
+}
+

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java Tue Oct  9 17:01:58 2012
@@ -0,0 +1,248 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.spi.ProviderModule;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.spi.ClusterController;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.spi.Schema;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * Default cluster controller implementation.
+ */
+public class ClusterControllerImpl implements ClusterController {
+
+  /**
+   * Module of providers for this controller.
+   */
+  private final ProviderModule providerModule;
+
+  /**
+   * Map of resource providers keyed by resource type.
+   */
+  private final Map<Resource.Type, ResourceProvider> resourceProviders;
+
+
+  // ----- Constructors ------------------------------------------------------
+
+  public ClusterControllerImpl(ProviderModule providerModule) {
+    this.providerModule = providerModule;
+    this.resourceProviders = getResourceSchemas();
+  }
+
+
+  // ----- ClusterController -------------------------------------------------
+
+  @Override
+  public Iterable<Resource> getResources(Resource.Type type, Request request, Predicate predicate)
+      throws AmbariException{
+    ResourceProvider provider = resourceProviders.get(type);
+    Set<Resource> resources;
+
+    if (provider == null) {
+      resources = Collections.emptySet();
+    } else {
+      resources = provider.getResources(request, predicate);
+      resources = populateResources(type, resources, request, predicate);
+    }
+    return new ResourceIterable(resources, predicate);
+  }
+
+  @Override
+  public Schema getSchema(Resource.Type type) {
+    return resourceProviders.get(type).getSchema();
+  }
+
+  @Override
+  public void createResources(Resource.Type type, Request request) throws AmbariException {
+    ResourceProvider provider = resourceProviders.get(type);
+    if (provider != null) {
+      provider.createResources(request);
+    }
+  }
+
+  @Override
+  public void updateResources(Resource.Type type, Request request, Predicate predicate) throws AmbariException {
+    ResourceProvider provider = resourceProviders.get(type);
+    if (provider != null) {
+      provider.updateResources(request, predicate);
+    }
+  }
+
+  @Override
+  public void deleteResources(Resource.Type type, Predicate predicate) throws AmbariException {
+    ResourceProvider provider = resourceProviders.get(type);
+    if (provider != null) {
+      provider.deleteResources(predicate);
+    }
+  }
+
+
+  // ----- helper methods ----------------------------------------------------
+
+  private Set<Resource> populateResources(Resource.Type type,
+                                          Set<Resource> resources,
+                                          Request request,
+                                          Predicate predicate) throws AmbariException{
+    Set<Resource> keepers = resources;
+
+    for (PropertyProvider propertyProvider : resourceProviders.get(type).getPropertyProviders()) {
+      //TODO : only call the provider if it provides properties that we need ...
+      keepers = propertyProvider.populateResources(keepers, request, predicate);
+    }
+    return keepers;
+  }
+
+  private Map<Resource.Type, ResourceProvider> getResourceSchemas() {
+    Map<Resource.Type, ResourceProvider> resourceProviders = new HashMap<Resource.Type, ResourceProvider>();
+
+    resourceProviders.put(Resource.Type.Cluster, providerModule.getResourceProvider(Resource.Type.Cluster));
+    resourceProviders.put(Resource.Type.Service, providerModule.getResourceProvider(Resource.Type.Service));
+    resourceProviders.put(Resource.Type.Host, providerModule.getResourceProvider(Resource.Type.Host));
+    resourceProviders.put(Resource.Type.Component, providerModule.getResourceProvider(Resource.Type.Component));
+    resourceProviders.put(Resource.Type.HostComponent, providerModule.getResourceProvider(Resource.Type.HostComponent));
+
+    return resourceProviders;
+  }
+
+
+  // ----- ResourceIterable inner class --------------------------------------
+
+  private static class ResourceIterable implements Iterable<Resource> {
+
+    /**
+     * The resources to iterate over.
+     */
+    private final Set<Resource> resources;
+
+    /**
+     * The predicate used to filter the set.
+     */
+    private final Predicate predicate;
+
+    // ----- Constructors ----------------------------------------------------
+
+    /**
+     * Create a ResourceIterable.
+     *
+     * @param resources  the set of resources to iterate over
+     * @param predicate  the predicate used to filter the set of resources
+     */
+    private ResourceIterable(Set<Resource> resources, Predicate predicate) {
+      this.resources = resources;
+      this.predicate = predicate;
+    }
+
+    // ----- Iterable --------------------------------------------------------
+
+    @Override
+    public Iterator<Resource> iterator() {
+      return new ResourceIterator(resources, predicate);
+    }
+  }
+
+
+  // ----- ResourceIterator inner class --------------------------------------
+
+  private static class ResourceIterator implements Iterator<Resource> {
+
+    /**
+     * The underlying iterator.
+     */
+    private final Iterator<Resource> iterator;
+
+    /**
+     * The predicate used to filter the resource being iterated over.
+     */
+    private final Predicate predicate;
+
+    /**
+     * The next resource.
+     */
+    private Resource nextResource;
+
+
+    // ----- Constructors ----------------------------------------------------
+
+    /**
+     * Create a new ResourceIterator.
+     *
+     * @param resources  the set of resources to iterate over
+     * @param predicate  the predicate used to filter the set of resources
+     */
+    private ResourceIterator(Set<Resource> resources, Predicate predicate) {
+      this.iterator     = resources.iterator();
+      this.predicate    = predicate;
+      this.nextResource = getNextResource();
+    }
+
+    // ----- Iterator --------------------------------------------------------
+
+    @Override
+    public boolean hasNext() {
+      return nextResource != null;
+    }
+
+    @Override
+    public Resource next() {
+      if (nextResource == null) {
+        throw new NoSuchElementException("Iterator has no more elements.");
+      }
+
+      Resource currentResource = nextResource;
+      this.nextResource = getNextResource();
+
+      return currentResource;
+    }
+
+    @Override
+    public void remove() {
+      throw new UnsupportedOperationException("Remove not supported.");
+    }
+
+    // ----- helper methods --------------------------------------------------
+
+    /**
+     * Get the next resource.
+     *
+     * @return the next resource.
+     */
+    private Resource getNextResource() {
+      while (iterator.hasNext()) {
+        Resource next = iterator.next();
+        if (predicate == null || predicate.evaluate(next)) {
+          return next;
+        }
+      }
+      return null;
+    }
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java Tue Oct  9 17:01:58 2012
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.spi.ProviderModule;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.AmbariManagementControllerImpl;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ *
+ */
+public class DefaultProviderModule implements ProviderModule {
+
+  private static final List<PropertyProvider> PROPERTY_PROVIDERS =
+      new LinkedList<PropertyProvider>();
+
+  @Override
+  public ResourceProvider getResourceProvider(Resource.Type type) {
+    AmbariManagementController managementController =
+        new AmbariManagementControllerImpl(null, null);
+    return ResourceProviderImpl.getResourceProvider(type,
+        PROPERTY_PROVIDERS, PropertyHelper.getPropertyIds(type, "DB"),
+        PropertyHelper.getKeyPropertyIds(type), managementController);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PropertyIdImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PropertyIdImpl.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PropertyIdImpl.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PropertyIdImpl.java Tue Oct  9 17:01:58 2012
@@ -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 org.apache.ambari.server.controller.spi.PropertyId;
+
+/**
+ * Simple PropertyId implementation.
+ */
+public class PropertyIdImpl implements PropertyId {
+  /**
+   * The property name.
+   */
+  private String name;
+
+  /**
+   * The category name.
+   */
+  private String category;
+
+  /**
+   * Indicates whether or not this property is temporal.
+   */
+  private boolean temporal;
+
+
+  // ----- Constructors ------------------------------------------------------
+
+  /**
+   * Create a property id.  Required for JSON serialization.
+   */
+  public PropertyIdImpl() {
+  }
+
+  /**
+   * Create a property id.
+   *
+   * @param name      the property name.
+   * @param category  the property category.
+   * @param temporal  a temporal indicator
+   */
+  public PropertyIdImpl(String name, String category, boolean temporal) {
+    this.name     = name;
+    this.category = category;
+    this.temporal = temporal;
+  }
+
+
+  // ----- PropertyId --------------------------------------------------------
+
+  public String getName() {
+    return name;
+  }
+
+  public String getCategory() {
+    return category;
+  }
+
+  public boolean isTemporal() {
+    return temporal;
+  }
+
+
+  // ----- Object overrides --------------------------------------------------
+
+  @Override
+  public int hashCode() {
+    return name.hashCode() +
+        (category == null ? 0 : category.hashCode()) +
+        (temporal ? 1 : 0);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+
+    if (this == o) {
+      return true;
+    }
+
+    if (!(o.getClass().equals(PropertyIdImpl.class))) {
+      return false;
+    }
+
+    PropertyIdImpl that = (PropertyIdImpl) o;
+
+    return this.name.equals(that.getName()) &&
+        equals(this.category, that.getCategory()) &&
+        this.isTemporal() == that.isTemporal();
+  }
+
+  @Override
+  public String toString() {
+    return "PropertyId[" + category + ", " + name + "]";
+  }
+
+
+  // ----- helper methods ----------------------------------------------------
+
+  private static boolean equals(Object o1, Object o2) {
+    if (o1 == null) {
+      return o2 == null;
+    }
+    return o2 != null && o1.equals(o2);
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PropertyPredicateVisitor.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PropertyPredicateVisitor.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PropertyPredicateVisitor.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/PropertyPredicateVisitor.java Tue Oct  9 17:01:58 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.server.controller.internal;
+
+import org.apache.ambari.server.controller.predicate.ArrayPredicate;
+import org.apache.ambari.server.controller.predicate.BasePredicate;
+import org.apache.ambari.server.controller.predicate.ComparisonPredicate;
+import org.apache.ambari.server.controller.predicate.PredicateVisitor;
+import org.apache.ambari.server.controller.predicate.UnaryPredicate;
+import org.apache.ambari.server.controller.spi.PropertyId;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Predicate visitor for extracting property values from the PropertyPredicates of a predicate graph.
+ */
+public class PropertyPredicateVisitor implements PredicateVisitor {
+  private final Map<PropertyId, String> properties = new HashMap<PropertyId, String>();
+
+  @Override
+  public void acceptComparisonPredicate(ComparisonPredicate predicate) {
+    properties.put(predicate.getPropertyId(), predicate.getValue().toString());
+  }
+
+  @Override
+  public void acceptArrayPredicate(ArrayPredicate predicate) {
+    BasePredicate[] predicates = predicate.getPredicates();
+    for (int i = 0; i < predicates.length; i++) {
+      predicates[i].accept(this);
+    }
+  }
+
+  @Override
+  public void acceptUnaryPredicate(UnaryPredicate predicate) {
+    //Do nothing
+  }
+
+
+  // ----- accessors ---------------------------------------------------------
+
+  /**
+   * Get the properties.
+   *
+   * @return the properties
+   */
+  public Map<PropertyId, String> getProperties() {
+    return properties;
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestImpl.java Tue Oct  9 17:01:58 2012
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.Request;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Default request implementation.
+ */
+public class RequestImpl implements Request {
+
+  /**
+   * The property ids associated with this request.  Used for requests that
+   * get resource values.
+   */
+  private final Set<PropertyId> propertyIds;
+
+  /**
+   * The properties associated with this request.  Used for requests that create
+   * resources or update resource values.
+   */
+  private final Set<Map<PropertyId, String>> properties;
+
+
+  // ----- Constructors ------------------------------------------------------
+
+  /**
+   * Create a request.
+   *
+   * @param propertyIds  the property ids associated with the request; may be null
+   * @param properties   the properties associated with the request; may be null
+   */
+  public RequestImpl(Set<PropertyId> propertyIds, Set<Map<PropertyId, String>> properties) {
+    this.propertyIds = propertyIds == null ?
+        Collections.unmodifiableSet(new HashSet<PropertyId>()) :
+        Collections.unmodifiableSet(propertyIds);
+
+    this.properties = properties == null ?
+        Collections.unmodifiableSet(new HashSet<Map<PropertyId, String>>()) :
+        Collections.unmodifiableSet(properties);
+  }
+
+
+  // ----- Request -----------------------------------------------------------
+
+  @Override
+  public Set<PropertyId> getPropertyIds() {
+    return propertyIds;
+  }
+
+  @Override
+  public Set<Map<PropertyId, String>> getProperties() {
+    return properties;
+  }
+
+  @Override
+  public TemporalInfo getTemporalInfo(PropertyId id) {
+    return null;  //TODO
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java Tue Oct  9 17:01:58 2012
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.Resource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Simple resource implementation.
+ */
+public class ResourceImpl implements Resource {
+
+  /**
+   * The resource type.
+   */
+  private final Type type;
+
+  /**
+   * The map of categories/properties for this resource.
+   */
+  private final Map<String, Map<String, String>> categories = new HashMap<String, Map<String, String>>();
+
+
+  // ----- Constructors ------------------------------------------------------
+
+  /**
+   * Create a resource of the given type.
+   *
+   * @param type  the resource type
+   */
+  public ResourceImpl(Type type) {
+    this.type = type;
+  }
+
+
+  // ----- Resource ----------------------------------------------------------
+
+  @Override
+  public Type getType() {
+    return type;
+  }
+
+  @Override
+  public Map<String, Map<String, String>> getCategories() {
+    return categories;
+  }
+
+  @Override
+  public void setProperty(PropertyId id, String value) {
+    String category = id.getCategory();
+
+    Map<String, String> properties = categories.get(category);
+
+    if (properties == null) {
+      properties = new HashMap<String, String>();
+      categories.put(category, properties);
+    }
+
+    properties.put(id.getName(), value);
+  }
+
+  @Override
+  public void setProperty(PropertyId id, Integer value) {
+    setProperty(id, value.toString());
+  }
+
+  @Override
+  public void setProperty(PropertyId id, Float value) {
+    setProperty(id, value.toString());
+  }
+
+  @Override
+  public void setProperty(PropertyId id, Double value) {
+    setProperty(id, value.toString());
+  }
+
+  @Override
+  public void setProperty(PropertyId id, Long value) {
+    setProperty(id, value.toString());
+  }
+
+  @Override
+  public String getPropertyValue(PropertyId id) {
+
+    Map<String, String> properties = categories.get(id.getCategory());
+
+    if (properties != null) {
+      return properties.get(id.getName());
+    }
+    return null;
+  }
+
+
+  // ----- Object overrides --------------------------------------------------
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+
+    sb.append("Resource : ").append(type).append("\n");
+    for (Map.Entry<String, Map<String, String>> catEntry : categories.entrySet()) {
+      for (Map.Entry<String, String> propEntry : catEntry.getValue().entrySet()) {
+        sb.append("    ").append(catEntry.getKey()).append(".").append(propEntry.getKey()).append(" : ").append(propEntry.getValue()).append("\n");
+      }
+    }
+    return sb.toString();
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceProviderImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceProviderImpl.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceProviderImpl.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceProviderImpl.java Tue Oct  9 17:01:58 2012
@@ -0,0 +1,745 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ClusterRequest;
+import org.apache.ambari.server.controller.ClusterResponse;
+import org.apache.ambari.server.controller.HostRequest;
+import org.apache.ambari.server.controller.HostResponse;
+import org.apache.ambari.server.controller.ServiceComponentHostRequest;
+import org.apache.ambari.server.controller.ServiceComponentHostResponse;
+import org.apache.ambari.server.controller.ServiceComponentRequest;
+import org.apache.ambari.server.controller.ServiceComponentResponse;
+import org.apache.ambari.server.controller.ServiceRequest;
+import org.apache.ambari.server.controller.ServiceResponse;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.spi.Schema;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Basic resource provider implementation that maps to a management controller.
+ */
+public abstract class ResourceProviderImpl implements ResourceProvider {
+
+  /**
+   * The list of property providers for this provider's resource type.
+   */
+  private final List<PropertyProvider> propertyProviders;
+
+  /**
+   * The set of property ids supported by this resource provider.
+   */
+  private final Set<PropertyId> propertyIds;
+
+  /**
+   * The management controller to delegate to.
+   */
+  private final AmbariManagementController managementController;
+
+  /**
+   * The schema for this provider's resource type.
+   */
+  private final Schema schema;
+
+
+  // ----- Property ID constants ---------------------------------------------
+
+  // Clusters
+  protected static final PropertyId CLUSTER_ID_PROPERTY_ID      = PropertyHelper.getPropertyId("cluster_id", "Clusters");
+  protected static final PropertyId CLUSTER_NAME_PROPERTY_ID    = PropertyHelper.getPropertyId("cluster_name", "Clusters");
+  protected static final PropertyId CLUSTER_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("version", "Clusters");
+  protected static final PropertyId CLUSTER_HOSTS_PROPERTY_ID   = PropertyHelper.getPropertyId("hosts", "Clusters");
+  // Services
+  protected static final PropertyId SERVICE_CLUSTER_NAME_PROPERTY_ID  = PropertyHelper.getPropertyId("cluster_name", "ServiceInfo");
+  protected static final PropertyId SERVICE_SERVICE_NAME_PROPERTY_ID  = PropertyHelper.getPropertyId("service_name", "ServiceInfo");
+  protected static final PropertyId SERVICE_SERVICE_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("state", "ServiceInfo");
+  // Components
+  protected static final PropertyId COMPONENT_CLUSTER_NAME_PROPERTY_ID   = PropertyHelper.getPropertyId("cluster_name", "ServiceComponentInfo");
+  protected static final PropertyId COMPONENT_SERVICE_NAME_PROPERTY_ID   = PropertyHelper.getPropertyId("service_name", "ServiceComponentInfo");
+  protected static final PropertyId COMPONENT_COMPONENT_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("service_name", "ServiceComponentInfo");
+  protected static final PropertyId COMPONENT_STATE_PROPERTY_ID          = PropertyHelper.getPropertyId("state", "ServiceComponentInfo");
+  // Hosts
+  protected static final PropertyId HOST_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("cluster_name", "Hosts");
+  protected static final PropertyId HOST_NAME_PROPERTY_ID         = PropertyHelper.getPropertyId("host_name", "Hosts");
+  protected static final PropertyId HOST_IP_PROPERTY_ID           = PropertyHelper.getPropertyId("ip", "Hosts");
+  protected static final PropertyId HOST_TOTAL_MEM_PROPERTY_ID    = PropertyHelper.getPropertyId("total_mem", "Hosts");
+  protected static final PropertyId HOST_CPU_COUNT_PROPERTY_ID    = PropertyHelper.getPropertyId("cpu_count", "Hosts");
+  protected static final PropertyId HOST_OS_ARCH_PROPERTY_ID      = PropertyHelper.getPropertyId("os_arch", "Hosts");
+  protected static final PropertyId HOST_OS_TYPE_PROPERTY_ID      = PropertyHelper.getPropertyId("os_type", "Hosts");
+  // Host Components
+  protected static final PropertyId HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID   = PropertyHelper.getPropertyId("cluster_name", "HostRoles");
+  protected static final PropertyId HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID   = PropertyHelper.getPropertyId("service_name", "HostRoles");
+  protected static final PropertyId HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("service_name", "HostRoles");
+  protected static final PropertyId HOST_COMPONENT_HOST_NAME_PROPERTY_ID      = PropertyHelper.getPropertyId("host_name", "HostRoles");
+  protected static final PropertyId HOST_COMPONENT_STATE_PROPERTY_ID          = PropertyHelper.getPropertyId("state", "HostRoles");
+
+
+  // ----- Constructors ------------------------------------------------------
+
+  /**
+   * Create a  new resource provider for the given management controller.
+   *
+   * @param propertyIds           the property ids
+   * @param managementController  the management controller
+   */
+  private ResourceProviderImpl(List<PropertyProvider> propertyProviders,
+                               Set<PropertyId> propertyIds,
+                               Map<Resource.Type, PropertyId> keyPropertyIds,
+                               AmbariManagementController managementController) {
+    this.propertyProviders    = propertyProviders;
+    this.propertyIds          = propertyIds;
+    this.managementController = managementController;
+    this.schema               = new SchemaImpl(this, keyPropertyIds);
+  }
+
+
+  // ----- ResourceProvider --------------------------------------------------
+
+  @Override
+  public Set<PropertyId> getPropertyIds() {
+    return propertyIds;
+  }
+
+  @Override
+  public List<PropertyProvider> getPropertyProviders() {
+    return propertyProviders;
+  }
+
+  @Override
+  public Schema getSchema() {
+    return schema;
+  }
+
+
+  // ----- accessors ---------------------------------------------------------
+
+  /**
+   * Get the associated management controller.
+   *
+   * @return the associated management controller
+   */
+  public AmbariManagementController getManagementController() {
+    return managementController;
+  }
+
+
+  // ----- utility methods ---------------------------------------------------
+
+  protected abstract Set<PropertyId> getPKPropertyIds();
+
+  protected Set<Map<PropertyId, String>> getPropertyMaps(Map<PropertyId, String> requestPropertyMap, Predicate predicate) throws AmbariException{
+
+    Set<PropertyId>              pkPropertyIds       = getPKPropertyIds();
+    Set<Map<PropertyId, String>> properties          = new HashSet<Map<PropertyId, String>>();
+    Set<Map<PropertyId, String>> predicateProperties = new HashSet<Map<PropertyId, String>>();
+
+    if (predicate != null && pkPropertyIds.equals(PredicateHelper.getPropertyIds(predicate))) {
+      predicateProperties.add(getProperties(predicate));
+    } else {
+      for (Resource resource : getResources(PropertyHelper.getReadRequest(pkPropertyIds), predicate)) {
+        predicateProperties.add(PropertyHelper.getProperties(resource));
+      }
+    }
+
+    for (Map<PropertyId, String> predicatePropertyMap : predicateProperties) {
+      // get properties from the given request properties
+      Map<PropertyId, String> propertyMap = requestPropertyMap == null ?
+          new HashMap<PropertyId, String>():
+          new HashMap<PropertyId, String>(requestPropertyMap);
+      // add the pk properties
+      setProperties(propertyMap, predicatePropertyMap, pkPropertyIds);
+      properties.add(propertyMap);
+    }
+    return properties;
+  }
+
+  /**
+   * Get a map of property values from a given predicate.
+   *
+   * @param predicate  the predicate
+   *
+   * @return the map of properties
+   */
+  private static Map<PropertyId, String> getProperties(Predicate predicate) {
+    if (predicate == null) {
+      return Collections.emptyMap();
+    }
+    PropertyPredicateVisitor visitor = new PropertyPredicateVisitor();
+    PredicateHelper.visit(predicate, visitor);
+    return visitor.getProperties();
+  }
+
+  /**
+   * Transfer property values from one map to another for the given list of property ids.
+   *
+   * @param to           the target map
+   * @param from         the source map
+   * @param propertyIds  the set of property ids
+   */
+  private static void setProperties(Map<PropertyId, String> to, Map<PropertyId, String> from, Set<PropertyId> propertyIds) {
+    for (PropertyId propertyId : propertyIds) {
+      if (from.containsKey(propertyId)) {
+        to.put(propertyId, from.get(propertyId));
+      }
+    }
+  }
+
+  /**
+   * Set a string property value on the given resource for the given id and value.
+   * Make sure that the id is in the given set of requested ids.
+   *
+   * @param resource      the resource
+   * @param propertyId    the property id
+   * @param value         the value to set
+   * @param requestedIds  the requested set of property ids
+   */
+  private static void setResourceProperty(Resource resource, PropertyId propertyId, String value, Set<PropertyId> requestedIds) {
+    if (requestedIds.contains(propertyId)) {
+      resource.setProperty(propertyId, value);
+    }
+  }
+
+  /**
+   * Set a long property value on the given resource for the given id and value.
+   * Make sure that the id is in the given set of requested ids.
+   *
+   * @param resource      the resource
+   * @param propertyId    the property id
+   * @param value         the value to set
+   * @param requestedIds  the requested set of property ids
+   */
+  private static void setResourceProperty(Resource resource, PropertyId propertyId, Long value, Set<PropertyId> requestedIds) {
+    if (requestedIds.contains(propertyId)) {
+      resource.setProperty(propertyId, value);
+    }
+  }
+
+  /**
+   * Set a integer property value on the given resource for the given id and value.
+   * Make sure that the id is in the given set of requested ids.
+   *
+   * @param resource      the resource
+   * @param propertyId    the property id
+   * @param value         the value to set
+   * @param requestedIds  the requested set of property ids
+   */
+  private static void setResourceProperty(Resource resource, PropertyId propertyId, Integer value, Set<PropertyId> requestedIds) {
+    if (requestedIds.contains(propertyId)) {
+      resource.setProperty(propertyId, value);
+    }
+  }
+
+  /**
+   * Factory method for obtaining a resource provider based on a given type and management controller.
+   *
+   * @param type                  the resource type
+   * @param propertyIds           the property ids
+   * @param managementController  the management controller
+   *
+   * @return a new resource provider
+   */
+  public static ResourceProvider getResourceProvider(Resource.Type type,
+                                                     List<PropertyProvider> propertyProviders,
+                                                     Set<PropertyId> propertyIds,
+                                                     Map<Resource.Type, PropertyId> keyPropertyIds,
+                                                     AmbariManagementController managementController) {
+    switch (type) {
+      case Cluster:
+        return new ClusterResourceProvider(propertyProviders, propertyIds, keyPropertyIds, managementController);
+      case Service:
+        return new ServiceResourceProvider(propertyProviders, propertyIds, keyPropertyIds, managementController);
+      case Component:
+        return new ComponentResourceProvider(propertyProviders, propertyIds, keyPropertyIds, managementController);
+      case Host:
+        return new HostResourceProvider(propertyProviders, propertyIds, keyPropertyIds, managementController);
+      case HostComponent:
+        return new HostComponentResourceProvider(propertyProviders, propertyIds, keyPropertyIds, managementController);
+    }
+    throw new IllegalArgumentException("Unknown type " + type);
+  }
+
+
+  // ------ ClusterResourceProvider inner class ------------------------------
+
+  private static class ClusterResourceProvider extends ResourceProviderImpl{
+
+    private static Set<PropertyId> pkPropertyIds =
+        new HashSet<PropertyId>(Arrays.asList(new PropertyId[]{
+            CLUSTER_ID_PROPERTY_ID}));
+
+    // ----- Constructors ----------------------------------------------------
+
+    /**
+     * Create a  new resource provider for the given management controller.
+     *
+     * @param propertyIds           the property ids
+     * @param managementController  the management controller
+     */
+    private ClusterResourceProvider(List<PropertyProvider> propertyProviders, Set<PropertyId> propertyIds, Map<Resource.Type, PropertyId> keyPropertyIds, AmbariManagementController managementController) {
+      super(propertyProviders, propertyIds, keyPropertyIds, managementController);
+    }
+
+// ----- ResourceProvider ------------------------------------------------
+
+    @Override
+    public void createResources(Request request) throws AmbariException {
+
+      for (Map<PropertyId, String> properties : request.getProperties()) {
+        getManagementController().createCluster(getRequest(properties));
+      }
+    }
+
+    @Override
+    public Set<Resource> getResources(Request request, Predicate predicate) throws AmbariException {
+      Set<PropertyId> requestedIds   = request.getPropertyIds();
+      ClusterRequest  clusterRequest = getRequest(getProperties(predicate));
+
+      Set<ClusterResponse> responses = getManagementController().getClusters(clusterRequest);
+
+      Set<Resource> resources = new HashSet<Resource>();
+      for (ClusterResponse response : responses) {
+        Resource resource = new ResourceImpl(Resource.Type.Cluster);
+        setResourceProperty(resource, CLUSTER_ID_PROPERTY_ID, response.getClusterId(), requestedIds);
+        setResourceProperty(resource, CLUSTER_NAME_PROPERTY_ID, response.getClusterName(), requestedIds);
+        resources.add(resource);
+      }
+      return resources;
+    }
+
+    @Override
+    public void updateResources(Request request, Predicate predicate) throws AmbariException {
+      for (Map<PropertyId, String> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
+        ClusterRequest clusterRequest = getRequest(propertyMap);
+        getManagementController().updateCluster(clusterRequest);
+      }
+    }
+
+    @Override
+    public void deleteResources(Predicate predicate) throws AmbariException {
+      for (Map<PropertyId, String> propertyMap : getPropertyMaps(null, predicate)) {
+        ClusterRequest clusterRequest = getRequest(propertyMap);
+        getManagementController().deleteCluster(clusterRequest);
+      }
+    }
+
+    // ----- utility methods -------------------------------------------------
+
+    @Override
+    protected Set<PropertyId> getPKPropertyIds() {
+      return pkPropertyIds;
+    }
+
+    /**
+     * Get a cluster request object from a map of property values.
+     *
+     * @param properties  the predicate
+     *
+     * @return the cluster request object
+     */
+    private ClusterRequest getRequest(Map<PropertyId, String> properties) {
+
+      String id = properties.get(CLUSTER_ID_PROPERTY_ID);
+      return new ClusterRequest(
+          id == null ? null : Long.decode(id),
+          properties.get(CLUSTER_NAME_PROPERTY_ID),
+          properties.get(CLUSTER_VERSION_PROPERTY_ID),
+          /*properties.get(CLUSTER_HOSTS_PROPERTY_ID)*/ null);
+    }
+  }
+
+  // ------ ServiceResourceProvider inner class ------------------------------
+
+  private static class ServiceResourceProvider extends ResourceProviderImpl{
+
+    private static Set<PropertyId> pkPropertyIds =
+        new HashSet<PropertyId>(Arrays.asList(new PropertyId[]{
+            SERVICE_CLUSTER_NAME_PROPERTY_ID,
+            SERVICE_SERVICE_NAME_PROPERTY_ID}));
+
+    // ----- Constructors ----------------------------------------------------
+
+    /**
+     * Create a  new resource provider for the given management controller.
+     *
+     * @param propertyIds           the property ids
+     * @param managementController  the management controller
+     */
+    private ServiceResourceProvider(List<PropertyProvider> propertyProviders, Set<PropertyId> propertyIds, Map<Resource.Type, PropertyId> keyPropertyIds, AmbariManagementController managementController) {
+      super(propertyProviders, propertyIds, keyPropertyIds, managementController);
+    }
+
+    // ----- ResourceProvider ------------------------------------------------
+
+    @Override
+    public void createResources(Request request) throws AmbariException {
+      for (Map<PropertyId, String> properties : request.getProperties()) {
+        getManagementController().createService(getRequest(properties));
+      }
+    }
+
+    @Override
+    public Set<Resource> getResources(Request request, Predicate predicate) throws AmbariException {
+      Set<PropertyId> requestedIds   = request.getPropertyIds();
+      ServiceRequest  serviceRequest = getRequest(getProperties(predicate));
+
+      Set<ServiceResponse> responses = getManagementController().getServices(serviceRequest);
+
+      Set<Resource> resources = new HashSet<Resource>();
+      for (ServiceResponse response : responses) {
+        Resource resource = new ResourceImpl(Resource.Type.Service);
+//        setResourceProperty(resource, SERVICE_CLUSTER_ID_PROPERTY_ID, response.getClusterId(), requestedIds);
+        setResourceProperty(resource, SERVICE_CLUSTER_NAME_PROPERTY_ID, response.getClusterName(), requestedIds);
+        setResourceProperty(resource, SERVICE_SERVICE_NAME_PROPERTY_ID, response.getServiceName(), requestedIds);
+//        setResourceProperty(resource, SERVICE_VERSION_PROPERTY_ID, response.getCurrentStackVersion(), requestedIds);
+        resources.add(resource);
+      }
+      return resources;
+    }
+
+    @Override
+    public void updateResources(Request request, Predicate predicate) throws AmbariException {
+      for (Map<PropertyId, String> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
+        ServiceRequest serviceRequest = getRequest(propertyMap);
+        getManagementController().updateService(serviceRequest);
+      }
+    }
+
+    @Override
+    public void deleteResources(Predicate predicate) throws AmbariException {
+      for (Map<PropertyId, String> propertyMap : getPropertyMaps(null, predicate)) {
+        ServiceRequest serviceRequest = getRequest(propertyMap);
+        getManagementController().deleteService(serviceRequest);
+      }
+    }
+
+    // ----- utility methods -------------------------------------------------
+
+    @Override
+    protected Set<PropertyId> getPKPropertyIds() {
+      return pkPropertyIds;
+    }
+
+    /**
+     * Get a service request object from a map of property values.
+     *
+     * @param properties  the predicate
+     *
+     * @return the service request object
+     */
+    private ServiceRequest getRequest(Map<PropertyId, String> properties) {
+      return new ServiceRequest(
+          properties.get(SERVICE_CLUSTER_NAME_PROPERTY_ID),
+          properties.get(SERVICE_SERVICE_NAME_PROPERTY_ID),
+          null,
+          properties.get(SERVICE_SERVICE_STATE_PROPERTY_ID));
+    }
+  }
+
+  // ------ ComponentResourceProvider inner class ----------------------------
+
+  private static class ComponentResourceProvider extends ResourceProviderImpl{
+
+    private static Set<PropertyId> pkPropertyIds =
+        new HashSet<PropertyId>(Arrays.asList(new PropertyId[]{
+            COMPONENT_CLUSTER_NAME_PROPERTY_ID,
+            COMPONENT_SERVICE_NAME_PROPERTY_ID,
+            COMPONENT_COMPONENT_NAME_PROPERTY_ID}));
+
+    // ----- Constructors ----------------------------------------------------
+
+    /**
+     * Create a  new resource provider for the given management controller.
+     *
+     * @param propertyIds           the property ids
+     * @param managementController  the management controller
+     */
+    private ComponentResourceProvider(List<PropertyProvider> propertyProviders, Set<PropertyId> propertyIds, Map<Resource.Type, PropertyId> keyPropertyIds, AmbariManagementController managementController) {
+      super(propertyProviders, propertyIds, keyPropertyIds, managementController);
+    }
+
+    // ----- ResourceProvider ------------------------------------------------
+
+    @Override
+    public void createResources(Request request) throws AmbariException {
+      for (Map<PropertyId, String> properties : request.getProperties()) {
+        getManagementController().createComponent(getRequest(properties));
+      }
+    }
+
+    @Override
+    public Set<Resource> getResources(Request request, Predicate predicate) throws AmbariException {
+      Set<PropertyId>          requestedIds            = request.getPropertyIds();
+      ServiceComponentRequest  serviceComponentRequest = getRequest(getProperties(predicate));
+
+      Set<ServiceComponentResponse> responses = getManagementController().getComponents(serviceComponentRequest);
+
+      Set<Resource> resources = new HashSet<Resource>();
+      for (ServiceComponentResponse response : responses) {
+        Resource resource = new ResourceImpl(Resource.Type.Component);
+//        setResourceProperty(resource, COMPONENT_CLUSTER_ID_PROPERTY_ID, response.getClusterId(), requestedIds);
+        setResourceProperty(resource, COMPONENT_CLUSTER_NAME_PROPERTY_ID, response.getClusterName(), requestedIds);
+        setResourceProperty(resource, COMPONENT_SERVICE_NAME_PROPERTY_ID, response.getServiceName(), requestedIds);
+        setResourceProperty(resource, COMPONENT_COMPONENT_NAME_PROPERTY_ID, response.getComponentName(), requestedIds);
+//        setResourceProperty(resource, COMPONENT_VERSION_PROPERTY_ID, response.getCurrentStackVersion(), requestedIds);
+        resources.add(resource);
+      }
+      return resources;
+    }
+
+    @Override
+    public void updateResources(Request request, Predicate predicate) throws AmbariException {
+      for (Map<PropertyId, String> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
+        ServiceComponentRequest serviceComponentRequest = getRequest(propertyMap);
+        getManagementController().updateComponent(serviceComponentRequest);
+      }
+    }
+
+    @Override
+    public void deleteResources(Predicate predicate) throws AmbariException {
+      for (Map<PropertyId, String> propertyMap : getPropertyMaps(null, predicate)) {
+        ServiceComponentRequest serviceComponentRequest = getRequest(propertyMap);
+        getManagementController().deleteComponent(serviceComponentRequest);
+      }
+    }
+
+    // ----- utility methods -------------------------------------------------
+
+    @Override
+    protected Set<PropertyId> getPKPropertyIds() {
+      return pkPropertyIds;
+    }
+
+    /**
+     * Get a component request object from a map of property values.
+     *
+     * @param properties  the predicate
+     *
+     * @return the component request object
+     */
+    private ServiceComponentRequest getRequest(Map<PropertyId, String> properties) {
+      return new ServiceComponentRequest(
+          properties.get(COMPONENT_CLUSTER_NAME_PROPERTY_ID),
+          properties.get(COMPONENT_SERVICE_NAME_PROPERTY_ID),
+          properties.get(COMPONENT_COMPONENT_NAME_PROPERTY_ID),
+          null,
+          properties.get(COMPONENT_STATE_PROPERTY_ID));
+    }
+  }
+
+  // ------ HostResourceProvider inner class ---------------------------------
+
+  private static class HostResourceProvider extends ResourceProviderImpl{
+
+    private static Set<PropertyId> pkPropertyIds =
+        new HashSet<PropertyId>(Arrays.asList(new PropertyId[]{
+            HOST_NAME_PROPERTY_ID}));
+
+    // ----- Constructors ----------------------------------------------------
+
+    /**
+     * Create a  new resource provider for the given management controller.
+     *
+     * @param propertyIds           the property ids
+     * @param managementController  the management controller
+     */
+    private HostResourceProvider(List<PropertyProvider> propertyProviders, Set<PropertyId> propertyIds, Map<Resource.Type, PropertyId> keyPropertyIds, AmbariManagementController managementController) {
+      super(propertyProviders, propertyIds, keyPropertyIds, managementController);
+    }
+
+    // ----- ResourceProvider ------------------------------------------------
+
+    @Override
+    public void createResources(Request request) throws AmbariException {
+      for (Map<PropertyId, String> properties : request.getProperties()) {
+        getManagementController().createHost(getRequest(properties));
+      }
+    }
+
+    @Override
+    public Set<Resource> getResources(Request request, Predicate predicate) throws AmbariException {
+      Set<PropertyId> requestedIds = request.getPropertyIds();
+      HostRequest     hostRequest  = getRequest(getProperties(predicate));
+
+      Set<HostResponse> responses = getManagementController().getHosts(hostRequest);
+
+      Set<Resource> resources = new HashSet<Resource>();
+      for (HostResponse response : responses) {
+        Resource resource = new ResourceImpl(Resource.Type.Host);
+        // TODO : more than one cluster
+//        setResourceProperty(resource, HOST_CLUSTER_NAME_PROPERTY_ID, response.getClusterNames(), requestedIds);
+        setResourceProperty(resource, HOST_NAME_PROPERTY_ID, response.getHostname(), requestedIds);
+        setResourceProperty(resource, HOST_IP_PROPERTY_ID, response.getIpv4(), requestedIds);
+        setResourceProperty(resource, HOST_TOTAL_MEM_PROPERTY_ID, response.getTotalMemBytes(), requestedIds);
+        setResourceProperty(resource, HOST_CPU_COUNT_PROPERTY_ID, response.getCpuCount(), requestedIds);
+        setResourceProperty(resource, HOST_OS_ARCH_PROPERTY_ID, response.getOsArch(), requestedIds);
+        setResourceProperty(resource, HOST_OS_TYPE_PROPERTY_ID, response.getOsType(), requestedIds);
+        // TODO ...
+        resources.add(resource);
+      }
+      return resources;
+    }
+
+    @Override
+    public void updateResources(Request request, Predicate predicate) throws AmbariException {
+      for (Map<PropertyId, String> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
+        HostRequest hostRequest = getRequest(propertyMap);
+        getManagementController().updateHost(hostRequest);
+      }
+    }
+
+    @Override
+    public void deleteResources(Predicate predicate) throws AmbariException {
+      for (Map<PropertyId, String> propertyMap : getPropertyMaps(null, predicate)) {
+        HostRequest hostRequest = getRequest(propertyMap);
+        getManagementController().deleteHost(hostRequest);
+      }
+    }
+
+    // ----- utility methods -------------------------------------------------
+
+    @Override
+    protected Set<PropertyId> getPKPropertyIds() {
+      return pkPropertyIds;
+    }
+
+    /**
+     * Get a component request object from a map of property values.
+     *
+     * @param properties  the predicate
+     *
+     * @return the component request object
+     */
+    private HostRequest getRequest(Map<PropertyId, String> properties) {
+      return new HostRequest(
+          properties.get(HOST_NAME_PROPERTY_ID),
+          // TODO : more than one cluster
+          Collections.singletonList(properties.get(HOST_CLUSTER_NAME_PROPERTY_ID)),
+          null);
+    }
+  }
+
+  // ------ HostComponentResourceProvider inner class ------------------------
+
+  private static class HostComponentResourceProvider extends ResourceProviderImpl{
+
+    private static Set<PropertyId> pkPropertyIds =
+        new HashSet<PropertyId>(Arrays.asList(new PropertyId[]{
+            HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID,
+            HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID,
+            HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID,
+            HOST_COMPONENT_HOST_NAME_PROPERTY_ID}));
+
+    // ----- Constructors ----------------------------------------------------
+
+    /**
+     * Create a  new resource provider for the given management controller.
+     *
+     * @param propertyIds           the property ids
+     * @param managementController  the management controller
+     */
+    private HostComponentResourceProvider(List<PropertyProvider> propertyProviders, Set<PropertyId> propertyIds, Map<Resource.Type, PropertyId> keyPropertyIds, AmbariManagementController managementController) {
+      super(propertyProviders, propertyIds, keyPropertyIds, managementController);
+    }
+
+    // ----- ResourceProvider ------------------------------------------------
+
+    @Override
+    public void createResources(Request request) throws AmbariException {
+      for (Map<PropertyId, String> properties : request.getProperties()) {
+        getManagementController().createHostComponent(getRequest(properties));
+      }
+    }
+
+    @Override
+    public Set<Resource> getResources(Request request, Predicate predicate) throws AmbariException {
+      Set<PropertyId>             requestedIds         = request.getPropertyIds();
+      ServiceComponentHostRequest hostComponentRequest = getRequest(getProperties(predicate));
+
+      Set<ServiceComponentHostResponse> responses = getManagementController().getHostComponents(hostComponentRequest);
+
+      Set<Resource> resources = new HashSet<Resource>();
+      for (ServiceComponentHostResponse response : responses) {
+        Resource resource = new ResourceImpl(Resource.Type.HostComponent);
+        setResourceProperty(resource, HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID, response.getClusterName(), requestedIds);
+        setResourceProperty(resource, HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID, response.getServiceName(), requestedIds);
+        setResourceProperty(resource, HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID, response.getComponentName(), requestedIds);
+        setResourceProperty(resource, HOST_COMPONENT_HOST_NAME_PROPERTY_ID, response.getHostname(), requestedIds);
+        setResourceProperty(resource, HOST_COMPONENT_STATE_PROPERTY_ID, response.getLiveState(), requestedIds);
+        resources.add(resource);
+      }
+      return resources;
+    }
+
+    @Override
+    public void updateResources(Request request, Predicate predicate) throws AmbariException {
+      for (Map<PropertyId, String> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
+        ServiceComponentHostRequest hostComponentRequest = getRequest(propertyMap);
+        getManagementController().updateHostComponent(hostComponentRequest);
+      }
+    }
+
+    @Override
+    public void deleteResources(Predicate predicate) throws AmbariException {
+      for (Map<PropertyId, String> propertyMap : getPropertyMaps(null, predicate)) {
+        ServiceComponentHostRequest serviceComponentHostRequest = getRequest(propertyMap);
+        getManagementController().deleteHostComponent(serviceComponentHostRequest);
+      }
+    }
+
+    // ----- utility methods -------------------------------------------------
+
+    @Override
+    protected Set<PropertyId> getPKPropertyIds() {
+      return pkPropertyIds;
+    }
+
+    /**
+     * Get a component request object from a map of property values.
+     *
+     * @param properties  the predicate
+     *
+     * @return the component request object
+     */
+    private ServiceComponentHostRequest getRequest(Map<PropertyId, String> properties) {
+      return new ServiceComponentHostRequest(
+          properties.get(HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID),
+          properties.get(HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID),
+          properties.get(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID),
+          properties.get(HOST_COMPONENT_HOST_NAME_PROPERTY_ID),
+          null,
+          properties.get(HOST_COMPONENT_STATE_PROPERTY_ID));
+    }
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/SchemaImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/SchemaImpl.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/SchemaImpl.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/SchemaImpl.java Tue Oct  9 17:01:58 2012
@@ -0,0 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.spi.PropertyId;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.spi.Schema;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Simple schema implementation.
+ */
+public class SchemaImpl implements Schema {
+  /**
+   * The associated resource provider.
+   */
+  private final ResourceProvider resourceProvider;
+
+  /**
+   * The list of associated property providers.
+   */
+  private final List<PropertyProvider> propertyProviders;
+
+  /**
+   * Key property mapping by resource type.
+   */
+  private final Map<Resource.Type, PropertyId> keyPropertyIds;
+
+
+  // ----- Constructors ------------------------------------------------------
+
+  /**
+   * Create a new schema for the given providers.
+   *
+   * @param resourceProvider   the resource provider
+   * @param keyPropertyIds     the key property mapping
+   */
+  public SchemaImpl(ResourceProvider resourceProvider,
+                    Map<Resource.Type, PropertyId> keyPropertyIds) {
+    this.resourceProvider = resourceProvider;
+    this.propertyProviders = resourceProvider.getPropertyProviders();
+    this.keyPropertyIds = keyPropertyIds;
+  }
+
+
+  // ----- Schema ------------------------------------------------------------
+
+  @Override
+  public PropertyId getKeyPropertyId(Resource.Type type) {
+    return keyPropertyIds.get(type);
+  }
+
+  @Override
+  public Map<String, Set<String>> getCategories() {
+    Map<String, Set<String>> categories = new HashMap<String, Set<String>>();
+
+    for (PropertyId propertyId : getPropertyIds()) {
+      final String category = propertyId.getCategory();
+      Set<String> properties = categories.get(category);
+      if (properties == null) {
+        properties = new HashSet<String>();
+        categories.put(category, properties);
+      }
+      properties.add(propertyId.getName());
+    }
+    return categories;
+  }
+
+
+  // ----- helper methods ----------------------------------------------------
+
+  private Set<PropertyId> getPropertyIds() {
+    Set<PropertyId> propertyIds = new HashSet<PropertyId>(resourceProvider.getPropertyIds());
+    for (PropertyProvider propertyProvider : propertyProviders) {
+      propertyIds.addAll(propertyProvider.getPropertyIds());
+    }
+    return propertyIds;
+  }
+}

Added: incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/ConnectionFactory.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/ConnectionFactory.java?rev=1396109&view=auto
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/ConnectionFactory.java (added)
+++ incubator/ambari/branches/AMBARI-666/ambari-server/src/main/java/org/apache/ambari/server/controller/jdbc/ConnectionFactory.java Tue Oct  9 17:01:58 2012
@@ -0,0 +1,36 @@
+/**
+ * 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.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Simple JDBC connection factory interface.
+ */
+public interface ConnectionFactory {
+  /**
+   * Get a connection.
+   *
+   * @return the connection
+   *
+   * @throws SQLException thrown if the connection cannot be obtained
+   */
+  public Connection getConnection() throws SQLException;
+}