You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2016/10/19 19:06:12 UTC

[8/8] ambari git commit: Merge branch 'branch-feature-AMBARI-18456' into trunk

Merge branch 'branch-feature-AMBARI-18456' into trunk


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

Branch: refs/heads/branch-2.5
Commit: f64fa722024a8be76415efd5c8cec7fc7fe13c18
Parents: 68d4da4
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Oct 19 12:06:10 2016 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Wed Oct 19 14:42:04 2016 -0400

----------------------------------------------------------------------
 .../funtest/server/utils/ClusterUtils.java      |    1 -
 ambari-project/pom.xml                          |    2 +-
 .../ambari/server/api/services/BaseRequest.java |   49 +-
 .../controller/AmbariManagementController.java  |    8 -
 .../AmbariManagementControllerImpl.java         |   33 +-
 .../ambari/server/controller/AmbariServer.java  |    5 +-
 .../internal/ComponentResourceProvider.java     |   26 +-
 .../internal/ServiceResourceProvider.java       |   38 +-
 .../internal/UpgradeResourceProvider.java       |    2 +-
 .../alerts/AlertServiceStateListener.java       |  122 +-
 .../orm/dao/ConfigGroupHostMappingDAO.java      |  137 +-
 .../orm/dao/HostComponentDesiredStateDAO.java   |    7 +-
 .../server/orm/dao/HostComponentStateDAO.java   |    9 +-
 .../apache/ambari/server/orm/dao/HostDAO.java   |    2 +-
 .../orm/entities/ClusterServiceEntity.java      |    2 +-
 .../HostComponentDesiredStateEntity.java        |   11 +
 .../orm/entities/HostComponentStateEntity.java  |   11 +
 .../org/apache/ambari/server/state/Cluster.java |   12 -
 .../apache/ambari/server/state/Clusters.java    |    9 +
 .../apache/ambari/server/state/ConfigImpl.java  |   98 +-
 .../org/apache/ambari/server/state/Host.java    |   11 -
 .../apache/ambari/server/state/HostConfig.java  |   12 +-
 .../org/apache/ambari/server/state/Service.java |   13 -
 .../ambari/server/state/ServiceComponent.java   |   13 -
 .../server/state/ServiceComponentHost.java      |    6 -
 .../server/state/ServiceComponentImpl.java      |  719 ++++-----
 .../apache/ambari/server/state/ServiceImpl.java |  642 +++------
 .../server/state/cluster/ClusterImpl.java       | 1360 +++++++-----------
 .../server/state/cluster/ClustersImpl.java      |  628 ++++----
 .../state/configgroup/ConfigGroupImpl.java      |   92 +-
 .../ambari/server/state/host/HostFactory.java   |    2 +-
 .../ambari/server/state/host/HostImpl.java      |  948 ++++--------
 .../svccomphost/ServiceComponentHostImpl.java   | 1066 +++++---------
 .../ambari/server/topology/TopologyManager.java |    1 -
 .../apache/ambari/server/utils/RetryHelper.java |   19 +-
 .../ExecutionCommandWrapperTest.java            |    1 -
 .../actionmanager/TestActionDBAccessorImpl.java |    9 -
 .../server/actionmanager/TestActionManager.java |    8 +-
 .../ambari/server/agent/AgentResourceTest.java  |   12 +-
 .../server/agent/HeartbeatProcessorTest.java    |  132 +-
 .../server/agent/HeartbeatTestHelper.java       |   16 +-
 .../server/agent/TestHeartbeatHandler.java      |  136 +-
 .../server/agent/TestHeartbeatMonitor.java      |   87 +-
 .../server/api/services/AmbariMetaInfoTest.java |    3 +
 .../server/api/services/ClusterServiceTest.java |   43 +-
 .../server/checks/InstallPackagesCheckTest.java |    5 +-
 .../configuration/RecoveryConfigHelperTest.java |  122 +-
 .../AmbariCustomCommandExecutionHelperTest.java |    1 -
 .../AmbariManagementControllerTest.java         |  185 +--
 .../BackgroundCustomCommandExecutionTest.java   |    1 -
 .../server/controller/KerberosHelperTest.java   |   80 +-
 ...hYarnCapacitySchedulerReleaseConfigTest.java |    7 +-
 .../internal/ClusterResourceProviderTest.java   |    7 +-
 .../internal/JMXHostProviderTest.java           |    6 -
 .../PreUpgradeCheckResourceProviderTest.java    |   52 +-
 .../internal/ServiceResourceProviderTest.java   |   63 +-
 .../StackDefinedPropertyProviderTest.java       |    1 -
 .../UpgradeResourceProviderHDP22Test.java       |    2 -
 .../internal/UpgradeResourceProviderTest.java   |    4 -
 .../UpgradeSummaryResourceProviderTest.java     |   48 +-
 .../DefaultServiceCalculatedStateTest.java      |    6 +-
 .../state/FlumeServiceCalculatedStateTest.java  |    7 +-
 .../GeneralServiceCalculatedStateTest.java      |   47 +-
 .../state/HBaseServiceCalculatedStateTest.java  |    7 +-
 .../state/HDFSServiceCalculatedStateTest.java   |    7 +-
 .../state/HiveServiceCalculatedStateTest.java   |    7 +-
 .../state/OozieServiceCalculatedStateTest.java  |    7 +-
 .../state/YarnServiceCalculatedStateTest.java   |    7 +-
 .../apache/ambari/server/events/EventsTest.java |    5 -
 .../HostVersionOutOfSyncListenerTest.java       |    3 -
 .../apache/ambari/server/orm/OrmTestHelper.java |   34 +-
 .../server/orm/dao/ClusterVersionDAOTest.java   |   12 +-
 .../server/orm/dao/ConfigGroupDAOTest.java      |   33 +-
 .../dao/HostComponentDesiredStateDAOTest.java   |   27 +-
 .../orm/dao/HostComponentStateDAOTest.java      |   28 +-
 .../orm/dao/RepositoryVersionDAOTest.java       |    6 +-
 .../ambari/server/orm/dao/SettingDAOTest.java   |   19 +-
 .../ambari/server/orm/dao/WidgetDAOTest.java    |    8 +-
 .../server/orm/dao/WidgetLayoutDAOTest.java     |   13 +-
 .../ComponentVersionCheckActionTest.java        |    5 -
 .../upgrades/ConfigureActionTest.java           |    2 -
 .../upgrades/UpgradeActionTest.java             |    8 -
 .../ambari/server/state/ConfigGroupTest.java    |   10 +-
 .../ambari/server/state/ConfigHelperTest.java   |   12 +-
 .../server/state/RequestExecutionTest.java      |   12 +-
 .../server/state/ServiceComponentTest.java      |   47 +-
 .../apache/ambari/server/state/ServiceTest.java |   15 +-
 .../ambari/server/state/UpgradeHelperTest.java  |    8 -
 .../state/alerts/AlertEventPublisherTest.java   |    7 +-
 .../state/alerts/InitialAlertEventTest.java     |    3 +-
 .../state/cluster/ClusterDeadlockTest.java      |   41 +-
 .../cluster/ClusterEffectiveVersionTest.java    |   19 +-
 .../server/state/cluster/ClusterImplTest.java   |   66 +-
 .../server/state/cluster/ClusterTest.java       |  122 +-
 .../state/cluster/ClustersDeadlockTest.java     |   12 +-
 .../server/state/cluster/ClustersTest.java      |   17 -
 .../ConcurrentServiceConfigVersionTest.java     |    4 -
 ...omponentHostConcurrentWriteDeadlockTest.java |    4 -
 .../ambari/server/state/host/HostImplTest.java  |   50 +-
 .../ambari/server/state/host/HostTest.java      |   22 +-
 .../svccomphost/ServiceComponentHostTest.java   |    5 -
 .../server/update/HostUpdateHelperTest.java     |   40 +-
 .../ambari/server/utils/StageUtilsTest.java     |    3 +-
 103 files changed, 2958 insertions(+), 5006 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-funtest/src/test/java/org/apache/ambari/funtest/server/utils/ClusterUtils.java
