You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by be...@apache.org on 2017/11/14 11:14:40 UTC

[07/17] ambari git commit: AMBARI-22345. Add service dependencies.Part 2.(vbrodetskyi)

AMBARI-22345. Add service dependencies.Part 2.(vbrodetskyi)


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

Branch: refs/heads/branch-feature-AMBARI-14714-blueprintv2
Commit: 19513a85f12fb235a01cecce12e68f405785a177
Parents: 6a78e1a
Author: Vitaly Brodetskyi <vb...@hortonworks.com>
Authored: Mon Nov 13 19:45:46 2017 +0200
Committer: Vitaly Brodetskyi <vb...@hortonworks.com>
Committed: Mon Nov 13 19:45:46 2017 +0200

----------------------------------------------------------------------
 .../server/api/services/ServiceService.java     |  22 +--
 .../controller/ServiceDependencyRequest.java    |  28 +---
 .../ServiceDependencyResourceProvider.java      | 102 ++++++------
 .../server/orm/dao/ClusterServiceDAO.java       |  16 ++
 .../orm/entities/ClusterServiceEntity.java      |  29 ++--
 .../orm/entities/ServiceDependencyEntity.java   | 154 +++++++++++++++++++
 .../org/apache/ambari/server/state/Cluster.java |   5 +-
 .../org/apache/ambari/server/state/Service.java |   5 +
 .../apache/ambari/server/state/ServiceImpl.java | 110 ++++++++++---
 .../server/state/cluster/ClusterImpl.java       |  61 +++-----
 .../main/resources/Ambari-DDL-Derby-CREATE.sql  |   8 +-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |   7 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |   7 +-
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |   7 +-
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql |  19 ++-
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |   7 +-
 .../src/main/resources/META-INF/persistence.xml |   1 +
 17 files changed, 411 insertions(+), 177 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
