You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jl...@apache.org on 2016/06/27 23:36:54 UTC

[28/34] ambari git commit: AMBARI-17355 & AMBARI-17354: POC: FE & BE changes for first class support for Yarn hosted services

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
index c7738cd..d3e549f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
@@ -29,6 +29,9 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.AmbariServer;
 import org.apache.ambari.server.controller.StackVersionResponse;
 import org.apache.ambari.server.stack.Validable;
 import org.apache.ambari.server.state.repository.VersionDefinitionXml;
@@ -146,13 +149,40 @@ public class StackInfo implements Comparable<StackInfo>, Validable{
     return services;
   }
 
-  public ServiceInfo getService(String name) {
+  public ServiceInfo getService(String serviceName) {
     Collection<ServiceInfo> services = getServices();
     for (ServiceInfo service : services) {
-      if (service.getName().equals(name)) {
+      if (service.getName().equals(serviceName)) {
         return service;
       }
     }
+
+    // HACK: If service name is different from stack service name, try using stack service name
+    try {
+      AmbariManagementController controller = AmbariServer.getController();
+      if (controller != null) {
+        Clusters clusters = controller.getClusters();
+        Map<String, Cluster> clusterMap = clusters.getClusters();
+        if (clusterMap != null && clusterMap.size() != 0) {
+          for (Cluster c : clusterMap.values()) {
+            StackId stackId = c.getCurrentStackVersion();
+            if (stackId.getStackName().equalsIgnoreCase(getName()) && stackId.getStackVersion().equalsIgnoreCase(version)) {
+              Service svc = c.getService(serviceName);
+              if (svc != null) {
+                String stackServiceName = svc.getStackServiceName();
+                for (ServiceInfo service : services) {
+                  if (service.getName().equals(stackServiceName)) {
+                    return service;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    } catch (AmbariException e) {
+
+    }
     //todo: exception?
     return null;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index 6cf9933..c8a3e72 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -38,6 +38,7 @@ import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import javax.annotation.Nullable;
+import javax.annotation.OverridingMethodsMustInvokeSuper;
 import javax.persistence.EntityManager;
 import javax.persistence.RollbackException;
 
@@ -49,6 +50,7 @@ import org.apache.ambari.server.ParentObjectNotFoundException;
 import org.apache.ambari.server.ServiceComponentHostNotFoundException;
 import org.apache.ambari.server.ServiceComponentNotFoundException;
 import org.apache.ambari.server.ServiceNotFoundException;
+import org.apache.ambari.server.ServiceGroupNotFoundException;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
@@ -83,6 +85,7 @@ import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
 import org.apache.ambari.server.orm.entities.ClusterConfigMappingEntity;
 import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
+import org.apache.ambari.server.orm.entities.ClusterServiceGroupEntity;
 import org.apache.ambari.server.orm.entities.ClusterStateEntity;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.orm.entities.ConfigGroupEntity;
@@ -103,31 +106,7 @@ import org.apache.ambari.server.orm.entities.UpgradeGroupEntity;
 import org.apache.ambari.server.orm.entities.UpgradeItemEntity;
 import org.apache.ambari.server.security.authorization.AuthorizationException;
 import org.apache.ambari.server.security.authorization.AuthorizationHelper;
-import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.ClusterHealthReport;
-import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.Config;
-import org.apache.ambari.server.state.ConfigFactory;
-import org.apache.ambari.server.state.ConfigHelper;
-import org.apache.ambari.server.state.DesiredConfig;
-import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.HostHealthStatus;
-import org.apache.ambari.server.state.HostState;
-import org.apache.ambari.server.state.MaintenanceState;
-import org.apache.ambari.server.state.PropertyInfo;
-import org.apache.ambari.server.state.RepositoryVersionState;
-import org.apache.ambari.server.state.SecurityType;
-import org.apache.ambari.server.state.Service;
-import org.apache.ambari.server.state.ServiceComponent;
-import org.apache.ambari.server.state.ServiceComponentHost;
-import org.apache.ambari.server.state.ServiceComponentHostEvent;
-import org.apache.ambari.server.state.ServiceComponentHostEventType;
-import org.apache.ambari.server.state.ServiceFactory;
-import org.apache.ambari.server.state.ServiceInfo;
-import org.apache.ambari.server.state.StackId;
-import org.apache.ambari.server.state.StackInfo;
-import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.*;
 import org.apache.ambari.server.state.configgroup.ConfigGroup;
 import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
@@ -174,6 +153,8 @@ public class ClusterImpl implements Cluster {
 
   private volatile Map<String, Service> services = null;
 
+  private volatile Map<String, ServiceGroup> serviceGroups = null;
+
   /**
    * [ Config Type -> [ Config Version Tag -> Config ] ]
    */
@@ -234,6 +215,9 @@ public class ClusterImpl implements Cluster {
   private ServiceFactory serviceFactory;
 
   @Inject
+  private ServiceGroupFactory serviceGroupFactory;
+
+  @Inject
   private ConfigFactory configFactory;
 
   @Inject
@@ -362,7 +346,15 @@ public class ClusterImpl implements Cluster {
       ServiceInfo serviceInfo = entry.getValue();
       Set<String> configTypes = serviceInfo.getConfigTypeAttributes().keySet();
       for (String configType : configTypes) {
-        serviceConfigTypes.put(serviceName, configType);
+        String configValue = configType + "," + configType;
+        serviceConfigTypes.put(serviceName, configValue);
+        // HACK : JRL : Create static service config mappings for service instances
+        for(int i = 1; i<= 5; i++) {
+          String serviceInstanceName = serviceName.concat("-" + i);
+          String instanceConfigType = configType.concat("-" + i);
+          configValue = instanceConfigType + "," + configType;
+          serviceConfigTypes.put(serviceInstanceName, configValue);
+        }
       }
     }
 
@@ -443,15 +435,15 @@ public class ClusterImpl implements Cluster {
                 StackId stackId = getCurrentStackVersion();
                 try {
                   if (ambariMetaInfo.getService(stackId.getStackName(),
-                    stackId.getStackVersion(), serviceEntity.getServiceName()) != null) {
+                    stackId.getStackVersion(), serviceEntity.getStackServiceName()) != null) {
                     services.put(serviceEntity.getServiceName(),
                       serviceFactory.createExisting(this, serviceEntity));
                   }
                 } catch (AmbariException e) {
                   LOG.error(String.format(
-                    "Can not get service info: stackName=%s, stackVersion=%s, serviceName=%s",
+                    "Can not get service info: stackName=%s, stackVersion=%s, serviceName=%s, stackServiceName=%s",
                     stackId.getStackName(), stackId.getStackVersion(),
-                    serviceEntity.getServiceName()));
+                    serviceEntity.getServiceName(), serviceEntity.getStackServiceName()));
                 }
               }
             }
@@ -463,6 +455,31 @@ public class ClusterImpl implements Cluster {
     }
   }
 
+  private void loadServiceGroups() {
+    if (serviceGroups == null) {
+      clusterGlobalLock.writeLock().lock();
+
+      try {
+        if (serviceGroups == null) {
+          ClusterEntity clusterEntity = getClusterEntity();
+          if (clusterEntity != null) {
+            serviceGroups = new TreeMap<String, ServiceGroup>();
+
+            if (!clusterEntity.getClusterServiceGroupEntities().isEmpty()) {
+              for (ClusterServiceGroupEntity serviceGroupEntity : clusterEntity.getClusterServiceGroupEntities()) {
+                serviceGroups.put(serviceGroupEntity.getServiceGroupName(),
+                    serviceGroupFactory.createExisting(this, serviceGroupEntity));
+
+              }
+            }
+          }
+        }
+      } finally {
+        clusterGlobalLock.writeLock().unlock();
+      }
+    }
+  }
+
   private void loadConfigGroups() {
     if (clusterConfigGroups == null) {
       clusterGlobalLock.writeLock().lock();
@@ -988,7 +1005,7 @@ public class ClusterImpl implements Cluster {
       if (LOG.isDebugEnabled()) {
         LOG.debug("Adding a new Service" + ", clusterName=" + getClusterName()
           + ", clusterId=" + getClusterId() + ", serviceName="
-          + service.getName());
+          + service.getName() + ", stackServiceName=" + service.getStackServiceName());
       }
       services.put(service.getName(), service);
     } finally {
@@ -997,20 +1014,20 @@ public class ClusterImpl implements Cluster {
   }
 
   @Override
-  public Service addService(String serviceName) throws AmbariException {
+  public Service addService(String serviceName, String stackServiceName, String serviceGroupName) throws AmbariException {
     loadServices();
     clusterGlobalLock.writeLock().lock();
     try {
       if (LOG.isDebugEnabled()) {
         LOG.debug("Adding a new Service" + ", clusterName=" + getClusterName()
-          + ", clusterId=" + getClusterId() + ", serviceName=" + serviceName);
+          + ", clusterId=" + getClusterId() + ", serviceName=" + serviceName + ", stackServiceName=" + stackServiceName);
       }
       if (services.containsKey(serviceName)) {
         throw new AmbariException("Service already exists" + ", clusterName="
             + getClusterName() + ", clusterId=" + getClusterId()
-            + ", serviceName=" + serviceName);
+            + ", serviceName=" + serviceName + ", stackServiceName=" + stackServiceName);
       }
-      Service s = serviceFactory.createNew(this, serviceName);
+      Service s = serviceFactory.createNew(this, serviceName, stackServiceName, serviceGroupName);
       services.put(s.getName(), s);
       return s;
     } finally {
@@ -1019,6 +1036,22 @@ public class ClusterImpl implements Cluster {
   }
 
   @Override
+  public void addServiceGroup(ServiceGroup serviceGroup) {
+    loadServices();
+    clusterGlobalLock.writeLock().lock();
+    try {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Adding a new service group" + ", clusterName=" + getClusterName()
+            + ", clusterId=" + getClusterId() + ", serviceGroupName="
+            + serviceGroup.getName());
+      }
+      serviceGroups.put(serviceGroup.getName(), serviceGroup);
+    } finally {
+      clusterGlobalLock.writeLock().unlock();
+    }
+  }
+
+  @Override
   public Service getService(String serviceName) throws AmbariException {
     loadServices();
     clusterGlobalLock.readLock().lock();
@@ -1044,6 +1077,31 @@ public class ClusterImpl implements Cluster {
   }
 
   @Override
+  public ServiceGroup getServiceGroup(String serviceGroupName) throws ServiceGroupNotFoundException {
+    loadServiceGroups();
+    clusterGlobalLock.readLock().lock();
+    try {
+      if (!serviceGroups.containsKey(serviceGroupName)) {
+        throw new ServiceGroupNotFoundException(getClusterName(), serviceGroupName);
+      }
+      return serviceGroups.get(serviceGroupName);
+    } finally {
+      clusterGlobalLock.readLock().unlock();
+    }
+  }
+
+  @Override
+  public Map<String, ServiceGroup> getServiceGroups() throws AmbariException {
+    loadServiceGroups();
+    clusterGlobalLock.readLock().lock();
+    try {
+      return new HashMap<>(serviceGroups);
+    } finally {
+      clusterGlobalLock.readLock().unlock();
+    }
+  }
+
+  @Override
   public StackId getDesiredStackVersion() {
     loadStackVersion();
     clusterGlobalLock.readLock().lock();
@@ -2226,6 +2284,33 @@ public class ClusterImpl implements Cluster {
     }
   }
 
+  @Override
+  public void deleteAllServiceGroups() throws AmbariException {
+
+  }
+
+  @Override
+  public void deleteServiceGroup(String serviceGroupName) throws AmbariException {
+    loadServiceGroups();
+    clusterGlobalLock.writeLock().lock();
+    try {
+      ServiceGroup serviceGroup = getServiceGroup(serviceGroupName);
+      LOG.info("Deleting service group for cluster" + ", clusterName="
+          + getClusterName() + ", serviceGroupName=" + serviceGroup.getName());
+      // FIXME check dependencies from meta layer
+      if (!serviceGroup.canBeRemoved()) {
+        throw new AmbariException("Could not delete service group from cluster"
+            + ", clusterName=" + getClusterName()
+            + ", serviceGroupName=" + serviceGroup.getName());
+      }
+      deleteServiceGroup(serviceGroup);
+      serviceGroups.remove(serviceGroupName);
+
+    } finally {
+      clusterGlobalLock.writeLock().unlock();
+    }
+  }
+
   /**
    * Deletes the specified service also removes references to it from {@link this.serviceComponentHosts}
    * and references to ServiceComponentHost objects that belong to the service from {@link this.serviceComponentHostsByHost}
@@ -2253,6 +2338,21 @@ public class ClusterImpl implements Cluster {
     }
   }
 
+  /**
+   * Deletes the specified service also removes references to it from {@link this.serviceComponentHosts}
+   * and references to ServiceComponentHost objects that belong to the service from {@link this.serviceComponentHostsByHost}
+   * <p>
+   *   Note: This method must be called only with write lock acquired.
+   * </p>
+   * @param serviceGroup the service group to be deleted
+   * @throws AmbariException
+   * @see   ServiceComponentHost
+   */
+  private void deleteServiceGroup(ServiceGroup serviceGroup) throws AmbariException {
+    final String serviceGroupName = serviceGroup.getName();
+    serviceGroup.delete();
+  }
+
   @Override
   public boolean canBeRemoved() {
     loadServices();
@@ -2524,7 +2624,11 @@ public class ClusterImpl implements Cluster {
     String serviceName = null;
     for (String configType : configTypes) {
       for (Entry<String, String> entry : serviceConfigTypes.entries()) {
-        if (StringUtils.equals(entry.getValue(), configType)) {
+        String value = entry.getValue();
+        String values[] = value.split(",");
+        String instanceConfigType = values[0];
+        String stackConfigType = values[1];
+        if (StringUtils.equals(instanceConfigType, configType)) {
           if (serviceName != null) {
             if (entry.getKey()!=null && !StringUtils.equals(serviceName, entry.getKey())) {
               throw new IllegalArgumentException(String.format("Config type %s belongs to %s service, " +
@@ -2544,8 +2648,12 @@ public class ClusterImpl implements Cluster {
   public String getServiceByConfigType(String configType) {
     for (Entry<String, String> entry : serviceConfigTypes.entries()) {
       String serviceName = entry.getKey();
-      String type = entry.getValue();
-      if (StringUtils.equals(type, configType)) {
+      String value = entry.getValue();
+      String values[] = value.split(",");
+      String instanceConfigType = values[0];
+      String stackConfigType = values[1];
+
+      if (StringUtils.equals(instanceConfigType, configType)) {
         return serviceName;
       }
     }
@@ -2553,6 +2661,22 @@ public class ClusterImpl implements Cluster {
   }
 
   @Override
+  public String getStackConfigTypeFromConfigType(String configType) {
+    for (Entry<String, String> entry : serviceConfigTypes.entries()) {
+      String serviceName = entry.getKey();
+      String value = entry.getValue();
+      String values[] = value.split(",");
+      String instanceConfigType = values[0];
+      String stackConfigType = values[1];
+
+      if (StringUtils.equals(instanceConfigType, configType)) {
+        return stackConfigType;
+      }
+    }
+    return null;
+  }
+
+  @Override
   public ServiceConfigVersionResponse setServiceConfigVersion(String serviceName, Long version, String user, String note) throws AmbariException {
     if (null == user) {
       throw new NullPointerException("User must be specified.");
@@ -2740,9 +2864,14 @@ public class ClusterImpl implements Cluster {
       List<ClusterConfigMappingEntity> mappingEntities =
           clusterDAO.getClusterConfigMappingEntitiesByCluster(getClusterId());
       for (ClusterConfigMappingEntity entity : mappingEntities) {
-        if (configTypes.contains(entity.getType()) && entity.isSelected() > 0) {
-          entity.setSelected(0);
-          entity = clusterDAO.mergeConfigMapping(entity);
+        for(String configType : configTypes) {
+          String values[] = configType.split(",");
+          String instanceConfigType = values[0];
+          String stackConfigType = values[1];
+          if (StringUtils.equals(instanceConfigType, entity.getType()) && entity.isSelected() > 0) {
+            entity.setSelected(0);
+            entity = clusterDAO.mergeConfigMapping(entity);
+          }
         }
       }
 
@@ -2834,7 +2963,11 @@ public class ClusterImpl implements Cluster {
     String serviceName = null;
     for (Config config : configs) {
       for (Entry<String, String> entry : serviceConfigTypes.entries()) {
-        if (StringUtils.equals(entry.getValue(), config.getType())) {
+        String value = entry.getValue();
+        String values[] = value.split(",");
+        String instanceConfigType = values[0];
+        String stackConfigType = values[1];
+        if (StringUtils.equals(instanceConfigType, config.getType())) {
           if (serviceName == null) {
             serviceName = entry.getKey();
             break;
@@ -2881,14 +3014,19 @@ public class ClusterImpl implements Cluster {
     //add configs from this service
     Collection<String> configTypes = serviceConfigTypes.get(serviceName);
     for (ClusterConfigMappingEntity mappingEntity : clusterDAO.getClusterConfigMappingEntitiesByCluster(getClusterId())) {
-      if (mappingEntity.isSelected() > 0 && configTypes.contains(mappingEntity.getType())) {
-        ClusterConfigEntity configEntity =
-          clusterDAO.findConfig(getClusterId(), mappingEntity.getType(), mappingEntity.getTag());
-        if (configEntity != null) {
-          configEntities.add(configEntity);
-        } else {
-          LOG.error("Desired cluster config type={}, tag={} is not present in database," +
-            " unable to add to service config version");
+      for(String configType : configTypes) {
+        String values[] = configType.split(",");
+        String instanceConfigType = values[0];
+        String stackConfigType = values[1];
+        if (mappingEntity.isSelected() > 0 && StringUtils.equals(instanceConfigType, mappingEntity.getType())) {
+          ClusterConfigEntity configEntity =
+              clusterDAO.findConfig(getClusterId(), mappingEntity.getType(), mappingEntity.getTag());
+          if (configEntity != null) {
+            configEntities.add(configEntity);
+          } else {
+            LOG.error("Desired cluster config type={}, tag={} is not present in database," +
+                " unable to add to service config version");
+          }
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
index f78dd95..c26e1e9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
@@ -297,6 +297,22 @@ public class ClustersImpl implements Clusters {
   }
 
   @Override
+  public Cluster getCluster(Long clusterId)
+    throws AmbariException {
+    checkLoaded();
+
+    Cluster cluster = null;
+    if (clusterId != null) {
+      cluster = clustersById.get(clusterId);
+    }
+    if (null == cluster) {
+      throw new ClusterNotFoundException(clusterId);
+    }
+    RetryHelper.addAffectedCluster(cluster);
+    return cluster;
+  }
+
+  @Override
   public Cluster getClusterById(long id) throws AmbariException {
     checkLoaded();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java
index 1d6b1e8..cc0dd36 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java
@@ -419,6 +419,7 @@ public class ConfigGroupImpl implements ConfigGroup {
           clusterConfigEntity.setClusterEntity(clusterEntity);
           clusterConfigEntity.setStack(clusterEntity.getDesiredStack());
           clusterConfigEntity.setType(config.getType());
+          clusterConfigEntity.setStackType(config.getStackType());
           clusterConfigEntity.setVersion(config.getVersion());
           clusterConfigEntity.setTag(config.getTag());
           clusterConfigEntity.setData(gson.toJson(config.getProperties()));

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index feae6e5..3fe59ca 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -1158,6 +1158,17 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
   }
 
   @Override
+  public String getStackServiceName() {
+    return serviceComponent.getStackServiceName();
+  }
+
+  @Override
+  public String getServiceGroupName() {
+    return serviceComponent.getServiceGroupName();
+  }
+
+
+  @Override
   public StackId getStackVersion() {
     readLock.lock();
     try {
@@ -1453,7 +1464,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
 
           ServiceComponentInstalledEvent event = new ServiceComponentInstalledEvent(
               getClusterId(), stackId.getStackName(),
-              stackId.getStackVersion(), getServiceName(), getServiceComponentName(), getHostName(),
+              stackId.getStackVersion(), getServiceName(), getStackServiceName(), getServiceGroupName(), getServiceComponentName(), getHostName(),
                   isRecoveryEnabled());
 
           eventPublisher.publish(event);
@@ -1597,12 +1608,14 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
       String stackVersion = stackId.getStackVersion();
       String stackName = stackId.getStackName();
       String serviceName = getServiceName();
+      String stackServiceName = getStackServiceName();
+      String serviceGroupName = getServiceGroupName();
       String componentName = getServiceComponentName();
       String hostName = getHostName();
       boolean recoveryEnabled = isRecoveryEnabled();
 
       ServiceComponentUninstalledEvent event = new ServiceComponentUninstalledEvent(
-          clusterId, stackName, stackVersion, serviceName, componentName,
+          clusterId, stackName, stackVersion, serviceName, stackServiceName, serviceGroupName, componentName,
           hostName, recoveryEnabled);
 
       eventPublisher.publish(event);

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
index e3b51c0..e40b3ae 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
@@ -194,10 +194,10 @@ public class AmbariContext {
     Set<ServiceRequest> serviceRequests = new HashSet<ServiceRequest>();
     Set<ServiceComponentRequest> componentRequests = new HashSet<ServiceComponentRequest>();
     for (String service : services) {
-      serviceRequests.add(new ServiceRequest(clusterName, service, null));
+      serviceRequests.add(new ServiceRequest(clusterName, service, service, "CORE", null));
       for (String component : topology.getBlueprint().getComponents(service)) {
         String recoveryEnabled = String.valueOf(topology.getBlueprint().isRecoveryEnabled(service, component));
-        componentRequests.add(new ServiceComponentRequest(clusterName, service, component, null, recoveryEnabled));
+        componentRequests.add(new ServiceComponentRequest(clusterName, service, component, null, null, recoveryEnabled));
       }
     }
     try {

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
index ff94795..d63373c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog150.java
@@ -717,11 +717,13 @@ public class UpgradeCatalog150 extends AbstractUpgradeCatalog {
       List<ClusterServiceEntity> clusterServiceEntities = clusterServiceDAO.findAll();
       for (final ClusterServiceEntity clusterServiceEntity : clusterServiceEntities) {
         String serviceName = clusterServiceEntity.getServiceName();
+        String stackServiceName = clusterServiceEntity.getStackServiceName();
+        String serviceGroupName = clusterServiceEntity.getServiceGroupName();
         ServiceInfo serviceInfo = null;
         try {
-          serviceInfo = ambariMetaInfo.getService(stackName, stackVersion, serviceName);
+          serviceInfo = ambariMetaInfo.getService(stackName, stackVersion, stackServiceName);
         } catch (AmbariException e) {
-          LOG.error("Service " + serviceName + " not found for " + stackName + stackVersion);
+          LOG.error("Service " + stackServiceName + " not found for " + stackName + " " + stackVersion + " " + serviceName);
           continue;
         }
         List<String> configTypes = serviceInfo.getConfigDependencies();
@@ -812,6 +814,7 @@ public class UpgradeCatalog150 extends AbstractUpgradeCatalog {
                       HostComponentDesiredStateEntityPK entityPK =
                         new HostComponentDesiredStateEntityPK();
                       entityPK.setClusterId(clusterId);
+                      // TODO: JRL Hardcoded service names :(
                       entityPK.setServiceName("HDFS");
                       entityPK.setComponentName("DATANODE");
                       entityPK.setHostId(hostEntity.getHostId());

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
index 41f538e..01b72d1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
@@ -131,6 +131,7 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
   public static final String BLUEPRINT_TABLE = "blueprint";
   public static final String VIEWINSTANCE_TABLE = "viewinstance";
   public static final String SHORT_URL_COLUMN = "short_url";
+  public static final String CLUSTER_HANDLE_COLUMN = "cluster_handle";
   protected static final String CLUSTER_VERSION_TABLE = "cluster_version";
   protected static final String HOST_VERSION_TABLE = "host_version";
 
@@ -246,6 +247,7 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
     createViewUrlTableDDL();
     updateViewInstanceEntityTable();
     createRemoteClusterTable();
+    updateViewInstanceTable();
   }
 
   private void createRemoteClusterTable() throws SQLException {
@@ -341,7 +343,7 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
 
   private void insertClusterInheritedPrincipal(String name) {
     PrincipalTypeEntity principalTypeEntity = new PrincipalTypeEntity();
-    principalTypeEntity.setName("ALL.CLUSTER.ADMINISTRATOR");
+    principalTypeEntity.setName(name);
     principalTypeEntity = principalTypeDAO.merge(principalTypeEntity);
 
     PrincipalEntity principalEntity = new PrincipalEntity();
@@ -2017,4 +2019,55 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
   private void updateTezViewProperty() throws SQLException {
     dbAccessor.executeUpdate("UPDATE viewinstanceproperty SET name = 'yarn.ats.url' where name = 'yarn.timeline-server.url'");
   }
+
+  /**
+   *  Update view instance table's cluster_handle column to have cluster_id
+   *  instead of cluster_name
+   */
+  @Transactional
+  private void updateViewInstanceTable() throws SQLException {
+    try {
+      if (Long.class.equals(dbAccessor.getColumnClass(VIEWINSTANCE_TABLE, CLUSTER_HANDLE_COLUMN))) {
+        LOG.info(String.format("%s column is already numeric. Skipping an update of %s table.", CLUSTER_HANDLE_COLUMN, VIEWINSTANCE_TABLE));
+        return;
+      }
+    } catch (ClassNotFoundException e) {
+      LOG.warn("Cannot determine a type of " + CLUSTER_HANDLE_COLUMN + " column.");
+    }
+
+    String cluster_handle_dummy = "cluster_handle_dummy";
+
+    dbAccessor.addColumn(VIEWINSTANCE_TABLE,
+      new DBColumnInfo(cluster_handle_dummy, Long.class, null, null, true));
+
+    Statement statement = null;
+    ResultSet resultSet = null;
+
+    try {
+      statement = dbAccessor.getConnection().createStatement();
+      if (statement != null) {
+        String selectSQL = String.format("SELECT cluster_id, cluster_name FROM %s",
+          CLUSTER_TABLE);
+
+        resultSet = statement.executeQuery(selectSQL);
+        while (null != resultSet && resultSet.next()) {
+          final Long clusterId = resultSet.getLong("cluster_id");
+          final String clusterName = resultSet.getString("cluster_name");
+
+          String updateSQL = String.format(
+            "UPDATE %s SET %s = %d WHERE cluster_handle = '%s'",
+            VIEWINSTANCE_TABLE, cluster_handle_dummy, clusterId, clusterName);
+
+          dbAccessor.executeQuery(updateSQL);
+        }
+      }
+    } finally {
+      JdbcUtils.closeResultSet(resultSet);
+      JdbcUtils.closeStatement(statement);
+    }
+
+    dbAccessor.dropColumn(VIEWINSTANCE_TABLE, CLUSTER_HANDLE_COLUMN);
+    dbAccessor.renameColumn(VIEWINSTANCE_TABLE, cluster_handle_dummy,
+      new DBColumnInfo(CLUSTER_HANDLE_COLUMN, Long.class, null, null, true));
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/utils/MapUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/MapUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/MapUtils.java
new file mode 100644
index 0000000..25a6857
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/MapUtils.java
@@ -0,0 +1,45 @@
+/**
+ * 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.utils;
+
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MapUtils {
+  public static Map<String, String> fillMap(String fileName)  {
+    String line = null;
+    Map<String, String>  map = new HashMap<>();
+
+    try {
+      BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)));
+      while ((line = reader.readLine()) != null) {
+        if (line.contains("=")) {
+          String[] strings = line.split("=");
+          map.put(strings[0], strings[1]);
+        }
+      }
+    } catch (Exception e) {
+
+    }
+    return map;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariClusterRegistry.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariClusterRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariClusterRegistry.java
index 38a47a4..c0c887f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariClusterRegistry.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariClusterRegistry.java
@@ -46,11 +46,11 @@ public class RemoteAmbariClusterRegistry {
   @Inject
   private Configuration configuration;
 
-  public RemoteAmbariCluster get(String clusterName){
-    RemoteAmbariCluster remoteAmbariCluster = clusterMap.get(clusterName);
+  public RemoteAmbariCluster get(Long clusterId){
+    RemoteAmbariCluster remoteAmbariCluster = clusterMap.get(clusterId);
     if(remoteAmbariCluster == null){
-      RemoteAmbariCluster cluster = getCluster(clusterName);
-      RemoteAmbariCluster oldCluster = clusterMap.putIfAbsent(clusterName, cluster);
+      RemoteAmbariCluster cluster = getCluster(clusterId);
+      RemoteAmbariCluster oldCluster = clusterMap.putIfAbsent(cluster.getName(), cluster);
       if(oldCluster == null) remoteAmbariCluster = cluster;
       else remoteAmbariCluster = oldCluster;
     }
@@ -58,8 +58,8 @@ public class RemoteAmbariClusterRegistry {
   }
 
 
-  private RemoteAmbariCluster getCluster(String clusterName) {
-    RemoteAmbariClusterEntity remoteAmbariClusterEntity = remoteAmbariClusterDAO.findByName(clusterName);
+  private RemoteAmbariCluster getCluster(Long clusterId) {
+    RemoteAmbariClusterEntity remoteAmbariClusterEntity = remoteAmbariClusterDAO.findById(clusterId);
     RemoteAmbariCluster remoteAmbariCluster = new RemoteAmbariCluster(remoteAmbariClusterEntity, configuration);
     return remoteAmbariCluster;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
index e98a4cd..f1d5c35 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
@@ -307,7 +307,7 @@ public class ViewContextImpl implements ViewContext, ViewController {
   @Override
   public AmbariStreamProvider getAmbariClusterStreamProvider() {
 
-    String clusterHandle = viewInstanceEntity.getClusterHandle();
+    Long clusterHandle = viewInstanceEntity.getClusterHandle();
     ClusterType clusterType = viewInstanceEntity.getClusterType();
 
     AmbariStreamProvider clusterStreamProvider = null;

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
index 6d4ef82..9f0a8d3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
@@ -33,6 +33,7 @@ import org.apache.ambari.server.api.resources.ViewExternalSubResourceDefinition;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.api.services.ViewExternalSubResourceService;
 import org.apache.ambari.server.api.services.ViewSubResourceService;
+import org.apache.ambari.server.api.util.ApiVersion;
 import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.AmbariServer;
@@ -911,7 +912,7 @@ public class ViewRegistry {
    */
   public Cluster getCluster(ViewInstanceDefinition viewInstance) {
     if (viewInstance != null) {
-      String clusterId = viewInstance.getClusterHandle();
+      Long clusterId = viewInstance.getClusterHandle();
 
       if (clusterId != null && viewInstance.getClusterType() == ClusterType.LOCAL_AMBARI) {
         try {
@@ -958,7 +959,7 @@ public class ViewRegistry {
 
             LOG.info("Auto creating instance of view " + viewName + " for cluster " + clusterName + ".");
             ViewInstanceEntity viewInstanceEntity = createViewInstanceEntity(viewEntity, viewConfig, autoConfig);
-            viewInstanceEntity.setClusterHandle(clusterName);
+            viewInstanceEntity.setClusterHandle(clusterId);
             installViewInstance(viewInstanceEntity);
           }
         } catch (Exception e) {
@@ -1205,7 +1206,7 @@ public class ViewRegistry {
     ViewContext viewInstanceContext = new ViewContextImpl(viewInstanceDefinition, this);
 
     ViewExternalSubResourceService externalSubResourceService =
-        new ViewExternalSubResourceService(viewDefinition.getExternalResourceType(), viewInstanceDefinition);
+        new ViewExternalSubResourceService(ApiVersion.v1, viewDefinition.getExternalResourceType(), viewInstanceDefinition);
 
     viewInstanceDefinition.addService(ResourceConfig.EXTERNAL_RESOURCE_PLURAL_NAME, externalSubResourceService);
 
@@ -1215,7 +1216,7 @@ public class ViewRegistry {
       Resource.Type  type           = resourceDefinition.getType();
       ResourceConfig resourceConfig = resourceDefinition.getResourceConfiguration();
 
-      ViewResourceHandler viewResourceService = new ViewSubResourceService(type, viewInstanceDefinition);
+      ViewResourceHandler viewResourceService = new ViewSubResourceService(ApiVersion.v1, type, viewInstanceDefinition);
 
       ClassLoader cl = viewDefinition.getClassLoader();
 
@@ -1681,6 +1682,7 @@ public class ViewRegistry {
     for (org.apache.ambari.server.state.Cluster cluster : allClusters.values()) {
 
       String clusterName = cluster.getClusterName();
+      Long clusterId= cluster.getClusterId();
       StackId stackId = cluster.getCurrentStackVersion();
       Set<String> serviceNames = cluster.getServices().keySet();
 
@@ -1690,7 +1692,7 @@ public class ViewRegistry {
           if (checkAutoInstanceConfig(autoInstanceConfig, stackId, service, serviceNames)) {
             LOG.info("Auto creating instance of view " + viewName + " for cluster " + clusterName + ".");
             ViewInstanceEntity viewInstanceEntity = createViewInstanceEntity(viewEntity, viewConfig, autoInstanceConfig);
-            viewInstanceEntity.setClusterHandle(clusterName);
+            viewInstanceEntity.setClusterHandle(clusterId);
             installViewInstance(viewInstanceEntity);
             addClusterInheritedPermissions(viewInstanceEntity, permissions);
           }
@@ -1907,11 +1909,11 @@ public class ViewRegistry {
   /**
    * Get Remote Ambari Cluster Stream provider
    *
-   * @param clusterName
+   * @param clusterId
    * @return
    */
-  protected AmbariStreamProvider createRemoteAmbariStreamProvider(String clusterName){
-    RemoteAmbariClusterEntity clusterEntity = remoteAmbariClusterDAO.findByName(clusterName);
+  protected AmbariStreamProvider createRemoteAmbariStreamProvider(Long clusterId){
+    RemoteAmbariClusterEntity clusterEntity = remoteAmbariClusterDAO.findById(clusterId);
     if(clusterEntity != null) {
       return new RemoteAmbariStreamProvider(getBaseurl(clusterEntity.getUrl()),
         clusterEntity.getUsername(),clusterEntity.getPassword(),

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
index 31dd8f2..e0c059e 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -123,8 +123,21 @@ CREATE TABLE serviceconfigmapping (
   CONSTRAINT FK_scvm_config FOREIGN KEY (config_id) REFERENCES clusterconfig(config_id),
   CONSTRAINT FK_scvm_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id));
 
+CREATE TABLE clusterservicegroups (
+  service_group_name VARCHAR(255) NOT NULL,
+  service_group_display_name VARCHAR(255) NOT NULL,
+  cluster_id BIGINT NOT NULL,
+  service_group_type VARCHAR(255) NOT NULL DEFAULT 'AMBARI',
+  assembly_file MEDIUMTEXT,
+  current_state VARCHAR(255) NOT NULL,
+  desired_state VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_clusterservicegroups PRIMARY KEY (service_group_name, cluster_id),
+  CONSTRAINT FK_clusterservicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
+
 CREATE TABLE clusterservices (
   service_name VARCHAR(255) NOT NULL,
+  stack_service_name VARCHAR(255) NOT NULL,
+  service_group_name VARCHAR(255) NOT NULL,
   cluster_id BIGINT NOT NULL,
   service_enabled INTEGER NOT NULL,
   CONSTRAINT PK_clusterservices PRIMARY KEY (service_name, cluster_id),
@@ -175,6 +188,7 @@ CREATE TABLE servicecomponentdesiredstate (
   desired_version VARCHAR(255) NOT NULL DEFAULT 'UNKNOWN',
   service_name VARCHAR(255) NOT NULL,
   recovery_enabled SMALLINT NOT NULL DEFAULT 0,
+  desired_count INTEGER NOT NULL DEFAULT 0,
   CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
   CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id),
   CONSTRAINT FK_scds_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES stack(stack_id),
@@ -566,7 +580,7 @@ CREATE TABLE viewinstance (
   icon64 VARCHAR(255),
   xml_driven CHAR(1),
   alter_names SMALLINT NOT NULL DEFAULT 1,
-  cluster_handle VARCHAR(255),
+  cluster_handle BIGINT,
   cluster_type VARCHAR(100) NOT NULL DEFAULT 'LOCAL_AMBARI',
   short_url BIGINT,
   CONSTRAINT PK_viewinstance PRIMARY KEY (view_instance_id),

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index 3c4f1ca..98dfd38 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -64,6 +64,7 @@ CREATE TABLE clusterconfig (
   version_tag VARCHAR(100) NOT NULL,
   version BIGINT NOT NULL,
   type_name VARCHAR(100) NOT NULL,
+  stack_type_name VARCHAR(100) NOT NULL,
   cluster_id BIGINT NOT NULL,
   stack_id BIGINT NOT NULL,
   config_data LONGTEXT NOT NULL,
@@ -123,8 +124,21 @@ CREATE TABLE serviceconfigmapping (
   CONSTRAINT FK_scvm_config FOREIGN KEY (config_id) REFERENCES clusterconfig(config_id),
   CONSTRAINT FK_scvm_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id));
 
+CREATE TABLE clusterservicegroups (
+  service_group_name VARCHAR(255) NOT NULL,
+  service_group_display_name VARCHAR(255) NOT NULL,
+  cluster_id BIGINT NOT NULL,
+  service_group_type VARCHAR(255) NOT NULL DEFAULT 'AMBARI',
+  assembly_file MEDIUMTEXT,
+  current_state VARCHAR(255) NOT NULL,
+  desired_state VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_clusterservicegroups PRIMARY KEY (service_group_name, cluster_id),
+  CONSTRAINT FK_clusterservicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
+
 CREATE TABLE clusterservices (
   service_name VARCHAR(255) NOT NULL,
+  stack_service_name VARCHAR(255) NOT NULL,
+  service_group_name VARCHAR(255) NOT NULL,
   cluster_id BIGINT NOT NULL,
   service_enabled INTEGER NOT NULL,
   CONSTRAINT PK_clusterservices PRIMARY KEY (service_name, cluster_id),
@@ -175,6 +189,7 @@ CREATE TABLE servicecomponentdesiredstate (
   desired_state VARCHAR(255) NOT NULL,
   service_name VARCHAR(100) NOT NULL,
   recovery_enabled SMALLINT NOT NULL DEFAULT 0,
+  desired_count INTEGER NOT NULL DEFAULT 0,
   CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
   CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id),
   CONSTRAINT FK_scds_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES stack(stack_id),
@@ -574,7 +589,7 @@ CREATE TABLE viewinstance (
   icon64 VARCHAR(255),
   xml_driven CHAR(1),
   alter_names TINYINT(1) NOT NULL DEFAULT 1,
-  cluster_handle VARCHAR(255),
+  cluster_handle BIGINT,
   cluster_type VARCHAR(100) NOT NULL DEFAULT 'LOCAL_AMBARI',
   short_url BIGINT,
   CONSTRAINT PK_viewinstance PRIMARY KEY (view_instance_id),

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index f31af16..d3d2e76 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -54,6 +54,7 @@ CREATE TABLE clusterconfig (
   version_tag VARCHAR2(255) NOT NULL,
   version NUMBER(19) NOT NULL,
   type_name VARCHAR2(255) NOT NULL,
+  stack_type_name VARCHAR2(255) NOT NULL,
   cluster_id NUMBER(19) NOT NULL,
   stack_id NUMBER(19) NOT NULL,
   config_data CLOB NOT NULL,
@@ -114,8 +115,21 @@ CREATE TABLE serviceconfigmapping (
   CONSTRAINT FK_scvm_config FOREIGN KEY (config_id) REFERENCES clusterconfig(config_id),
   CONSTRAINT FK_scvm_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id));
 
+CREATE TABLE clusterservicegroups (
+  service_group_name VARCHAR(255) NOT NULL,
+  service_group_display_name VARCHAR(255) NOT NULL,
+  cluster_id BIGINT NOT NULL,
+  service_group_type VARCHAR(255) NOT NULL DEFAULT 'AMBARI',
+  assembly_file CLOB,
+  current_state VARCHAR(255) NOT NULL,
+  desired_state VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_clusterservicegroups PRIMARY KEY (service_group_name, cluster_id),
+  CONSTRAINT FK_clusterservicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
+
 CREATE TABLE clusterservices (
   service_name VARCHAR2(255) NOT NULL,
+  stack_service_name VARCHAR(255) NOT NULL,
+  service_group_name VARCHAR(255) NOT NULL,
   cluster_id NUMBER(19) NOT NULL,
   service_enabled NUMBER(10) NOT NULL,
   CONSTRAINT PK_clusterservices PRIMARY KEY (service_name, cluster_id),
@@ -166,6 +180,7 @@ CREATE TABLE servicecomponentdesiredstate (
   desired_version VARCHAR(255) DEFAULT 'UNKNOWN' NOT NULL,
   service_name VARCHAR2(255) NOT NULL,
   recovery_enabled SMALLINT DEFAULT 0 NOT NULL,
+  desired_count INTEGER NOT NULL DEFAULT 0,
   CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
   CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id),
   CONSTRAINT FK_scds_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES stack(stack_id),
@@ -565,7 +580,7 @@ CREATE TABLE viewinstance (
   icon64 VARCHAR(255),
   xml_driven CHAR(1),
   alter_names NUMBER(1) DEFAULT 1 NOT NULL,
-  cluster_handle VARCHAR(255),
+  cluster_handle BIGINT,
   cluster_type VARCHAR(100) DEFAULT 'LOCAL_AMBARI' NOT NULL,
   short_url NUMBER,
   CONSTRAINT PK_viewinstance PRIMARY KEY (view_instance_id),

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index d1147b7..e591975 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -54,6 +54,7 @@ CREATE TABLE clusterconfig (
   version_tag VARCHAR(255) NOT NULL,
   version BIGINT NOT NULL,
   type_name VARCHAR(255) NOT NULL,
+  stack_type_name VARCHAR(255) NOT NULL,
   cluster_id BIGINT NOT NULL,
   stack_id BIGINT NOT NULL,
   config_data TEXT NOT NULL,
@@ -123,8 +124,21 @@ CREATE TABLE serviceconfigmapping (
   CONSTRAINT FK_scvm_config FOREIGN KEY (config_id) REFERENCES clusterconfig(config_id),
   CONSTRAINT FK_scvm_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id));
 
+CREATE TABLE clusterservicegroups (
+  service_group_name VARCHAR(255) NOT NULL,
+  service_group_display_name VARCHAR(255) NOT NULL,
+  cluster_id BIGINT NOT NULL,
+  service_group_type VARCHAR(255) NOT NULL DEFAULT 'AMBARI',
+  assembly_file TEXT,
+  current_state VARCHAR(255) NOT NULL,
+  desired_state VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_clusterservicegroups PRIMARY KEY (service_group_name, cluster_id),
+  CONSTRAINT FK_clusterservicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
+
 CREATE TABLE clusterservices (
   service_name VARCHAR(255) NOT NULL,
+  stack_service_name VARCHAR(255) NOT NULL,
+  service_group_name VARCHAR(100) DEFAULT 'CORE' NOT NULL,
   cluster_id BIGINT NOT NULL,
   service_enabled INTEGER NOT NULL,
   CONSTRAINT PK_clusterservices PRIMARY KEY (service_name, cluster_id),
@@ -175,6 +189,7 @@ CREATE TABLE servicecomponentdesiredstate (
   desired_state VARCHAR(255) NOT NULL,
   service_name VARCHAR(255) NOT NULL,
   recovery_enabled SMALLINT NOT NULL DEFAULT 0,
+  desired_count INTEGER NOT NULL DEFAULT 0,
   CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
   CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id),
   CONSTRAINT FK_scds_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES stack(stack_id),
@@ -566,7 +581,7 @@ CREATE TABLE viewinstance (
   icon64 VARCHAR(255),
   xml_driven CHAR(1),
   alter_names SMALLINT NOT NULL DEFAULT 1,
-  cluster_handle VARCHAR(255),
+  cluster_handle BIGINT,
   cluster_type VARCHAR(100) NOT NULL DEFAULT 'LOCAL_AMBARI',
   short_url BIGINT,
   CONSTRAINT PK_viewinstance PRIMARY KEY (view_instance_id),

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
index 5a7a6a5..087d8d8 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
@@ -73,6 +73,7 @@ CREATE TABLE ambari.clusterconfig (
   version_tag VARCHAR(255) NOT NULL,
   version BIGINT NOT NULL,
   type_name VARCHAR(255) NOT NULL,
+  stack_type_name VARCHAR(255) NOT NULL,
   cluster_id BIGINT NOT NULL,
   stack_id BIGINT NOT NULL,
   config_data TEXT NOT NULL,
@@ -154,8 +155,22 @@ CREATE TABLE ambari.serviceconfigmapping (
 );
 GRANT ALL PRIVILEGES ON TABLE ambari.serviceconfigmapping TO :username;
 
+CREATE TABLE ambari.clusterservicegroups (
+  service_group_name VARCHAR(255) NOT NULL,
+  service_group_display_name VARCHAR(255) NOT NULL,
+  cluster_id BIGINT NOT NULL,
+  service_group_type VARCHAR(255) NOT NULL DEFAULT 'AMBARI',
+  assembly_file TEXT,
+  current_state VARCHAR(255) NOT NULL,
+  desired_state VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_clusterservicegroups PRIMARY KEY (service_group_name, cluster_id),
+  CONSTRAINT FK_clusterservicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
+GRANT ALL PRIVILEGES ON TABLE ambari.clusterservicegroups TO :username;
+
 CREATE TABLE ambari.clusterservices (
   service_name VARCHAR(255) NOT NULL,
+  stack_service_name VARCHAR(255) NOT NULL,
+  service_group_name VARCHAR(255) NOT NULL,
   cluster_id BIGINT NOT NULL,
   service_enabled INTEGER NOT NULL,
   CONSTRAINT PK_clusterservices PRIMARY KEY (service_name, cluster_id),
@@ -214,6 +229,7 @@ CREATE TABLE ambari.servicecomponentdesiredstate (
   desired_state VARCHAR(255) NOT NULL,
   service_name VARCHAR(255) NOT NULL,
   recovery_enabled SMALLINT NOT NULL DEFAULT 0,
+  desired_count INTEGER NOT NULL DEFAULT 0,
   CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
   CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id),
   CONSTRAINT FK_scds_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES ambari.stack(stack_id),
@@ -667,7 +683,7 @@ CREATE TABLE ambari.viewinstance (
   icon64 VARCHAR(255),
   xml_driven CHAR(1),
   alter_names SMALLINT NOT NULL DEFAULT 1,
-  cluster_handle VARCHAR(255),
+  cluster_handle BIGINT,
   cluster_type VARCHAR(100) NOT NULL DEFAULT 'LOCAL_AMBARI',
   short_url BIGINT,
   CONSTRAINT PK_viewinstance PRIMARY KEY (view_instance_id),

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
index 2dba3b7..7e217fd 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -53,6 +53,7 @@ CREATE TABLE clusterconfig (
   version_tag VARCHAR(255) NOT NULL,
   version NUMERIC(19) NOT NULL,
   type_name VARCHAR(255) NOT NULL,
+  stack_type_name VARCHAR(255) NOT NULL,
   cluster_id NUMERIC(19) NOT NULL,
   stack_id NUMERIC(19) NOT NULL,
   config_data TEXT NOT NULL,
@@ -112,8 +113,21 @@ CREATE TABLE serviceconfigmapping (
   CONSTRAINT FK_scvm_config FOREIGN KEY (config_id) REFERENCES clusterconfig(config_id),
   CONSTRAINT FK_scvm_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id));
 
+CREATE TABLE clusterservicegroups (
+  service_group_name VARCHAR(255) NOT NULL,
+  service_group_display_name VARCHAR(255) NOT NULL,
+  cluster_id BIGINT NOT NULL,
+  service_group_type VARCHAR(255) NOT NULL DEFAULT 'AMBARI',
+  assembly_file TEXT,
+  current_state VARCHAR(255) NOT NULL,
+  desired_state VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_clusterservicegroups PRIMARY KEY (service_group_name, cluster_id),
+  CONSTRAINT FK_clusterservicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
+
 CREATE TABLE clusterservices (
   service_name VARCHAR(255) NOT NULL,
+  stack_service_name VARCHAR(255) NOT NULL,
+  service_group_name VARCHAR(255) NOT NULL,
   cluster_id NUMERIC(19) NOT NULL,
   service_enabled INTEGER NOT NULL,
   CONSTRAINT PK_clusterservices PRIMARY KEY (service_name, cluster_id),
@@ -164,6 +178,7 @@ CREATE TABLE servicecomponentdesiredstate (
   desired_state VARCHAR(255) NOT NULL,
   service_name VARCHAR(255) NOT NULL,
   recovery_enabled SMALLINT NOT NULL DEFAULT 0,
+  desired_count INTEGER NOT NULL DEFAULT 0,
   CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
   CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id),
   CONSTRAINT FK_scds_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES stack(stack_id),
@@ -563,7 +578,7 @@ CREATE TABLE viewinstance (
   icon64 VARCHAR(255),
   xml_driven CHAR(1),
   alter_names BIT NOT NULL DEFAULT 1,
-  cluster_handle VARCHAR(255),
+  cluster_handle BIGINT,
   cluster_type VARCHAR(100) NOT NULL DEFAULT 'LOCAL_AMBARI',
   short_url NUMERIC,
   CONSTRAINT PK_viewinstance PRIMARY KEY (view_instance_id),

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index e769e5b..045b5b1 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -67,6 +67,7 @@ CREATE TABLE clusterconfig (
   version_tag VARCHAR(255) NOT NULL,
   version BIGINT NOT NULL,
   type_name VARCHAR(255) NOT NULL,
+  stack_type_name VARCHAR(255) NOT NULL,
   cluster_id BIGINT NOT NULL,
   stack_id BIGINT NOT NULL,
   config_data VARCHAR(MAX) NOT NULL,
@@ -136,8 +137,21 @@ CREATE TABLE clusterconfigmapping (
   CONSTRAINT PK_clusterconfigmapping PRIMARY KEY CLUSTERED (cluster_id, type_name, create_timestamp ),
   CONSTRAINT clusterconfigmappingcluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
 
+CREATE TABLE clusterservicegroups (
+  service_group_name VARCHAR(255) NOT NULL,
+  service_group_display_name VARCHAR(255) NOT NULL,
+  cluster_id BIGINT NOT NULL,
+  service_group_type VARCHAR(255) NOT NULL DEFAULT 'AMBARI',
+  assembly_file VARCHAR(MAX),
+  current_state VARCHAR(255) NOT NULL,
+  desired_state VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_clusterservicegroups PRIMARY KEY (service_group_name, cluster_id),
+  CONSTRAINT FK_clusterservicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
+
 CREATE TABLE clusterservices (
   service_name VARCHAR(255) NOT NULL,
+  stack_service_name VARCHAR(255) NOT NULL,
+  service_group_name VARCHAR(255) NOT NULL,
   cluster_id BIGINT NOT NULL,
   service_enabled INT NOT NULL,
   CONSTRAINT PK_clusterservices PRIMARY KEY CLUSTERED (service_name, cluster_id),
@@ -188,6 +202,7 @@ CREATE TABLE servicecomponentdesiredstate (
   desired_state VARCHAR(255) NOT NULL,
   service_name VARCHAR(255) NOT NULL,
   recovery_enabled SMALLINT NOT NULL DEFAULT 0,
+  desired_count INTEGER NOT NULL DEFAULT 0,
   CONSTRAINT pk_sc_desiredstate PRIMARY KEY (id),
   CONSTRAINT unq_scdesiredstate_name UNIQUE(component_name, service_name, cluster_id),
   CONSTRAINT FK_scds_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES stack(stack_id),
@@ -573,7 +588,7 @@ CREATE TABLE viewinstance (
   icon64 VARCHAR(255),
   xml_driven CHAR(1),
   alter_names BIT NOT NULL DEFAULT 1,
-  cluster_handle VARCHAR(255),
+  cluster_handle BIGINT,
   cluster_type VARCHAR(100) NOT NULL DEFAULT 'LOCAL_AMBARI',
   short_url BIGINT,
   CONSTRAINT PK_viewinstance PRIMARY KEY CLUSTERED (view_instance_id),

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/META-INF/persistence.xml b/ambari-server/src/main/resources/META-INF/persistence.xml
index 5671dcf..46f3c5a 100644
--- a/ambari-server/src/main/resources/META-INF/persistence.xml
+++ b/ambari-server/src/main/resources/META-INF/persistence.xml
@@ -27,6 +27,7 @@
     <class>org.apache.ambari.server.orm.entities.ClusterConfigMappingEntity</class>
     <class>org.apache.ambari.server.orm.entities.ClusterEntity</class>
     <class>org.apache.ambari.server.orm.entities.ClusterServiceEntity</class>
+    <class>org.apache.ambari.server.orm.entities.ClusterServiceGroupEntity</class>
     <class>org.apache.ambari.server.orm.entities.ClusterStateEntity</class>
     <class>org.apache.ambari.server.orm.entities.ClusterVersionEntity</class>
     <class>org.apache.ambari.server.orm.entities.ConfigGroupConfigMappingEntity</class>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/resources/ambari.repo
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/ambari.repo b/ambari-server/src/main/resources/ambari.repo
new file mode 100644
index 0000000..5a58d49
--- /dev/null
+++ b/ambari-server/src/main/resources/ambari.repo
@@ -0,0 +1,8 @@
+#VERSION_NUMBER=2.4.0.0-583
+[AMBARI.2.4.0.0-2.x]
+name=Ambari 2.x
+baseurl=http://s3.amazonaws.com/dev.hortonworks.com/ambari/centos6/2.x/BUILDS/2.4.0.0-583/
+gpgcheck=1
+gpgkey=http://s3.amazonaws.com/dev.hortonworks.com/ambari/centos6/RPM-GPG-KEY/RPM-GPG-KEY-Jenkins
+enabled=1
+priority=1