----------------------------------------------------------------------
diff --git a/ambari-funtest/src/test/java/org/apache/ambari/funtest/server/utils/ClusterUtils.java b/ambari-funtest/src/test/java/org/apache/ambari/funtest/server/utils/ClusterUtils.java
index 8cf09c2..36204f7 100644
--- a/ambari-funtest/src/test/java/org/apache/ambari/funtest/server/utils/ClusterUtils.java
+++ b/ambari-funtest/src/test/java/org/apache/ambari/funtest/server/utils/ClusterUtils.java
@@ -91,7 +91,6 @@ public class ClusterUtils {
             hostAttributes.put("os_family", "redhat");
             hostAttributes.put("os_release_version", "6.3");
             host1.setHostAttributes(hostAttributes);
-            host1.persist();
         }
 
         /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-project/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-project/pom.xml b/ambari-project/pom.xml
index 9be5f45..a38c6a2 100644
--- a/ambari-project/pom.xml
+++ b/ambari-project/pom.xml
@@ -114,7 +114,7 @@
       <dependency>
         <groupId>org.apache.derby</groupId>
         <artifactId>derby</artifactId>
-        <version>10.9.1.0</version>
+        <version>10.12.1.1</version>
       </dependency>
       <dependency>
         <groupId>org.springframework.security</groupId>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java
index 9f7b949..73af2c8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java
@@ -18,40 +18,39 @@
 
 package org.apache.ambari.server.api.services;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+
 import org.apache.ambari.server.api.handlers.RequestHandler;
 import org.apache.ambari.server.api.predicate.InvalidQueryException;
 import org.apache.ambari.server.api.predicate.PredicateCompiler;
 import org.apache.ambari.server.api.predicate.QueryLexer;
 import org.apache.ambari.server.api.query.render.Renderer;
 import org.apache.ambari.server.api.resources.ResourceInstance;
-import org.apache.ambari.server.controller.internal.SortRequestImpl;
 import org.apache.ambari.server.controller.internal.PageRequestImpl;
+import org.apache.ambari.server.controller.internal.SortRequestImpl;
 import org.apache.ambari.server.controller.internal.TemporalInfoImpl;
-import org.apache.ambari.server.controller.spi.SortRequest;
 import org.apache.ambari.server.controller.spi.PageRequest;
 import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.SortRequest;
 import org.apache.ambari.server.controller.spi.SortRequestProperty;
 import org.apache.ambari.server.controller.spi.TemporalInfo;
 import org.apache.ambari.server.utils.RequestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.UriInfo;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Collection;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * Request implementation.