index 1f3332f..76782d5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
@@ -316,10 +316,10 @@ public class ServiceService extends BaseService {
           responseContainer = RESPONSE_CONTAINER_LIST)
   @ApiImplicitParams({
           @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION,
-                  defaultValue = "ServiceInfo/service_group_name, ServiceInfo/service_name, ServiceInfo/cluster_name",
+                  defaultValue = "ServiceDependencyInfo/dependency_service_id, ServiceInfo/service_group_name, ServiceInfo/service_name, ServiceInfo/cluster_name",
                   dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
           @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION,
-                  defaultValue = "ServiceInfo/service_group_name.asc, ServiceInfo/service_name.asc, ServiceInfo/cluster_name.asc",
+                  defaultValue = "ServiceDependencyInfo/dependency_service_id.asc, ServiceInfo/service_group_name.asc, ServiceInfo/service_name.asc, ServiceInfo/cluster_name.asc",
                   dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
           @ApiImplicitParam(name = QUERY_PAGE_SIZE, value = QUERY_PAGE_SIZE_DESCRIPTION, defaultValue = DEFAULT_PAGE_SIZE, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
           @ApiImplicitParam(name = QUERY_FROM, value = QUERY_FROM_DESCRIPTION, defaultValue = DEFAULT_FROM, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
@@ -336,7 +336,7 @@ public class ServiceService extends BaseService {
   }
 
   @GET
-  @Path("{serviceName}/dependencies/{dependencyServiceName}")
+  @Path("{serviceName}/dependencies/{dependencyServiceId}")
   @Produces(MediaType.TEXT_PLAIN)
   @ApiOperation(value = "Get the details of a service dependency",
           nickname = "ServiceService#getServiceDependency",
@@ -344,7 +344,7 @@ public class ServiceService extends BaseService {
           response = ServiceResponse.ServiceResponseSwagger.class,
           responseContainer = RESPONSE_CONTAINER_LIST)
   @ApiImplicitParams({
-          @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, defaultValue = "ServiceInfo/*",
+          @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, defaultValue = "ServiceDependencyInfo/*",
                   dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY)
   })
   @ApiResponses(value = {
@@ -354,9 +354,9 @@ public class ServiceService extends BaseService {
   })
   public Response getServiceDependency(String body, @Context HttpHeaders headers, @Context UriInfo ui,
                                               @PathParam("serviceName") String serviceName,
-                                              @PathParam("dependencyServiceName") String dependencyServiceName) {
+                                              @PathParam("dependencyServiceId") String dependencyServiceId) {
     return handleRequest(headers, body, ui, Request.Type.GET,
-            createServiceDependencyResource(m_clusterName, m_serviceGroupName, serviceName, dependencyServiceName));
+            createServiceDependencyResource(m_clusterName, m_serviceGroupName, serviceName, dependencyServiceId));
   }
 
 
@@ -386,7 +386,7 @@ public class ServiceService extends BaseService {
   }
 
   @DELETE
-  @Path("{serviceName}/dependencies")
+  @Path("{serviceName}/dependencies/{dependencyServiceId}")
   @Produces(MediaType.TEXT_PLAIN)
   @ApiOperation(value = "Deletes a service dependency",
           nickname = "ServiceService#deleteServiceDependency"
@@ -400,9 +400,9 @@ public class ServiceService extends BaseService {
   })
   public Response deleteServiceDependency(String body, @Context HttpHeaders headers, @Context UriInfo ui,
                                               @PathParam("serviceName") String serviceName,
-                                              @PathParam("dependencyServiceName") String dependencyServiceName) {
+                                              @PathParam("dependencyServiceId") String dependencyServiceId) {
     return handleRequest(headers, body, ui, Request.Type.DELETE,
-            createServiceDependencyResource(m_clusterName, m_serviceGroupName, serviceName, dependencyServiceName));
+            createServiceDependencyResource(m_clusterName, m_serviceGroupName, serviceName, dependencyServiceId));
   }
 
   /**
@@ -766,12 +766,12 @@ public class ServiceService extends BaseService {
     return createResource(Resource.Type.Artifact, mapIds);
   }
 
-  ResourceInstance createServiceDependencyResource(String clusterName, String serviceGroupName, String serviceName, String serviceDependencyName) {
+  ResourceInstance createServiceDependencyResource(String clusterName, String serviceGroupName, String serviceName, String serviceDependencyId) {
     Map<Resource.Type, String> mapIds = new HashMap<>();
     mapIds.put(Resource.Type.Cluster, clusterName);
     mapIds.put(Resource.Type.ServiceGroup, serviceGroupName);
     mapIds.put(Resource.Type.Service, serviceName);
-    mapIds.put(Resource.Type.ServiceDependency, serviceDependencyName);
+    mapIds.put(Resource.Type.ServiceDependency, serviceDependencyId);
 
 
     return createResource(Resource.Type.ServiceDependency, mapIds);

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceDependencyRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceDependencyRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceDependencyRequest.java
index 97fe502..6cf46b4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceDependencyRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceDependencyRequest.java
@@ -22,16 +22,13 @@ public class ServiceDependencyRequest {
   private String clusterName;
   private String serviceName;
   private String serviceGroupName;
-  private String dependencyServiceName;
-  private String dependencyServiceGroupName;
+  private Long dependencyServiceId;
 
-  public ServiceDependencyRequest(String clusterName, String serviceName, String serviceGroupName,
-                                  String dependencyServiceName, String dependencyServiceGroupName) {
+  public ServiceDependencyRequest(String clusterName, String serviceName, String serviceGroupName, Long dependencyServiceId) {
     this.clusterName = clusterName;
     this.serviceName = serviceName;
     this.serviceGroupName = serviceGroupName;
-    this.dependencyServiceName = dependencyServiceName;
-    this.dependencyServiceGroupName = dependencyServiceGroupName;
+    this.dependencyServiceId = dependencyServiceId;
   }
 
   public String getClusterName() {
@@ -42,12 +39,12 @@ public class ServiceDependencyRequest {
     this.clusterName = clusterName;
   }
 
-  public String getDependencyServiceName() {
-    return dependencyServiceName;
+  public Long getDependencyServiceId() {
+    return dependencyServiceId;
   }
 
-  public void setDependencyServiceName(String dependencyServiceName) {
-    this.dependencyServiceName = dependencyServiceName;
+  public void setDependencyServiceId(Long dependencyServiceId) {
+    this.dependencyServiceId = dependencyServiceId;
   }
 
   public String getServiceGroupName() {
@@ -66,22 +63,13 @@ public class ServiceDependencyRequest {
     this.serviceName = serviceName;
   }
 
-  public String getDependencyServiceGroupName() {
-    return dependencyServiceGroupName;
-  }
-
-  public void setDependencyServiceGroupName(String dependencyServiceGroupName) {
-    this.dependencyServiceGroupName = dependencyServiceGroupName;
-  }
-
   @Override
   public String toString() {
     return "ServiceDependencyRequest{" +
             "clusterName='" + clusterName + '\'' +
             ", serviceName='" + serviceName + '\'' +
             ", serviceGroupName='" + serviceGroupName + '\'' +
-            ", dependencyServiceName='" + dependencyServiceName + '\'' +
-            ", dependencyServiceGroupName='" + dependencyServiceGroupName + '\'' +
+            ", dependencyServiceId=" + dependencyServiceId +
             '}';
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceDependencyResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceDependencyResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceDependencyResourceProvider.java
index d8d89da..dd48875 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceDependencyResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceDependencyResourceProvider.java
@@ -28,13 +28,11 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.ClusterNotFoundException;
 import org.apache.ambari.server.ObjectNotFoundException;
 import org.apache.ambari.server.ParentObjectNotFoundException;
 import org.apache.ambari.server.ServiceGroupNotFoundException;
 import org.apache.ambari.server.api.services.ServiceKey;
 import org.apache.ambari.server.controller.AmbariManagementController;
-import org.apache.ambari.server.controller.KerberosHelper;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.ServiceDependencyRequest;
 import org.apache.ambari.server.controller.ServiceDependencyResponse;
@@ -62,7 +60,6 @@ import org.apache.commons.lang.Validate;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.Gson;
-import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import com.google.inject.assistedinject.AssistedInject;
 
@@ -93,7 +90,7 @@ public class ServiceDependencyResourceProvider extends AbstractControllerResourc
                   SERVICE_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID,
                   SERVICE_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID,
                   SERVICE_DEPENDENCY_SERVICE_NAME_PROPERTY_ID,
-                  SERVICE_DEPENDENCY_DEPENDENCY_SERVICE_NAME_PROPERTY_ID}));
+                  SERVICE_DEPENDENCY_DEPENDENCY_SERVICE_ID_PROPERTY_ID}));
 
   private static Gson gson = StageUtils.getGson();
 
@@ -126,16 +123,11 @@ public class ServiceDependencyResourceProvider extends AbstractControllerResourc
     KEY_PROPERTY_IDS.put(Resource.Type.Cluster, SERVICE_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID);
     KEY_PROPERTY_IDS.put(Resource.Type.Service, SERVICE_DEPENDENCY_SERVICE_NAME_PROPERTY_ID);
     KEY_PROPERTY_IDS.put(Resource.Type.ServiceGroup, SERVICE_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID);
-    KEY_PROPERTY_IDS.put(Resource.Type.ServiceDependency, SERVICE_DEPENDENCY_DEPENDENCY_SERVICE_NAME_PROPERTY_ID);
+    KEY_PROPERTY_IDS.put(Resource.Type.ServiceDependency, SERVICE_DEPENDENCY_DEPENDENCY_SERVICE_ID_PROPERTY_ID);
   }
 
   private Clusters clusters;
 
-  /**
-   * kerberos helper
-   */
-  @Inject
-  private KerberosHelper kerberosHelper;
 
   // ----- Constructors ----------------------------------------------------
 
@@ -291,7 +283,7 @@ public class ServiceDependencyResourceProvider extends AbstractControllerResourc
     notifyDelete(Resource.Type.ServiceDependency, predicate);
     for(ServiceDependencyRequest svgReq : requests) {
       deleteStatusMetaData.addDeletedKey("cluster_name: " + svgReq.getClusterName() + ", " + " service_name: " + svgReq.getServiceName()
-              + " dependency_service_name: " + svgReq.getDependencyServiceName());
+              + " dependency_service_ID: " + svgReq.getDependencyServiceId());
     }
     return getRequestStatus(null, null, deleteStatusMetaData);
   }
@@ -327,10 +319,9 @@ public class ServiceDependencyResourceProvider extends AbstractControllerResourc
     String clusterName = (String) properties.get(SERVICE_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID);
     String serviceName = (String) properties.get(SERVICE_DEPENDENCY_SERVICE_NAME_PROPERTY_ID);
     String serviceGroupName = (String) properties.get(SERVICE_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID);
-    String dependencyServiceName = (String) properties.get(SERVICE_DEPENDENCY_DEPENDENCY_SERVICE_NAME_PROPERTY_ID);
-    String dependencyServiceGroupName = (String) properties.get(SERVICE_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID);
-    ServiceDependencyRequest svcRequest = new ServiceDependencyRequest(clusterName, serviceName, serviceGroupName,
-                                                                       dependencyServiceName, dependencyServiceGroupName);
+    String strdependencyServiceId = (String) properties.get(SERVICE_DEPENDENCY_DEPENDENCY_SERVICE_ID_PROPERTY_ID);
+    Long dependencyServiceId = strdependencyServiceId == null ? null : Long.valueOf(strdependencyServiceId);
+    ServiceDependencyRequest svcRequest = new ServiceDependencyRequest(clusterName, serviceName, serviceGroupName, dependencyServiceId);
     return svcRequest;
   }
 
@@ -353,9 +344,8 @@ public class ServiceDependencyResourceProvider extends AbstractControllerResourc
       Cluster cluster = clusters.getCluster(request.getClusterName());
 
 
-      Service updatedService = cluster.addDependencyToService(request.getServiceGroupName(), request.getServiceName(), request.getDependencyServiceGroupName(),
-              request.getDependencyServiceName());
-      createdServiceDependencies.addAll(updatedService.getServiceDependencyResponses());   //!!!!!
+      Service updatedService = cluster.addDependencyToService(request.getServiceGroupName(), request.getServiceName(), request.getDependencyServiceId());
+      createdServiceDependencies.addAll(updatedService.getServiceDependencyResponses());
     }
     return createdServiceDependencies;
   }
@@ -403,7 +393,8 @@ public class ServiceDependencyResourceProvider extends AbstractControllerResourc
       Collection<Service> services = cluster.getServices().values();
       Service currentService = null;
       for (Service service : services) {
-        if (service.getServiceGroupId() == serviceGroup.getServiceGroupId()) {
+        if (service.getServiceGroupId() == serviceGroup.getServiceGroupId() &&
+                service.getName().equals(request.getServiceName())) {
           currentService = service;
           break;
         }
@@ -416,7 +407,6 @@ public class ServiceDependencyResourceProvider extends AbstractControllerResourc
   }
 
 
-  // Delete services based on the given set of requests
   protected void deleteServiceDependencies(Set<ServiceDependencyRequest> request)
           throws AmbariException, AuthorizationException {
 
@@ -437,7 +427,17 @@ public class ServiceDependencyResourceProvider extends AbstractControllerResourc
         }
 
         Cluster cluster = clusters.getCluster(serviceDependencyRequest.getClusterName());
-        Service service = cluster.getService(serviceDependencyRequest.getServiceName());
+        ServiceGroup serviceGroup = cluster.getServiceGroup(serviceDependencyRequest.getServiceGroupName());
+        Service service = null;
+
+        for (Service srv : cluster.getServicesById().values()) {
+          if (srv.getName().equals(serviceDependencyRequest.getServiceName()) &&
+                  srv.getServiceGroupName().equals(serviceDependencyRequest.getServiceGroupName())) {
+            service = srv;
+            break;
+          }
+        }
+
         List<ServiceKey> serviceKeys = service.getServiceDependencies();
         if (serviceKeys == null || serviceKeys.isEmpty()) {
           throw new AmbariException("Service name " + serviceDependencyRequest.getServiceName() + " has no" +
@@ -445,17 +445,17 @@ public class ServiceDependencyResourceProvider extends AbstractControllerResourc
         } else {
           boolean dependencyAvailable = false;
           for (ServiceKey serviceKey : serviceKeys) {
-            if (serviceKey.getServiceName().equals(serviceDependencyRequest.getDependencyServiceName())) {
+            if (serviceKey.getServiceId() == serviceDependencyRequest.getDependencyServiceId()) {
               dependencyAvailable = true;
             }
           }
           if (!dependencyAvailable) {
             throw new AmbariException("Servcie name " + serviceDependencyRequest.getServiceName() + " has no" +
-                    "dependency " + serviceDependencyRequest.getDependencyServiceName() + ", so nothing to remove.");
+                    "dependency service with id" + serviceDependencyRequest.getDependencyServiceId() + ", so nothing to remove.");
           }
 
           service.getCluster().removeDependencyFromService(serviceDependencyRequest.getServiceGroupName(), serviceDependencyRequest.getServiceName(),
-                  serviceDependencyRequest.getDependencyServiceGroupName(), serviceDependencyRequest.getDependencyServiceName());
+                  serviceDependencyRequest.getDependencyServiceId());
         }
       }
     }