@@ -144,11 +143,13 @@ public abstract class BaseRequest implements Request {
       parseQueryPredicate();
       result = getRequestHandler().handleRequest(this);
     } catch (InvalidQueryException e) {
-      result =  new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST,
-          "Unable to compile query predicate: " + e.getMessage()));
+      String message = "Unable to compile query predicate: " + e.getMessage();
+      LOG.error(message, e);
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, message));
     } catch (IllegalArgumentException e) {
-      result =  new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST,
-          "Invalid Request: " + e.getMessage()));
+      String message = "Invalid Request: " + e.getMessage();
+      LOG.error(message, e);
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, message));
     }
 
     if (! result.getStatus().isErrorState()) {
@@ -322,7 +323,7 @@ public abstract class BaseRequest implements Request {
     if (queryString != null) {
       try {
         Collection<String> ignoredProperties = null;
-        switch (this.getRequestType()) {
+        switch (getRequestType()) {
           case PUT:
             ignoredProperties = m_resource.getResourceDefinition().getUpdateDirectives();
             break;

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index 2bf7578..a2d7251 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -53,7 +53,6 @@ import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceComponentFactory;
 import org.apache.ambari.server.state.ServiceComponentHost;
-import org.apache.ambari.server.state.ServiceFactory;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.ServiceOsSpecific;
 import org.apache.ambari.server.state.State;
@@ -549,13 +548,6 @@ public interface AmbariManagementController {
   AmbariMetaInfo getAmbariMetaInfo();
 
   /**
-   * Get the service factory for this management controller.
-   *
-   * @return the service factory
-   */
-  ServiceFactory getServiceFactory();
-
-  /**
    * Get the service component factory for this management controller.
    *
    * @return the service component factory

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 9517236..92bcb59 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -63,7 +63,6 @@ import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
 
 import javax.persistence.RollbackException;
 
@@ -3089,13 +3088,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         changedHosts, requestParameters, requestProperties,
         runSmokeTest, reconfigureClients);
 
-    Lock clusterWriteLock = cluster.getClusterGlobalLock().writeLock();
-    clusterWriteLock.lock();
-    try {
-      updateServiceStates(cluster, changedServices, changedComponents, changedHosts, ignoredHosts);
-    } finally {
-      clusterWriteLock.unlock();
-    }
+    updateServiceStates(cluster, changedServices, changedComponents, changedHosts, ignoredHosts);
+
     return requestStages;
   }
 
@@ -4717,11 +4711,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   }
 
   @Override
-  public ServiceFactory getServiceFactory() {
-    return serviceFactory;
-  }
-
-  @Override
   public ServiceComponentFactory getServiceComponentFactory() {
     return serviceComponentFactory;
   }
@@ -5167,13 +5156,15 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
     StackInfo stackInfo = ambariMetaInfo.getStack(linkEntity.getStack().getStackName(), linkEntity.getStack().getStackVersion());
 
-    if (stackInfo == null)
+    if (stackInfo == null) {
       throw new StackAccessException("stackName=" + linkEntity.getStack().getStackName() + ", stackVersion=" + linkEntity.getStack().getStackVersion());
+    }
 
     ExtensionInfo extensionInfo = ambariMetaInfo.getExtension(linkEntity.getExtension().getExtensionName(), linkEntity.getExtension().getExtensionVersion());
 
-    if (extensionInfo == null)
+    if (extensionInfo == null) {
       throw new StackAccessException("extensionName=" + linkEntity.getExtension().getExtensionName() + ", extensionVersion=" + linkEntity.getExtension().getExtensionVersion());
+    }
 
     ExtensionHelper.validateDeleteLink(getClusters(), stackInfo, extensionInfo);
     ambariMetaInfo.getStackManager().unlinkStackAndExtension(stackInfo, extensionInfo);
@@ -5203,13 +5194,15 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
     StackInfo stackInfo = ambariMetaInfo.getStack(request.getStackName(), request.getStackVersion());
 
-    if (stackInfo == null)
+    if (stackInfo == null) {
       throw new StackAccessException("stackName=" + request.getStackName() + ", stackVersion=" + request.getStackVersion());
+    }
 
     ExtensionInfo extensionInfo = ambariMetaInfo.getExtension(request.getExtensionName(), request.getExtensionVersion());
 
-    if (extensionInfo == null)
+    if (extensionInfo == null) {
       throw new StackAccessException("extensionName=" + request.getExtensionName() + ", extensionVersion=" + request.getExtensionVersion());
+    }
 
     ExtensionHelper.validateCreateLink(stackInfo, extensionInfo);
     ExtensionLinkEntity linkEntity = createExtensionLinkEntity(request);
@@ -5266,13 +5259,15 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   public void updateExtensionLink(ExtensionLinkEntity linkEntity) throws AmbariException {
     StackInfo stackInfo = ambariMetaInfo.getStack(linkEntity.getStack().getStackName(), linkEntity.getStack().getStackVersion());
 
-    if (stackInfo == null)
+    if (stackInfo == null) {
       throw new StackAccessException("stackName=" + linkEntity.getStack().getStackName() + ", stackVersion=" + linkEntity.getStack().getStackVersion());
+    }
 
     ExtensionInfo extensionInfo = ambariMetaInfo.getExtension(linkEntity.getExtension().getExtensionName(), linkEntity.getExtension().getExtensionVersion());
 
-    if (extensionInfo == null)
+    if (extensionInfo == null) {
       throw new StackAccessException("extensionName=" + linkEntity.getExtension().getExtensionName() + ", extensionVersion=" + linkEntity.getExtension().getExtensionVersion());
+    }
 
     ambariMetaInfo.getStackManager().linkStackToExtension(stackInfo, extensionInfo);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index eee7fee..4030ef9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -28,6 +28,8 @@ import java.net.URL;
 import java.util.EnumSet;
 import java.util.Enumeration;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.logging.LogManager;
 
 import javax.crypto.BadPaddingException;
@@ -145,6 +147,7 @@ import org.springframework.web.context.request.RequestContextListener;
 import org.springframework.web.context.support.GenericWebApplicationContext;
 import org.springframework.web.filter.DelegatingFilterProxy;
 
+import com.google.common.base.Joiner;
 import com.google.common.util.concurrent.ServiceManager;
 import com.google.gson.Gson;
 import com.google.inject.Guice;
@@ -864,7 +867,7 @@ public class AmbariServer {
 
     BaseService.init(injector.getInstance(RequestAuditLogger.class));
 
-    RetryHelper.init(configs.getOperationsRetryAttempts());
+    RetryHelper.init(injector.getInstance(Clusters.class), configs.getOperationsRetryAttempts());
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
index fe89752..241a48f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
@@ -17,9 +17,16 @@
  */
 package org.apache.ambari.server.controller.internal;
 
-import com.google.inject.assistedinject.Assisted;
-import com.google.inject.assistedinject.AssistedInject;
-import com.google.inject.persist.Transactional;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+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.DuplicateResourceException;
@@ -57,15 +64,9 @@ import org.apache.ambari.server.state.State;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.Validate;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import com.google.inject.persist.Transactional;
 
 /**
  * Resource provider for component resources.
@@ -379,7 +380,6 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
       }
 
       s.addServiceComponent(sc);
-      sc.persist();
     }
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
index 56196c1..13f822e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
@@ -17,9 +17,18 @@
  */
 package org.apache.ambari.server.controller.internal;
 
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-import com.google.inject.assistedinject.AssistedInject;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+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.DuplicateResourceException;
@@ -60,23 +69,14 @@ import org.apache.ambari.server.state.MaintenanceState;
 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.ServiceFactory;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.State;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.Validate;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
 
 /**
  * Resource provider for service resources.
@@ -344,18 +344,12 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
     // do all validation checks
     validateCreateRequests(requests, clusters);
 
-    ServiceFactory serviceFactory = getManagementController().getServiceFactory();
     for (ServiceRequest request : requests) {
       Cluster cluster = clusters.getCluster(request.getClusterName());
 
-      State state = State.INIT;
-
       // Already checked that service does not exist
-      Service s = serviceFactory.createNew(cluster, request.getServiceName());
+      Service s = cluster.addService(request.getServiceName());
 
-      s.setDesiredState(state);
-      s.setDesiredStackVersion(cluster.getDesiredStackVersion());
-      s.persist();
       // Initialize service widgets
       getManagementController().initializeWidgetsAndLayouts(cluster, s);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index d37e32b..b3d23d9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -360,7 +360,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
           // rollback
           // As we operate inside with cluster data, any cache which belongs to
           // cluster need to be flushed
-          cluster.invalidateData();
+          clusters.get().invalidate(cluster);
           throw e;
         }
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
index da4cbf5..6f6cea8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
@@ -20,6 +20,7 @@ package org.apache.ambari.server.events.listeners.alerts;
 import java.text.MessageFormat;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.locks.Lock;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.EagerSingleton;
@@ -34,7 +35,6 @@ import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
 import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
 import org.apache.ambari.server.orm.entities.AlertGroupEntity;
-import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.alert.AlertDefinition;
 import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
@@ -43,6 +43,7 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.eventbus.AllowConcurrentEvents;
 import com.google.common.eventbus.Subscribe;
+import com.google.common.util.concurrent.Striped;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
@@ -95,7 +96,13 @@ public class AlertServiceStateListener {
    * Used to retrieve a cluster using clusterId from event.
    */
   @Inject
-  private Provider<Clusters> clusters;
+  private Provider<Clusters> m_clusters;
+
+  /**
+   * Used for ensuring that the concurrent nature of the event handler methods
+   * don't collide when attempting to perform operations on the same service.
+   */
+  private Striped<Lock> m_locksByService = Striped.lazyWeakLock(20);
 
   /**
    * Constructor.
@@ -125,38 +132,46 @@ public class AlertServiceStateListener {
     String stackVersion = event.getStackVersion();
     String serviceName = event.getServiceName();
 
-    // create the default alert group for the new service if absent; this MUST
-    // be done before adding definitions so that they are properly added to the
-    // default group
-    if (null == m_alertDispatchDao.findDefaultServiceGroup(clusterId, serviceName)) {
-      try {
-        m_alertDispatchDao.createDefaultGroup(clusterId, serviceName);
-      } catch (AmbariException ambariException) {
-        LOG.error("Unable to create a default alert group for {}",
-          event.getServiceName(), ambariException);
-      }
-    }
+    Lock lock = m_locksByService.get(serviceName);
+    lock.lock();
 
-    // populate alert definitions for the new service from the database, but
-    // don't worry about sending down commands to the agents; the host
-    // components are not yet bound to the hosts so we'd have no way of knowing
-    // which hosts are invalidated; do that in another impl
     try {
-      Set<AlertDefinition> alertDefinitions = m_metaInfoProvider.get().getAlertDefinitions(
-          stackName, stackVersion, serviceName);
+      // create the default alert group for the new service if absent; this MUST
+      // be done before adding definitions so that they are properly added to the
+      // default group
+      if (null == m_alertDispatchDao.findDefaultServiceGroup(clusterId, serviceName)) {
+        try {
+          m_alertDispatchDao.createDefaultGroup(clusterId, serviceName);
+        } catch (AmbariException ambariException) {
+          LOG.error("Unable to create a default alert group for {}",
+            event.getServiceName(), ambariException);
+        }
+      }
 
-      for (AlertDefinition definition : alertDefinitions) {
-        AlertDefinitionEntity entity = m_alertDefinitionFactory.coerce(
-            clusterId,
-            definition);
+      // populate alert definitions for the new service from the database, but
+      // don't worry about sending down commands to the agents; the host
+      // components are not yet bound to the hosts so we'd have no way of knowing
+      // which hosts are invalidated; do that in another impl
+      try {
+        Set<AlertDefinition> alertDefinitions = m_metaInfoProvider.get().getAlertDefinitions(
+            stackName, stackVersion, serviceName);
 
-        m_definitionDao.create(entity);
+        for (AlertDefinition definition : alertDefinitions) {
+          AlertDefinitionEntity entity = m_alertDefinitionFactory.coerce(
+              clusterId,
+              definition);
+
+          m_definitionDao.create(entity);
+        }
+      } catch (AmbariException ae) {
+        String message = MessageFormat.format(
+            "Unable to populate alert definitions from the database during installation of {0}",
+            serviceName);
+        LOG.error(message, ae);
       }
-    } catch (AmbariException ae) {
-      String message = MessageFormat.format(
-          "Unable to populate alert definitions from the database during installation of {0}",
-          serviceName);
-      LOG.error(message, ae);
+    }
+    finally {
+      lock.unlock();
     }
   }
 
@@ -170,43 +185,44 @@ public class AlertServiceStateListener {
   @AllowConcurrentEvents
   public void onAmbariEvent(ServiceRemovedEvent event) {
     LOG.debug("Received event {}", event);
-    Cluster cluster = null;
 
     try {
-      cluster = clusters.get().getClusterById(event.getClusterId());
+      m_clusters.get().getClusterById(event.getClusterId());
     } catch (AmbariException e) {
-      LOG.warn("Unable to retrieve cluster info for id: " + event.getClusterId());
+      LOG.warn("Unable to retrieve cluster with id {}", event.getClusterId());
+      return;
     }
 
-    if (cluster != null) {
-      // TODO: Explicit locking used to prevent deadlock situation caused during cluster delete
-      cluster.getClusterGlobalLock().writeLock().lock();
-      try {
-        List<AlertDefinitionEntity> definitions = m_definitionDao.findByService(event.getClusterId(),
+    String serviceName = event.getServiceName();
+    Lock lock = m_locksByService.get(serviceName);
+    lock.lock();
+
+    try {
+      List<AlertDefinitionEntity> definitions = m_definitionDao.findByService(event.getClusterId(),
           event.getServiceName());
 
-        for (AlertDefinitionEntity definition : definitions) {
-          try {
-            m_definitionDao.remove(definition);
-          } catch (Exception exception) {
-            LOG.error("Unable to remove alert definition {}", definition.getDefinitionName(), exception);
-          }
+      for (AlertDefinitionEntity definition : definitions) {
+        try {
+          m_definitionDao.remove(definition);
+        } catch (Exception exception) {
+          LOG.error("Unable to remove alert definition {}", definition.getDefinitionName(),
+              exception);
         }
+      }
 
-        // remove the default group for the service
-        AlertGroupEntity group = m_alertDispatchDao.findGroupByName(event.getClusterId(),
+      // remove the default group for the service
+      AlertGroupEntity group = m_alertDispatchDao.findGroupByName(event.getClusterId(),
           event.getServiceName());
 
-        if (null != group && group.isDefault()) {
-          try {
-            m_alertDispatchDao.remove(group);
-          } catch (Exception exception) {
-            LOG.error("Unable to remove default alert group {}", group.getGroupName(), exception);
-          }
+      if (null != group && group.isDefault()) {
+        try {
+          m_alertDispatchDao.remove(group);
+        } catch (Exception exception) {
+          LOG.error("Unable to remove default alert group {}", group.getGroupName(), exception);
         }
-      } finally {
-        cluster.getClusterGlobalLock().writeLock().unlock();
       }
+    } finally {
+      lock.unlock();
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupHostMappingDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupHostMappingDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupHostMappingDAO.java
index 71d93cc..28b9fea 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupHostMappingDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupHostMappingDAO.java
@@ -17,10 +17,16 @@
  */
 package org.apache.ambari.server.orm.dao;
 
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.orm.RequiresSession;
@@ -40,16 +46,10 @@ import org.apache.ambari.server.state.host.HostFactory;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.Predicate;
 
-import javax.persistence.EntityManager;
-import javax.persistence.TypedQuery;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.HashMap;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
 
 @Singleton
 public class ConfigGroupHostMappingDAO {
@@ -65,16 +65,16 @@ public class ConfigGroupHostMappingDAO {
   private HostFactory hostFactory;
   @Inject
   Clusters clusters;
-  
+
   private final ReadWriteLock gl = new ReentrantReadWriteLock();
-  
+
   private Map<Long, Set<ConfigGroupHostMapping>> configGroupHostMappingByHost;
-  
+
   private volatile boolean cacheLoaded;
 
-  
+
   private void populateCache() {
-    
+
     if (!cacheLoaded) {
       gl.writeLock().lock();
       try {
@@ -106,10 +106,10 @@ public class ConfigGroupHostMappingDAO {
       } finally {
         gl.writeLock().unlock();
       }
-      
+
 
     }
-    
+
   }
 
   /**
@@ -121,50 +121,51 @@ public class ConfigGroupHostMappingDAO {
   @RequiresSession
   public ConfigGroupHostMappingEntity findByPK(final ConfigGroupHostMappingEntityPK
         configGroupHostMappingEntityPK) {
-    
+
     return entityManagerProvider.get()
       .find(ConfigGroupHostMappingEntity.class, configGroupHostMappingEntityPK);
   }
 
   @RequiresSession
   public Set<ConfigGroupHostMapping> findByHostId(Long hostId) {
-    
+
     populateCache();
-    
-    if (!configGroupHostMappingByHost.containsKey(hostId))
+
+    if (!configGroupHostMappingByHost.containsKey(hostId)) {
       return null;
-    
+    }
+
     Set<ConfigGroupHostMapping> set = new HashSet<ConfigGroupHostMapping>(configGroupHostMappingByHost.get(hostId));
-    
+
     return set;
-    
+
   }
 
   @RequiresSession
   public Set<ConfigGroupHostMapping> findByGroup(final Long groupId) {
-    
+
     populateCache();
-    
+
     Set<ConfigGroupHostMapping> result = new HashSet<ConfigGroupHostMapping>();
-    
+
     for (Set<ConfigGroupHostMapping> item : configGroupHostMappingByHost.values()) {
-      
+
       Set<ConfigGroupHostMapping> setByHost = new HashSet<ConfigGroupHostMapping>(item);
-      
+
       CollectionUtils.filter(setByHost, new Predicate() {
-        
+
         @Override
         public boolean evaluate(Object arg0) {
           return ((ConfigGroupHostMapping) arg0).getConfigGroupId().equals(groupId);
         }
       });
-      
+
       result.addAll(setByHost);
-      
+
     }
-    
+
     return result;
-    
+
   }
 
   @RequiresSession
@@ -178,33 +179,33 @@ public class ConfigGroupHostMappingDAO {
     populateCache();
 
     entityManagerProvider.get().persist(configGroupHostMappingEntity);
-    
+
     //create in cache
     Set<ConfigGroupHostMapping> set = configGroupHostMappingByHost.get(configGroupHostMappingEntity.getHostId());
     if (set == null){
       set = new HashSet<ConfigGroupHostMapping>();
       configGroupHostMappingByHost.put(configGroupHostMappingEntity.getHostId(), set);
     }
-    
+
     set.add(buildConfigGroupHostMapping(configGroupHostMappingEntity));
   }
 
   @Transactional
   public ConfigGroupHostMappingEntity merge(ConfigGroupHostMappingEntity configGroupHostMappingEntity) {
-    
+
     populateCache();
-    
+
     Set<ConfigGroupHostMapping> set = configGroupHostMappingByHost.get(configGroupHostMappingEntity.getHostId());
     if (set == null){
       set = new HashSet<ConfigGroupHostMapping>();
       configGroupHostMappingByHost.put(configGroupHostMappingEntity.getHostId(), set);
     }
-    
+
     //Update object in set
     set.remove(buildConfigGroupHostMapping(configGroupHostMappingEntity));
     set.add(buildConfigGroupHostMapping(configGroupHostMappingEntity));
-    
-    
+
+
     return entityManagerProvider.get().merge(configGroupHostMappingEntity);
   }
 
@@ -213,23 +214,23 @@ public class ConfigGroupHostMappingDAO {
                          configGroupHostMappingEntity) {
     cacheLoaded = false;
     populateCache();
-    
+
     entityManagerProvider.get().refresh(configGroupHostMappingEntity);
   }
 
   @Transactional
   public void remove(final ConfigGroupHostMappingEntity
                          configGroupHostMappingEntity) {
-    
+
     populateCache();
-    
+
     entityManagerProvider.get().remove(merge(configGroupHostMappingEntity));
-    
+
     Set<ConfigGroupHostMapping> setByHost = configGroupHostMappingByHost.get(configGroupHostMappingEntity.getHostId());
-    
+
     if (setByHost != null) {
       CollectionUtils.filter(setByHost, new Predicate() {
-        
+
         @Override
         public boolean evaluate(Object arg0) {
           return !((ConfigGroupHostMapping) arg0).getConfigGroupId().
@@ -243,14 +244,14 @@ public class ConfigGroupHostMappingDAO {
   public void removeByPK(final ConfigGroupHostMappingEntityPK
                          configGroupHostMappingEntityPK) {
     populateCache();
-    
+
     entityManagerProvider.get().remove(findByPK(configGroupHostMappingEntityPK));
-    
+
     Set<ConfigGroupHostMapping> setByHost = configGroupHostMappingByHost.get(configGroupHostMappingEntityPK.getHostId());
-    
+
     if (setByHost != null) {
       CollectionUtils.filter(setByHost, new Predicate() {
-        
+
         @Override
         public boolean evaluate(Object arg0) {
           return !((ConfigGroupHostMapping) arg0).getConfigGroupId().
@@ -258,7 +259,7 @@ public class ConfigGroupHostMappingDAO {
         }
       });
     }
-    
+
   }
 
   @Transactional
@@ -273,18 +274,18 @@ public class ConfigGroupHostMappingDAO {
     // Flush to current transaction required in order to avoid Eclipse link
     // from re-ordering delete
     entityManagerProvider.get().flush();
-    
+
     for (Set<ConfigGroupHostMapping> setByHost : configGroupHostMappingByHost.values()) {
-      
+
       CollectionUtils.filter(setByHost, new Predicate() {
-        
+
         @Override
         public boolean evaluate(Object arg0) {
           return !((ConfigGroupHostMapping) arg0).getConfigGroupId().equals(groupId);
         }
       });
     }
-    
+
   }
 
   @Transactional
@@ -294,22 +295,22 @@ public class ConfigGroupHostMappingDAO {
         "confighosts.hostId = ?1", String.class);
 
     daoUtils.executeUpdate(query, hostId);
-    
-    
+
+
     Set<ConfigGroupHostMapping> setByHost = configGroupHostMappingByHost.get(hostId);
-    
+
     setByHost.clear();
   }
-  
+
   private ConfigGroupHostMapping buildConfigGroupHostMapping(
       ConfigGroupHostMappingEntity configGroupHostMappingEntity) {
-    
+
     ConfigGroupHostMappingImpl configGroupHostMapping = new ConfigGroupHostMappingImpl();
     configGroupHostMapping.setConfigGroup(buildConfigGroup(configGroupHostMappingEntity.getConfigGroupEntity()));
     configGroupHostMapping.setConfigGroupId(configGroupHostMappingEntity.getConfigGroupId());
     configGroupHostMapping.setHost(buildHost(configGroupHostMappingEntity.getHostEntity()));
     configGroupHostMapping.setHostId(configGroupHostMappingEntity.getHostId());
-    
+
     return configGroupHostMapping;
   }
 
@@ -321,12 +322,12 @@ public class ConfigGroupHostMappingDAO {
       //almost impossible
     }
     ConfigGroup configGroup = configGroupFactory.createExisting(cluster, configGroupEntity);
-    
+
     return configGroup;
   }
 
   private Host buildHost(HostEntity hostEntity) {
-    Host host = hostFactory.create(hostEntity, false);
+    Host host = hostFactory.create(hostEntity);
     return host;
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentDesiredStateDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentDesiredStateDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentDesiredStateDAO.java
index 176e15b..876b1cf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentDesiredStateDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentDesiredStateDAO.java
@@ -95,17 +95,16 @@ public class HostComponentDesiredStateDAO {
 
   @Transactional
   public void remove(HostComponentDesiredStateEntity hostComponentDesiredStateEntity) {
-    HostEntity hostEntity = hostDAO.findById(hostComponentDesiredStateEntity.getHostId());
+    HostEntity hostEntity = hostComponentDesiredStateEntity.getHostEntity();
 
     if (hostEntity == null) {
       throw new IllegalStateException(String.format("Missing hostEntity for host id %1d",
               hostComponentDesiredStateEntity.getHostId()));
     }
 
-    entityManagerProvider.get().remove(merge(hostComponentDesiredStateEntity));
-
-    // Make sure that the state entity is removed from its host entity
     hostEntity.removeHostComponentDesiredStateEntity(hostComponentDesiredStateEntity);
+
+    entityManagerProvider.get().remove(hostComponentDesiredStateEntity);
     hostDAO.merge(hostEntity);
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentStateDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentStateDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentStateDAO.java
index 2eefe09..cc7b503 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentStateDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostComponentStateDAO.java
@@ -27,7 +27,6 @@ import javax.persistence.TypedQuery;
 
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
-import org.apache.ambari.server.orm.entities.HostEntity;
 import org.apache.ambari.server.state.UpgradeState;
 
 import com.google.inject.Inject;
@@ -177,13 +176,7 @@ public class HostComponentStateDAO {
 
   @Transactional
   public void remove(HostComponentStateEntity hostComponentStateEntity) {
-    HostEntity hostEntity = hostDAO.findByName(hostComponentStateEntity.getHostName());
-
-    entityManagerProvider.get().remove(merge(hostComponentStateEntity));
-
-    // Make sure that the state entity is removed from its host entity
-    hostEntity.removeHostComponentStateEntity(hostComponentStateEntity);
-    hostDAO.merge(hostEntity);
+    entityManagerProvider.get().remove(hostComponentStateEntity);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostDAO.java
index d367eb3..0d20fd3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostDAO.java
@@ -112,7 +112,7 @@ public class HostDAO {
 
   @Transactional
   public void remove(HostEntity hostEntity) {
-    entityManagerProvider.get().remove(merge(hostEntity));
+    entityManagerProvider.get().remove(hostEntity);
   }
 
   public List<String> getHostNamesByHostIds(List<Long> hostIds) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/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 320c1be..5c76356 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
@@ -49,7 +49,7 @@ public class ClusterServiceEntity {
   @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false)
   private ClusterEntity clusterEntity;
 
-  @OneToOne(mappedBy = "clusterServiceEntity")
+  @OneToOne(mappedBy = "clusterServiceEntity", cascade = { CascadeType.PERSIST, CascadeType.MERGE })
   private ServiceDesiredStateEntity serviceDesiredStateEntity;
 
   @OneToMany(mappedBy = "clusterServiceEntity")

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java
index fd15200..274a1e0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentDesiredStateEntity.java
@@ -37,6 +37,8 @@ import org.apache.ambari.server.state.MaintenanceState;
 import org.apache.ambari.server.state.SecurityState;
 import org.apache.ambari.server.state.State;
 
+import com.google.common.base.Objects;
+
 @javax.persistence.IdClass(HostComponentDesiredStateEntityPK.class)
 @javax.persistence.Table(name = "hostcomponentdesiredstate")
 @Entity
@@ -255,4 +257,13 @@ public class HostComponentDesiredStateEntity {
   public void setRestartRequired(boolean restartRequired) {
     this.restartRequired = (restartRequired == false ? 0 : 1);
   }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String toString() {
+    return Objects.toStringHelper(this).add("serviceName", serviceName).add("componentName",
+        componentName).add("hostId", hostId).add("desiredState", desiredState).toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java
index 1555321..9d35e2a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostComponentStateEntity.java
@@ -38,6 +38,8 @@ import org.apache.ambari.server.state.SecurityState;
 import org.apache.ambari.server.state.State;
 import org.apache.ambari.server.state.UpgradeState;
 
+import com.google.common.base.Objects;
+
 @Entity
 @Table(name = "hostcomponentstate")
 @TableGenerator(
@@ -283,4 +285,13 @@ public class HostComponentStateEntity {
     this.hostEntity = hostEntity;
   }
 
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String toString() {
+    return Objects.toStringHelper(this).add("serviceName", serviceName).add("componentName",
+        componentName).add("hostId", hostId).add("state", currentState).toString();
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/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 2452df6..b1958ef 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
@@ -22,7 +22,6 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.locks.ReadWriteLock;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.ClusterResponse;
@@ -522,12 +521,6 @@ public interface Cluster {
   Service addService(String serviceName) throws AmbariException;
 
   /**
-   * Get lock to control access to cluster structure
-   * @return cluster-global lock
-   */
-  ReadWriteLock getClusterGlobalLock();
-
-  /**
    * Fetch desired configs for list of hosts in cluster
    * @param hostIds
    * @return
@@ -670,11 +663,6 @@ public interface Cluster {
   void removeConfigurations(StackId stackId);
 
   /**
-   * Clear cluster caches and re-read data from database
-   */
-  void invalidateData();
-
-  /**
    * Returns whether this cluster was provisioned by a Blueprint or not.
    * @return true if the cluster was deployed with a Blueprint otherwise false.
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
index 2d859b3..e2164c0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
@@ -278,4 +278,13 @@ public interface Clusters {
    */
   int getClusterSize(String clusterName);
 
+  /**
+   * Invalidates the specified cluster by retrieving it from the database and
+   * refreshing all of the internal stateful collections.
+   *
+   * @param cluster
+   *          the cluster to invalidate and refresh (not {@code null}).
+   */
+  void invalidate(Cluster cluster);
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
index 038d202..1f52e6a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
@@ -27,9 +27,6 @@ import java.util.Set;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
-import org.apache.ambari.annotations.TransactionalLock;
-import org.apache.ambari.annotations.TransactionalLock.LockArea;
-import org.apache.ambari.annotations.TransactionalLock.LockType;
 import org.apache.ambari.server.events.ClusterConfigChangedEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.orm.dao.ClusterDAO;
@@ -356,69 +353,64 @@ public class ConfigImpl implements Config {
   @Override
   @Transactional
   public void persist(boolean newConfig) {
-    cluster.getClusterGlobalLock().writeLock().lock(); //null cluster is not expected, NPE anyway later in code
+    readWriteLock.writeLock().lock();
     try {
-      readWriteLock.writeLock().lock();
-      try {
-        ClusterEntity clusterEntity = clusterDAO.findById(cluster.getClusterId());
-
-        if (newConfig) {
-          ClusterConfigEntity entity = new ClusterConfigEntity();
-          entity.setClusterEntity(clusterEntity);
-          entity.setClusterId(cluster.getClusterId());
-          entity.setType(getType());
-          entity.setVersion(getVersion());
-          entity.setTag(getTag());
-          entity.setTimestamp(new Date().getTime());
-          entity.setStack(clusterEntity.getDesiredStack());
-          entity.setData(gson.toJson(getProperties()));
+      ClusterEntity clusterEntity = clusterDAO.findById(cluster.getClusterId());
+
+      if (newConfig) {
+        ClusterConfigEntity entity = new ClusterConfigEntity();
+        entity.setClusterEntity(clusterEntity);
+        entity.setClusterId(cluster.getClusterId());
+        entity.setType(getType());
+        entity.setVersion(getVersion());
+        entity.setTag(getTag());
+        entity.setTimestamp(new Date().getTime());
+        entity.setStack(clusterEntity.getDesiredStack());
+        entity.setData(gson.toJson(getProperties()));
+
+        if (null != getPropertiesAttributes()) {
+          entity.setAttributes(gson.toJson(getPropertiesAttributes()));
+        }
 
-          if (null != getPropertiesAttributes()) {
-            entity.setAttributes(gson.toJson(getPropertiesAttributes()));
+        clusterDAO.createConfig(entity);
+        clusterEntity.getClusterConfigEntities().add(entity);
+
+        // save the entity, forcing a flush to ensure the refresh picks up the
+        // newest data
+        clusterDAO.merge(clusterEntity, true);
+      } else {
+        // only supporting changes to the properties
+        ClusterConfigEntity entity = null;
+
+        // find the existing configuration to update
+        for (ClusterConfigEntity cfe : clusterEntity.getClusterConfigEntities()) {
+          if (getTag().equals(cfe.getTag()) && getType().equals(cfe.getType())
+              && getVersion().equals(cfe.getVersion())) {
+            entity = cfe;
+            break;
           }
+        }
+
+        // if the configuration was found, then update it
+        if (null != entity) {
+          LOG.debug(
+              "Updating {} version {} with new configurations; a new version will not be created",
+              getType(), getVersion());
 
-          clusterDAO.createConfig(entity);
-          clusterEntity.getClusterConfigEntities().add(entity);
+          entity.setData(gson.toJson(getProperties()));
 
           // save the entity, forcing a flush to ensure the refresh picks up the
           // newest data
           clusterDAO.merge(clusterEntity, true);
-          cluster.refresh();
-        } else {
-          // only supporting changes to the properties
-          ClusterConfigEntity entity = null;
-
-          // find the existing configuration to update
-          for (ClusterConfigEntity cfe : clusterEntity.getClusterConfigEntities()) {
-            if (getTag().equals(cfe.getTag()) &&
-                getType().equals(cfe.getType()) &&
-                getVersion().equals(cfe.getVersion())) {
-              entity = cfe;
-              break;
-            }
-          }
-
-          // if the configuration was found, then update it
-          if (null != entity) {
-            LOG.debug(
-                    "Updating {} version {} with new configurations; a new version will not be created",
-                    getType(), getVersion());
-
-            entity.setData(gson.toJson(getProperties()));
-
-            // save the entity, forcing a flush to ensure the refresh picks up the
-            // newest data
-            clusterDAO.merge(clusterEntity, true);
-            cluster.refresh();
-          }
         }
-      } finally {
-        readWriteLock.writeLock().unlock();
       }
     } finally {
-      cluster.getClusterGlobalLock().writeLock().unlock();
+      readWriteLock.writeLock().unlock();
     }
 
+    // re-load the entity associations for the cluster
+    cluster.refresh();
+
     // broadcast the change event for the configuration
     ClusterConfigChangedEvent event = new ClusterConfigChangedEvent(cluster.getClusterName(),
         getType(), getTag(), getVersion());

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/state/Host.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Host.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Host.java
index bd3f8bf..bd6cc0d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Host.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Host.java
@@ -43,11 +43,6 @@ public interface Host extends Comparable {
   Long getHostId();
 
   /**
-   * @param hostName the hostName to set
-   */
-  void setHostName(String hostName);
-
-  /**
    * @return the currentPingPort
    */
   Integer getCurrentPingPort();
@@ -338,12 +333,6 @@ public interface Host extends Comparable {
 
   HostResponse convertToResponse();
 
-  boolean isPersisted();
-
-  void persist();
-
-  void refresh();
-
   void importHostInfo(HostInfo hostInfo);
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/state/HostConfig.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/HostConfig.java b/ambari-server/src/main/java/org/apache/ambari/server/state/HostConfig.java
index fc22ba5..3e767e1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/HostConfig.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/HostConfig.java
@@ -17,12 +17,13 @@
  */
 package org.apache.ambari.server.state;
 
-import com.google.common.base.Objects;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
 import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
-import java.util.HashMap;
-import java.util.Map;
+import com.google.common.base.Objects;
 
 /**
  * Data structure that hangs off of the Host and points to what tags are
@@ -30,7 +31,7 @@ import java.util.Map;
  */
 
 public class HostConfig {
-  private final Map<Long, String> configGroupOverrides = new HashMap<Long, String>();
+  private final Map<Long, String> configGroupOverrides = new ConcurrentHashMap<Long, String>();
   private String defaultVersionTag;
 
   public HostConfig() {
@@ -67,8 +68,9 @@ public class HostConfig {
       sb.append(", overrides = [ ");
       int i = 0;
       for (Map.Entry<Long, String> entry : configGroupOverrides.entrySet()) {
-        if (i++ != 0)
+        if (i++ != 0) {
           sb.append(", ");
+        }
         sb.append(entry.getKey().toString() + " : " + entry.getValue());
       }
       sb.append("]");

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/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 7000574..df3cfd8 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
@@ -19,7 +19,6 @@
 package org.apache.ambari.server.state;
 
 import java.util.Map;
-import java.util.concurrent.locks.ReadWriteLock;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.ServiceResponse;
@@ -73,12 +72,6 @@ public interface Service {
 
   void debugDump(StringBuilder sb);
 
-  boolean isPersisted();
-
-  void persist();
-
-  void refresh();
-
   ServiceComponent addServiceComponent(String serviceComponentName)
       throws AmbariException;
 
@@ -99,12 +92,6 @@ public interface Service {
   void delete() throws AmbariException;
 
   /**
-   * Get lock to control access to cluster structure
-   * @return cluster-global lock
-   */
-  ReadWriteLock getClusterGlobalLock();
-
-  /**
    * Sets the maintenance state for the service
    * @param state the state
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponent.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponent.java
index 983cbdf..f91a958 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponent.java
@@ -19,7 +19,6 @@
 package org.apache.ambari.server.state;
 
 import java.util.Map;
-import java.util.concurrent.locks.ReadWriteLock;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.ServiceComponentResponse;
@@ -73,12 +72,6 @@ public interface ServiceComponent {
 
   ServiceComponentResponse convertToResponse();
 
-  void refresh();
-
-  boolean isPersisted();
-
-  void persist();
-
   void debugDump(StringBuilder sb);
 
   boolean isClientComponent();
@@ -98,10 +91,4 @@ public interface ServiceComponent {
       String hostName) throws AmbariException;
 
   void delete() throws AmbariException;
-
-  /**
-   * Get lock to control access to cluster structure
-   * @return cluster-global lock
-   */
-  ReadWriteLock getClusterGlobalLock();
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f64fa722/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
index cd7f826..fd92bed 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceComponentHost.java
@@ -188,12 +188,6 @@ public interface ServiceComponentHost {
    */
   ServiceComponentHostResponse convertToResponse(Map<String, DesiredConfig> desiredConfigs);
 
-  boolean isPersisted();
-
-  void persist();
-
-  void refresh();
-
   void debugDump(StringBuilder sb);
 
   boolean canBeRemoved();