@@ -470,24 +470,34 @@ public class ServiceDependencyResourceProvider extends AbstractControllerResourc
     for (ServiceDependencyRequest request : requests) {
       final String clusterName = request.getClusterName();
       final String serviceGroupName = request.getServiceGroupName();
-      final String dependencyServiceGroupName = request.getDependencyServiceGroupName();
-
-      Validate.notNull(clusterName, "Cluster name should be provided when creating a service group");
-
-      // validating service group dependencies
-      if (StringUtils.isEmpty(dependencyServiceGroupName)) {
-        throw new AmbariException("Service group name is empty or null!");
-      } else {
-        Cluster cluster = clusters.getCluster(clusterName);
-        //throws service group not found exception
-        ServiceGroup serviceGroup = cluster.getServiceGroup(dependencyServiceGroupName);
-
+      final String serviceName = request.getServiceName();
+      final Long dependencyServiceId = request.getDependencyServiceId();
+
+      Validate.notNull(clusterName, "Cluster name should be provided when creating a service dependency");
+      Validate.notNull(serviceGroupName, "Service group name should be provided when creating a service dependency");
+      Validate.notNull(serviceName, "Service name should be provided when creating a service dependency");
+      Validate.notNull(dependencyServiceId, "Dependency service id should be provided when creating a service dependency");
+
+      //throws cluster not found exception
+      Cluster cluster = clusters.getCluster(clusterName);
+      //throws service group not found exception
+      ServiceGroup serviceGroup = cluster.getServiceGroup(serviceGroupName);
+      //throws service not found exception
+      Service service = cluster.getService(serviceName);
+
+      boolean dependencyServiceAvailable = false;
+      for (Cluster cl : clusters.getClusters().values()) {
+        if (cl.getServicesById().containsKey(dependencyServiceId)) {
+          dependencyServiceAvailable = true;
+        }
       }
 
-      Validate.notEmpty(serviceGroupName, "Service group name should be provided when adding a service group dependency");
+      if (!dependencyServiceAvailable) {
+        throw new AmbariException("There is no service with id=" + dependencyServiceId);
+      }
 
       if (LOG.isDebugEnabled()) {
-        LOG.debug("Received a createServiceGroupDependency request" +
+        LOG.debug("Received a createServiceDependency request" +
                 ", clusterName=" + clusterName + ", serviceGroupName=" + serviceGroupName + ", request=" + request);
       }
 
@@ -497,15 +507,15 @@ public class ServiceDependencyResourceProvider extends AbstractControllerResourc
       }
 
 
-      Cluster cluster;
-      try {
-        cluster = clusters.getCluster(clusterName);
-      } catch (ClusterNotFoundException e) {
-        throw new ParentObjectNotFoundException("Attempted to add a service group to a cluster which doesn't exist", e);
-      }
-
-
+      if (service.getServiceDependencies() != null) {
+        for (ServiceKey sk : service.getServiceDependencies()) {
+          if (sk.getServiceId() == dependencyServiceId) {
+            throw new AmbariException("Service with id=" + dependencyServiceId + " already added to dependencies for " +
+                    serviceName + " service");
+          }
+        }
 
+      }
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterServiceDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterServiceDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterServiceDAO.java
index c7032aa..5bb1da7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterServiceDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterServiceDAO.java
@@ -27,6 +27,7 @@ import javax.persistence.TypedQuery;
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
 import org.apache.ambari.server.orm.entities.ClusterServiceEntityPK;
+import org.apache.ambari.server.orm.entities.ServiceDependencyEntity;
 
 import com.google.inject.Inject;
 import com.google.inject.Provider;
@@ -92,16 +93,31 @@ public class ClusterServiceDAO {
   }
 
   @Transactional
+  public void createServiceDependency(ServiceDependencyEntity serviceDependencyEntity) {
+    entityManagerProvider.get().persist(serviceDependencyEntity);
+  }
+
+  @Transactional
   public ClusterServiceEntity merge(ClusterServiceEntity clusterServiceEntity) {
     return entityManagerProvider.get().merge(clusterServiceEntity);
   }
 
   @Transactional
+  public ServiceDependencyEntity mergeServiceDependency(ServiceDependencyEntity serviceDependencyEntity) {
+    return entityManagerProvider.get().merge(serviceDependencyEntity);
+  }
+
+  @Transactional
   public void remove(ClusterServiceEntity clusterServiceEntity) {
     entityManagerProvider.get().remove(merge(clusterServiceEntity));
   }
 
   @Transactional
+  public void removeServiceDependency(ServiceDependencyEntity serviceDependencyEntity) {
+    entityManagerProvider.get().remove(mergeServiceDependency(serviceDependencyEntity));
+  }
+
+  @Transactional
   public void removeByPK(ClusterServiceEntityPK clusterServiceEntityPK) {
     ClusterServiceEntity entity = findByPK(clusterServiceEntityPK);
     entityManagerProvider.get().remove(entity);

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
index e5a1618..843aa1e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterServiceEntity.java
@@ -30,8 +30,6 @@ import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.JoinColumns;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
 import javax.persistence.ManyToOne;
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
@@ -105,20 +103,11 @@ public class ClusterServiceEntity {
   @OneToMany(mappedBy = "clusterServiceEntity")
   private Collection<ServiceComponentDesiredStateEntity> serviceComponentDesiredStateEntities;
 
-  @ManyToMany
-  @JoinTable(
-    name = "servicedependencies",
-    joinColumns = {@JoinColumn(name = "service_id", referencedColumnName = "id", nullable = false, insertable = true, updatable = true),
-            @JoinColumn(name = "service_cluster_id", referencedColumnName = "cluster_id", nullable = false, insertable = false, updatable = false),
-            @JoinColumn(name = "service_group_id", referencedColumnName = "service_group_id", nullable = false, insertable = false, updatable = false)},
-    inverseJoinColumns = {@JoinColumn(name = "dependent_service_id", referencedColumnName = "id", nullable = false, insertable = true, updatable = true),
-            @JoinColumn(name = "dependent_service_cluster_id", referencedColumnName = "cluster_id", nullable = false, insertable = false, updatable = false),
-            @JoinColumn(name = "dependent_service_group_id", referencedColumnName = "service_group_id", nullable = false, insertable = false, updatable = false)}
-  )
-  private List<ClusterServiceEntity> serviceDependencies;
-
-  @ManyToMany(mappedBy="serviceDependencies")
-  private List<ClusterServiceEntity> dependencies;
+  @OneToMany(mappedBy="service")
+  private List<ServiceDependencyEntity> serviceDependencies;
+
+  @OneToMany(mappedBy="serviceDependency")
+  private List<ServiceDependencyEntity> dependencies;
 
   public Long getClusterId() {
     return clusterId;
@@ -168,19 +157,19 @@ public class ClusterServiceEntity {
     this.serviceEnabled = serviceEnabled;
   }
 
-  public List<ClusterServiceEntity> getDependencies() {
+  public List<ServiceDependencyEntity> getDependencies() {
     return dependencies;
   }
 
-  public void setDependencies(List<ClusterServiceEntity> dependencies) {
+  public void setDependencies(List<ServiceDependencyEntity> dependencies) {
     this.dependencies = dependencies;
   }
 
-  public List<ClusterServiceEntity> getServiceDependencies() {
+  public List<ServiceDependencyEntity> getServiceDependencies() {
     return serviceDependencies;
   }
 
-  public void setServiceDependencies(List<ClusterServiceEntity> serviceDependencies) {
+  public void setServiceDependencies(List<ServiceDependencyEntity> serviceDependencies) {
     this.serviceDependencies = serviceDependencies;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceDependencyEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceDependencyEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceDependencyEntity.java
new file mode 100644
index 0000000..47dc435
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceDependencyEntity.java
@@ -0,0 +1,154 @@
+/*
+ * 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.orm.entities;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+
+@Entity
+@Table(name = "servicedependencies")
+@TableGenerator(name = "service_dependency_id_generator",
+        table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value"
+        , pkColumnValue = "service_dependency_id_seq"
+        , initialValue = 1
+)
+public class ServiceDependencyEntity {
+
+  @Id
+  @Column(name = "id", nullable = false, insertable = true, updatable = true)
+  @GeneratedValue(strategy = GenerationType.TABLE, generator = "service_dependency_id_generator")
+  private Long serviceDependencyId;
+
+  @Column(name = "service_id", nullable = false, insertable = false, updatable = false)
+  private long serviceId;
+
+  @Column(name = "service_cluster_id", nullable = false, insertable = false, updatable = false)
+  private long serviceClusterId;
+
+  @Column(name = "service_group_id", nullable = false, insertable = false, updatable = false)
+  private long serviceGroupId;
+
+  @Column(name = "dependent_service_id", nullable = false, insertable = false, updatable = false)
+  private long dependentServiceId;
+
+  @Column(name = "dependent_service_group_id", nullable = false, insertable = false, updatable = false)
+  private long dependentServiceGroupId;
+
+  @Column(name = "dependent_service_cluster_id", nullable = false, insertable = false, updatable = false)
+  private long dependentServiceClusterId;
+
+  @ManyToOne
+  @JoinColumns({
+          @JoinColumn(name = "service_id", referencedColumnName = "id", nullable = false),
+          @JoinColumn(name = "service_cluster_id", referencedColumnName = "cluster_id", nullable = false),
+          @JoinColumn(name = "service_group_id", referencedColumnName = "service_group_id", nullable = false) })
+  private ClusterServiceEntity service;
+
+  @ManyToOne
+  @JoinColumns({
+          @JoinColumn(name = "dependent_service_id", referencedColumnName = "id", nullable = false),
+          @JoinColumn(name = "dependent_service_cluster_id", referencedColumnName = "cluster_id", nullable = false),
+          @JoinColumn(name = "dependent_service_group_id", referencedColumnName = "service_group_id", nullable = false) })
+  private ClusterServiceEntity serviceDependency;
+
+  public Long getServiceDependencyId() {
+    return serviceDependencyId;
+  }
+
+  public long getDependentServiceGroupId() {
+    return dependentServiceGroupId;
+  }
+
+  public void setDependentServiceGroupId(long dependentServiceGroupId) {
+    this.dependentServiceGroupId = dependentServiceGroupId;
+  }
+
+  public long getDependentServiceId() {
+    return dependentServiceId;
+  }
+
+  public void setDependentServiceId(long dependentServiceId) {
+    this.dependentServiceId = dependentServiceId;
+  }
+
+  public long getDependentServiceClusterId() {
+    return dependentServiceClusterId;
+  }
+
+  public void setDependentServiceClusterId(long dependentServiceClusterId) {
+    this.dependentServiceClusterId = dependentServiceClusterId;
+  }
+
+  public ClusterServiceEntity getService() {
+    return service;
+  }
+
+  public void setService(ClusterServiceEntity service) {
+    this.service = service;
+  }
+
+  public ClusterServiceEntity getServiceDependency() {
+    return serviceDependency;
+  }
+
+  public void setServiceDependency(ClusterServiceEntity serviceDependency) {
+    this.serviceDependency = serviceDependency;
+  }
+
+  public long getServiceGroupId() {
+    return serviceGroupId;
+  }
+
+  public void setServiceGroupId(long serviceGroupId) {
+    this.serviceGroupId = serviceGroupId;
+  }
+
+  public long getServiceId() {
+    return serviceId;
+  }
+
+  public void setServiceId(long serviceId) {
+    this.serviceId = serviceId;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof ServiceDependencyEntity)) return false;
+
+    ServiceDependencyEntity that = (ServiceDependencyEntity) o;
+
+    if (serviceDependencyId != null ? !serviceDependencyId.equals(that.serviceDependencyId) : that.serviceDependencyId != null)
+      return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return serviceDependencyId != null ? serviceDependencyId.hashCode() : 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
index 2afb428..c8768dd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
@@ -75,10 +75,9 @@ public interface Cluster {
                      RepositoryVersionEntity repositoryVersion) throws AmbariException;
 
   Service addDependencyToService(String  serviceGroupName, String serviceName,
-                                        String dependencyServiceGroupName, String dependencyServiceName);
+                                        Long dependencyServiceId) throws AmbariException;
 
-  Service removeDependencyFromService(String  serviceGroupName, String serviceName, String dependencyServiceGroupName,
-                                      String dependencyServiceName);
+  Service removeDependencyFromService(String  serviceGroupName, String serviceName, Long dependencyServiceId);
 
   /**
    * Add service group to the cluster

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/ambari-server/src/main/java/org/apache/ambari/server/state/Service.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Service.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Service.java
index c4c2d84..0ba80cc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Service.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Service.java
@@ -26,6 +26,7 @@ import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.ServiceKey;
 import org.apache.ambari.server.controller.ServiceDependencyResponse;
 import org.apache.ambari.server.controller.ServiceResponse;
+import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 
 public interface Service {
@@ -88,6 +89,10 @@ public interface Service {
 
   boolean isClientOnlyService();
 
+  ClusterServiceEntity removeDependencyService(Long dependencyServiceId);
+
+  ClusterServiceEntity addDependencyService(Long dependencyServiceId) throws AmbariException;
+
   void delete() throws AmbariException;
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
index bfb04be..c6b187a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
@@ -53,6 +53,7 @@ import org.apache.ambari.server.orm.entities.ClusterServiceEntityPK;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
+import org.apache.ambari.server.orm.entities.ServiceDependencyEntity;
 import org.apache.ambari.server.orm.entities.ServiceDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.ServiceDesiredStateEntityPK;
 import org.apache.ambari.server.orm.entities.ServiceGroupEntity;
@@ -85,6 +86,9 @@ public class ServiceImpl implements Service {
   private AmbariMetaInfo ambariMetaInfo;
 
   @Inject
+  private Clusters clusters;
+
+  @Inject
   private ServiceConfigDAO serviceConfigDAO;
 
   private final ClusterServiceDAO clusterServiceDAO;
@@ -144,19 +148,27 @@ public class ServiceImpl implements Service {
 
     if (serviceDependencies != null) {
       for (ServiceKey serviceKey : serviceDependencies) {
-        Cluster dependencyCluster = cluster;
-        ServiceGroup dependencyServiceGroup = dependencyCluster.getServiceGroup(serviceKey.getServiceGroupName());
-        ServiceGroupEntity dependencyServiceGroupEntity = serviceGroupDAO.findByClusterAndServiceGroupIds(dependencyCluster.getClusterId(),
-                dependencyServiceGroup.getServiceGroupId());
-
-        for (Service service : dependencyCluster.getServices().values()) {
-          if (service.getName().equals(serviceName) && service.getServiceGroupId() == dependencyServiceGroup.getServiceGroupId()) {
-            serviceEntity.getServiceDependencies().add(clusterServiceDAO.findById(dependencyCluster.getClusterId(),
-                    dependencyServiceGroup.getServiceGroupId(), service.getServiceId()));
+
+        Cluster dependencyCluster = null;
+
+        for (Cluster cl : clusters.getClusters().values()) {
+          if (cl.getServicesById().containsKey(serviceKey.getServiceId())) {
+            dependencyCluster = cl;
+
             break;
           }
         }
 
+
+        ClusterServiceEntity dependencyServiceEntity = clusterServiceDAO.findById(serviceKey.getClusterId(), serviceKey.getServiceGroupId(), serviceKey.getServiceId());
+        ServiceDependencyEntity serviceDependencyEntity = new ServiceDependencyEntity();
+        serviceDependencyEntity.setService(serviceEntity);
+        serviceDependencyEntity.setServiceDependency(dependencyServiceEntity);
+
+        clusterServiceDAO.createServiceDependency(serviceDependencyEntity);
+
+        serviceEntity.getServiceDependencies().add(serviceDependencyEntity);
+
       }
     }
 
@@ -235,6 +247,8 @@ public class ServiceImpl implements Service {
   }
 
 
+
+
   /***
    * Refresh Service info due to current stack
    * @throws AmbariException
@@ -356,38 +370,39 @@ public class ServiceImpl implements Service {
     return responses;
   }
 
-  public List<ServiceKey> getServiceDependencies(List<ClusterServiceEntity> clusterServiceEntities) throws AmbariException {
+  public List<ServiceKey> getServiceDependencies(List<ServiceDependencyEntity> serviceDependencyEntities) throws AmbariException {
     List<ServiceKey> serviceDependenciesList = new ArrayList<>();
 
-    if (clusterServiceEntities != null) {
-      for (ClusterServiceEntity cse : clusterServiceEntities) {
+    if (serviceDependencyEntities != null) {
+      for (ServiceDependencyEntity sde : serviceDependencyEntities) {
         ServiceKey serviceKey = new ServiceKey();
+        ClusterServiceEntity dependencyService = sde.getServiceDependency();
         String clusterName = "";
         Long clusterId = null;
-        if (cse.getClusterId() == cluster.getClusterId()) {
+        if (dependencyService.getClusterId() == cluster.getClusterId()) {
           clusterName = cluster.getClusterName();
           clusterId = cluster.getClusterId();
         } else {
-          ClusterEntity clusterEntity = clusterDAO.findById(cse.getClusterId());
+          ClusterEntity clusterEntity = clusterDAO.findById(dependencyService.getClusterId());
           if (clusterEntity != null) {
             clusterName = clusterEntity.getClusterName();
             clusterId = clusterEntity.getClusterId();
           } else {
-            LOG.error("Unable to get cluster id for service " + cse.getServiceName());
+            LOG.error("Unable to get cluster id for service " + dependencyService.getServiceName());
           }
         }
 
 
         Cluster dependencyCluster = cluster;
-        ServiceGroup dependencyServiceGroup = dependencyCluster.getServiceGroup(cse.getServiceGroupId());
+        ServiceGroup dependencyServiceGroup = dependencyCluster.getServiceGroup(dependencyService.getServiceGroupId());
 
 
         serviceKey.setServiceGroupName(dependencyServiceGroup.getServiceGroupName());
         serviceKey.setServiceGroupId(dependencyServiceGroup.getServiceGroupId());
         serviceKey.setClusterName(clusterName);
         serviceKey.setClusterId(clusterId);
-        serviceKey.setServiceName(cse.getServiceName());
-        serviceKey.setServiceId(cse.getServiceId());
+        serviceKey.setServiceName(dependencyService.getServiceName());
+        serviceKey.setServiceId(dependencyService.getServiceId());
         serviceDependenciesList.add(serviceKey);
       }
     }
@@ -567,6 +582,65 @@ public class ServiceImpl implements Service {
   }
 
   @Override
+  public ClusterServiceEntity removeDependencyService(Long dependencyServiceId) {
+    ClusterServiceEntity currentServiceEntity = clusterServiceDAO.findById(getClusterId(), getServiceGroupId(), getServiceId());
+
+    ServiceDependencyEntity dependencyEntityToRemove = null;
+    if (currentServiceEntity.getServiceDependencies() != null) {
+      for (ServiceDependencyEntity sde : currentServiceEntity.getServiceDependencies()) {
+        if (sde.getServiceDependency().getServiceId() == dependencyServiceId) {
+          dependencyEntityToRemove = sde;
+          break;
+        }
+      }
+    }
+
+    currentServiceEntity.getServiceDependencies().remove(dependencyEntityToRemove);
+    ClusterServiceEntity updatedServiceEntity = removeServiceDependencyEntity(dependencyEntityToRemove, currentServiceEntity);
+    currentServiceEntity.getServiceDependencies().remove(dependencyEntityToRemove);
+
+    return updatedServiceEntity;
+  }
+
+  @Transactional
+  protected ClusterServiceEntity removeServiceDependencyEntity(ServiceDependencyEntity dependencyEntityToRemove,
+                                                               ClusterServiceEntity currentServiceEntity) {
+    clusterServiceDAO.removeServiceDependency(dependencyEntityToRemove);
+    ClusterServiceEntity updatedServiceEntity = clusterServiceDAO.merge(currentServiceEntity);
+    return updatedServiceEntity;
+  }
+
+  @Override
+  public ClusterServiceEntity addDependencyService(Long dependencyServiceId) throws AmbariException {
+    Service dependentService = null;
+    for (Cluster cl : clusters.getClusters().values()) {
+      if (cl.getServicesById().containsKey(dependencyServiceId)) {
+        dependentService = cl.getService(dependencyServiceId);
+        break;
+      }
+    }
+
+    ClusterServiceEntity currentServiceEntity = clusterServiceDAO.findById(getClusterId(), getServiceGroupId(), getServiceId());
+    ClusterServiceEntity dependentServiceEntity = clusterServiceDAO.findById(dependentService.getClusterId(),
+            dependentService.getServiceGroupId(), dependentService.getServiceId());
+
+    ServiceDependencyEntity newServiceDependency = new ServiceDependencyEntity();
+    newServiceDependency.setService(currentServiceEntity);
+    newServiceDependency.setServiceDependency(dependentServiceEntity);
+
+    return addServiceDependencyEntity(newServiceDependency, currentServiceEntity);
+  }
+
+  @Transactional
+  protected ClusterServiceEntity addServiceDependencyEntity(ServiceDependencyEntity newServiceDependency,
+                                                               ClusterServiceEntity currentServiceEntity) {
+    clusterServiceDAO.createServiceDependency(newServiceDependency);
+    currentServiceEntity.getServiceDependencies().add(newServiceDependency);
+    ClusterServiceEntity updatedServiceEntity = clusterServiceDAO.merge(currentServiceEntity);
+    return updatedServiceEntity;
+  }
+
+  @Override
   public void debugDump(StringBuilder sb) {
     sb.append("Service={ serviceName=").append(getName())
       .append(", serviceType=").append(getServiceType())

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/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 4a8cdee..e3b5d6e 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
@@ -939,36 +939,27 @@ public class ClusterImpl implements Cluster {
   }
 
   @Override
-  public Service addDependencyToService(String  serviceGroupName, String serviceName, String dependencyServiceGroupName,
-                                        String dependencyServiceName) {
+  public Service addDependencyToService(String  serviceGroupName, String serviceName, Long dependencyServiceId) throws AmbariException {
     Service currentService = null;
-    Service dependentService = null;
-    for (Service service : services.values()) {
-
+    for (Service service : getServicesById().values()) {
       if (service.getName().equals(serviceName) && service.getServiceGroupName().equals(serviceGroupName)) {
         currentService = service;
       }
-
-      if (service.getName().equals(dependencyServiceName) && service.getServiceGroupName().equals(dependencyServiceGroupName)) {
-        dependentService = service;
-      }
     }
 
+    ClusterServiceEntity updatedServiceEntity = null;
     Service updatedService = null;
     clusterGlobalLock.writeLock().lock();
     try {
-      ClusterServiceEntity currentServiceEntity = clusterServiceDAO.findById(getClusterId(),
-              currentService.getServiceGroupId(), currentService.getServiceId());
-      ClusterServiceEntity dependentServiceEntity = clusterServiceDAO.findById(getClusterId(),
-              dependentService.getServiceGroupId(), dependentService.getServiceId());
 
-      currentServiceEntity.getServiceDependencies().add(dependentServiceEntity);
-      ClusterServiceEntity updatedServiceEntity = clusterServiceDAO.merge(currentServiceEntity);
-      updatedService = serviceFactory.createExisting(this, getServiceGroup(currentService.getServiceGroupName()),
-                                                      updatedServiceEntity);
+      updatedServiceEntity = currentService.addDependencyService(dependencyServiceId);
+
+
+      updatedService = serviceFactory.createExisting(this, getServiceGroup(currentService.getServiceGroupName()), updatedServiceEntity);
       addService(updatedService);
     } catch (ServiceGroupNotFoundException e) {
-      e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+      LOG.error("Service group " + currentService.getServiceGroupName() + " was not found.");
+      e.printStackTrace();
     } finally {
       clusterGlobalLock.writeLock().unlock();
     }
@@ -977,40 +968,28 @@ public class ClusterImpl implements Cluster {
   }
 
   @Override
-  public Service removeDependencyFromService(String  serviceGroupName, String serviceName, String dependencyServiceGroupName,
-                                        String dependencyServiceName) {
-    Service currentService = null;
-
-    for (Service service : services.values()) {
-
-      if (service.getName().equals(serviceName) && service.getServiceGroupName().equals(serviceGroupName)) {
-        currentService = service;
-      }
-
-    }
-
+  public Service removeDependencyFromService(String  serviceGroupName, String serviceName, Long dependencyServiceId) {
     Service updatedService = null;
+    Service currentService = null;
     clusterGlobalLock.writeLock().lock();
     try {
-      ClusterServiceEntity currentServiceEntity = clusterServiceDAO.findById(getClusterId(),
-              currentService.getServiceGroupId(), currentService.getServiceId());
 
+      for (Service service : getServicesById().values()) {
 
-
-      ClusterServiceEntity serviceEntityToRemove = null;
-      for (ClusterServiceEntity cse : currentServiceEntity.getServiceDependencies()) {
-        if (cse.getServiceName().equals(dependencyServiceName) /*&& cse.getClusterServiceGroupEntity().getServiceGroupName().equals(dependencyServiceGroupName)*/) {
-          serviceEntityToRemove = cse;
-          break;
+        if (service.getName().equals(serviceName) && service.getServiceGroupName().equals(serviceGroupName)) {
+          currentService = service;
         }
+
       }
-      currentServiceEntity.getServiceDependencies().remove(serviceEntityToRemove);
-      ClusterServiceEntity updatedServiceEntity = clusterServiceDAO.merge(currentServiceEntity);
+
+      ClusterServiceEntity updatedServiceEntity = currentService.removeDependencyService(dependencyServiceId);
+
       updatedService = serviceFactory.createExisting(this, getServiceGroup(currentService.getServiceGroupName()),
               updatedServiceEntity);
       addService(updatedService);
     } catch (ServiceGroupNotFoundException e) {
-      e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+      LOG.error("Service group " + currentService.getServiceGroupName() + " was not found.");
+      e.printStackTrace();
     } finally {
       clusterGlobalLock.writeLock().unlock();
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/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 06f3387..0ddade4 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -183,14 +183,16 @@ CREATE TABLE clusterconfig (
 
 
 CREATE TABLE servicedependencies (
+  id BIGINT NOT NULL,
   service_id BIGINT NOT NULL,
   service_group_id BIGINT NOT NULL,
   service_cluster_id BIGINT NOT NULL,
   dependent_service_id BIGINT NOT NULL,
   dependent_service_group_id BIGINT NOT NULL,
   dependent_service_cluster_id BIGINT NOT NULL,
-  CONSTRAINT PK_servicedependencies PRIMARY KEY (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
-  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id));
+  CONSTRAINT PK_servicedependencies PRIMARY KEY (id),
+  CONSTRAINT UQ_servicedependencies UNIQUE (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
+  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id),
   CONSTRAINT FK_servicedependencies_dependent_service_group_cluster_id FOREIGN KEY (dependent_service_id, dependent_service_group_id, dependent_service_cluster_id) REFERENCES clusterservices (id, service_group_id, cluster_id));
 
 CREATE TABLE serviceconfig (
@@ -1162,6 +1164,8 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value)
   UNION ALL
   SELECT 'service_group_dependency_id_seq', 1 FROM SYSIBM.SYSDUMMY1
   UNION ALL
+  SELECT 'service_dependency_id_seq', 1 FROM SYSIBM.SYSDUMMY1
+  UNION ALL
   SELECT 'service_id_seq', 1 FROM SYSIBM.SYSDUMMY1
   UNION ALL
   SELECT 'host_id_seq', 0 FROM SYSIBM.SYSDUMMY1

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/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 e204aab..c6a6e98 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -202,14 +202,16 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
 CREATE TABLE servicedependencies (
+  id BIGINT NOT NULL,
   service_id BIGINT NOT NULL,
   service_group_id BIGINT NOT NULL,
   service_cluster_id BIGINT NOT NULL,
   dependent_service_id BIGINT NOT NULL,
   dependent_service_group_id BIGINT NOT NULL,
   dependent_service_cluster_id BIGINT NOT NULL,
-  CONSTRAINT PK_servicedependencies PRIMARY KEY (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
-  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id));
+  CONSTRAINT PK_servicedependencies PRIMARY KEY (id),
+  CONSTRAINT UQ_servicedependencies UNIQUE (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
+  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id),
   CONSTRAINT FK_servicedependencies_dependent_service_group_cluster_id FOREIGN KEY (dependent_service_id, dependent_service_group_id, dependent_service_cluster_id) REFERENCES clusterservices (id, service_group_id, cluster_id));
 
 CREATE TABLE serviceconfig (
@@ -1172,6 +1174,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) VALUES
   ('cluster_id_seq', 1),
   ('cluster_setting_id_seq', 1),
   ('service_group_id_seq', 1),
+  ('service_dependency_id_seq', 1),
   ('service_group_dependency_id_seq', 1),
   ('service_id_seq', 1),
   ('host_id_seq', 0),

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/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 4cd4ba4..ece6ef6 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -182,14 +182,16 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
 CREATE TABLE servicedependencies (
+  id NUMBER(19) NOT NULL,
   service_id NUMBER(19) NOT NULL,
   service_group_id NUMBER(19) NOT NULL,
   service_cluster_id NUMBER(19) NOT NULL,
   dependent_service_id NUMBER(19) NOT NULL,
   dependent_service_group_id NUMBER(19) NOT NULL,
   dependent_service_cluster_id NUMBER(19) NOT NULL,
-  CONSTRAINT PK_servicedependencies PRIMARY KEY (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
-  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id));
+  CONSTRAINT PK_servicedependencies PRIMARY KEY (id),
+  CONSTRAINT UQ_servicedependencies UNIQUE (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
+  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id),
   CONSTRAINT FK_servicedependencies_dependent_service_group_cluster_id FOREIGN KEY (dependent_service_id, dependent_service_group_id, dependent_service_cluster_id) REFERENCES clusterservices (id, service_group_id, cluster_id));
 
 CREATE TABLE serviceconfig (
@@ -1151,6 +1153,7 @@ CREATE INDEX idx_alert_notice_state on alert_notice(notify_state);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('host_role_command_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('cluster_setting_id_seq', 1);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('service_group_id_seq', 1);
+INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('service_dependency_id_seq', 1);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('service_group_dependency_id_seq', 1);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('service_id_seq', 1);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('user_id_seq', 1);

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/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 1c296ee..14e8e6e 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -183,14 +183,16 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
 CREATE TABLE servicedependencies (
+  id BIGINT NOT NULL,
   service_id BIGINT NOT NULL,
   service_group_id BIGINT NOT NULL,
   service_cluster_id BIGINT NOT NULL,
   dependent_service_id BIGINT NOT NULL,
   dependent_service_group_id BIGINT NOT NULL,
   dependent_service_cluster_id BIGINT NOT NULL,
-  CONSTRAINT PK_servicedependencies PRIMARY KEY (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
-  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id));
+  CONSTRAINT PK_servicedependencies PRIMARY KEY (id),
+  CONSTRAINT UQ_servicedependencies UNIQUE (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
+  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id),
   CONSTRAINT FK_servicedependencies_dependent_service_group_cluster_id FOREIGN KEY (dependent_service_id, dependent_service_group_id, dependent_service_cluster_id) REFERENCES clusterservices (id, service_group_id, cluster_id));
 
 CREATE TABLE serviceconfig (
@@ -1158,6 +1160,7 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value) VALUES
   ('service_group_id_seq', 1),
   ('service_group_dependency_id_seq', 1),
   ('service_id_seq', 1),
+  ('service_dependency_id_seq', 1),
   ('host_id_seq', 0),
   ('user_id_seq', 2),
   ('group_id_seq', 1),

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/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 7dfe929..994d1e7 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -181,14 +181,16 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
 CREATE TABLE servicedependencies (
-  service_id NUMERIC(19) NOT NULL,
-  service_group_id NUMERIC(19) NOT NULL,
-  service_cluster_id NUMERIC(19) NOT NULL,
-  dependent_service_id NUMERIC(19) NOT NULL,
-  dependent_service_group_id NUMERIC(19) NOT NULL,
-  dependent_service_cluster_id NUMERIC(19) NOT NULL,
-  CONSTRAINT PK_servicedependencies PRIMARY KEY (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
-  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id));
+  id NUMBER(19) NOT NULL,
+  service_id NUMBER(19) NOT NULL,
+  service_group_id NUMBER(19) NOT NULL,
+  service_cluster_id NUMBER(19) NOT NULL,
+  dependent_service_id NUMBER(19) NOT NULL,
+  dependent_service_group_id NUMBER(19) NOT NULL,
+  dependent_service_cluster_id NUMBER(19) NOT NULL,
+  CONSTRAINT PK_servicedependencies PRIMARY KEY (id),
+  CONSTRAINT UQ_servicedependencies UNIQUE (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
+  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id),
   CONSTRAINT FK_servicedependencies_dependent_service_group_cluster_id FOREIGN KEY (dependent_service_id, dependent_service_group_id, dependent_service_cluster_id) REFERENCES clusterservices (id, service_group_id, cluster_id));
 
 CREATE TABLE serviceconfig (
@@ -1150,6 +1152,7 @@ CREATE INDEX idx_alert_notice_state on alert_notice(notify_state);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('cluster_id_seq', 1);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('cluster_setting_id_seq', 1);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('service_group_id_seq', 1);
+INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('service_dependency_id_seq', 1);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('service_group_dependency_id_seq', 1);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('service_id_seq', 1);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('host_id_seq', 0);

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/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 7ad4251..a399bed 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -195,14 +195,16 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
 CREATE TABLE servicedependencies (
+  id BIGINT NOT NULL,
   service_id BIGINT NOT NULL,
   service_group_id BIGINT NOT NULL,
   service_cluster_id BIGINT NOT NULL,
   dependent_service_id BIGINT NOT NULL,
   dependent_service_group_id BIGINT NOT NULL,
   dependent_service_cluster_id BIGINT NOT NULL,
-  CONSTRAINT PK_servicedependencies PRIMARY KEY (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
-  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id));
+  CONSTRAINT PK_servicedependencies PRIMARY KEY (id),
+  CONSTRAINT UQ_servicedependencies UNIQUE (service_id, service_group_id, service_cluster_id, dependent_service_id, dependent_service_group_id, dependent_service_cluster_id),
+  CONSTRAINT FK_servicedependencies_service_group_cluster_id FOREIGN KEY (service_id, service_group_id, service_cluster_id) REFERENCES clusterservices  (id, service_group_id, cluster_id),
   CONSTRAINT FK_servicedependencies_dependent_service_group_cluster_id FOREIGN KEY (dependent_service_id, dependent_service_group_id, dependent_service_cluster_id) REFERENCES clusterservices (id, service_group_id, cluster_id));
 
 CREATE TABLE serviceconfig (
@@ -1176,6 +1178,7 @@ BEGIN TRANSACTION
     ('cluster_id_seq', 1),
     ('cluster_setting_id_seq', 1),
     ('service_group_id_seq', 1),
+    ('service_dependency_id_seq', 1),
     ('service_group_dependency_id_seq', 1),
     ('service_id_seq', 1),
     ('host_id_seq', 0),

http://git-wip-us.apache.org/repos/asf/ambari/blob/19513a85/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 5b0d439..680bdea 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.ClusterConfigEntity</class>
     <class>org.apache.ambari.server.orm.entities.ClusterEntity</class>
     <class>org.apache.ambari.server.orm.entities.ServiceGroupEntity</class>
+    <class>org.apache.ambari.server.orm.entities.ServiceDependencyEntity</class>
     <class>org.apache.ambari.server.orm.entities.ServiceGroupDependencyEntity</class>
     <class>org.apache.ambari.server.orm.entities.ClusterSettingEntity</class>
     <class>org.apache.ambari.server.orm.entities.ClusterServiceEntity</class>