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 2015/04/02 01:00:50 UTC

[2/2] ambari git commit: AMBARI-10301 - Stack Database Table Creation and Population From Resources (jonathanhurley)

AMBARI-10301 - Stack Database Table Creation and Population From Resources (jonathanhurley)


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

Branch: refs/heads/trunk
Commit: 69197e6302f28e69ccfc11b1e31d77d9dcf61a97
Parents: cc4a9a3
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Mar 31 15:53:23 2015 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Wed Apr 1 19:00:42 2015 -0400

----------------------------------------------------------------------
 .../server/api/services/AmbariMetaInfo.java     |  44 ++---
 .../server/configuration/Configuration.java     |  12 +-
 .../ambari/server/controller/AmbariServer.java  |   4 -
 .../server/controller/ControllerModule.java     |   5 +-
 .../apache/ambari/server/orm/dao/StackDAO.java  | 160 +++++++++++++++++++
 .../ambari/server/orm/entities/StackEntity.java | 154 ++++++++++++++++++
 .../server/orm/entities/StackEntity_.java       |  35 ++++
 .../ambari/server/stack/StackManager.java       |  77 +++++++--
 .../server/stack/StackManagerFactory.java       |  48 ++++++
 .../server/upgrade/UpgradeCatalog210.java       |  38 ++++-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |   9 ++
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |   8 +
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |  12 +-
 .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql     |  12 +-
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |  12 +-
 .../src/main/resources/META-INF/persistence.xml |   3 +-
 .../actionmanager/TestActionDBAccessorImpl.java |   4 +
 .../ambari/server/agent/AgentResourceTest.java  |  57 ++++---
 .../server/agent/TestHeartbeatHandler.java      |   6 +-
 .../server/agent/TestHeartbeatMonitor.java      |   3 +-
 .../server/api/services/AmbariMetaInfoTest.java |  61 +++++--
 .../services/KerberosServiceMetaInfoTest.java   |  56 +++++--
 .../AmbariCustomCommandExecutionHelperTest.java |   5 +-
 .../AmbariManagementControllerTest.java         |  17 +-
 .../BackgroundCustomCommandExecutionTest.java   |   4 +-
 .../server/controller/KerberosHelperTest.java   |  50 +++---
 ...hYarnCapacitySchedulerReleaseConfigTest.java |   4 +-
 ...ClusterStackVersionResourceProviderTest.java |  69 +++-----
 .../HostStackVersionResourceProviderTest.java   |  44 ++---
 .../internal/JMXHostProviderTest.java           |  23 +--
 .../StackArtifactResourceProviderTest.java      |  38 ++---
 .../HostVersionOutOfSyncListenerTest.java       |  17 +-
 .../scheduler/ExecutionScheduleManagerTest.java |  59 ++++---
 .../stack/StackManagerCommonServicesTest.java   | 111 ++++++++-----
 .../server/stack/StackManagerMiscTest.java      |  69 +++++---
 .../ambari/server/stack/StackManagerTest.java   |  64 ++++----
 .../ambari/server/state/ConfigGroupTest.java    |  18 +--
 .../ambari/server/state/ConfigHelperTest.java   |  34 ++--
 .../server/state/RequestExecutionTest.java      |  17 +-
 .../server/state/ServiceComponentTest.java      |   2 -
 .../apache/ambari/server/state/ServiceTest.java |   1 -
 .../ambari/server/state/UpgradeHelperTest.java  |   1 -
 .../state/alerts/AlertEventPublisherTest.java   |   1 -
 .../state/alerts/InitialAlertEventTest.java     |   1 -
 .../state/cluster/ClusterDeadlockTest.java      |   2 -
 .../server/state/cluster/ClusterTest.java       |   3 +-
 .../state/cluster/ClustersDeadlockTest.java     |   1 -
 .../server/state/cluster/ClustersTest.java      |   3 +-
 .../ambari/server/state/host/HostTest.java      |   4 +-
 .../server/state/stack/UpgradePackTest.java     |   4 +-
 .../svccomphost/ServiceComponentHostTest.java   |   7 +-
 .../ambari/server/utils/TestStageUtils.java     |   2 -
 52 files changed, 1074 insertions(+), 421 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index 3e37c3c..e87cd57 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -47,15 +47,14 @@ import org.apache.ambari.server.customactions.ActionDefinitionManager;
 import org.apache.ambari.server.events.AlertDefinitionDisabledEvent;
 import org.apache.ambari.server.events.AlertDefinitionRegistrationEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
-import org.apache.ambari.server.metadata.ActionMetadata;
 import org.apache.ambari.server.metadata.AgentAlertDefinitions;
 import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
 import org.apache.ambari.server.orm.dao.MetainfoDAO;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
 import org.apache.ambari.server.orm.entities.MetainfoEntity;
-import org.apache.ambari.server.stack.StackContext;
 import org.apache.ambari.server.stack.StackDirectory;
 import org.apache.ambari.server.stack.StackManager;
+import org.apache.ambari.server.stack.StackManagerFactory;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ComponentInfo;
@@ -92,8 +91,6 @@ import com.google.inject.Singleton;
  */
 @Singleton
 public class AmbariMetaInfo {
-
-
   public static final String SERVICE_CONFIG_FOLDER_NAME = "configuration";
   public static final String SERVICE_THEMES_FOLDER_NAME = "themes";
   public static final String SERVICE_CONFIG_FILE_NAME_POSTFIX = ".xml";
@@ -137,7 +134,7 @@ public class AmbariMetaInfo {
 
   // all the supported OS'es
   @Inject
-  private OsFamily os_family;
+  private OsFamily osFamily;
 
   /**
    * ALL_SUPPORTED_OS is dynamically generated list from loaded families from os_family.json
@@ -147,7 +144,6 @@ public class AmbariMetaInfo {
 
   private final ActionDefinitionManager adManager = new ActionDefinitionManager();
   private String serverVersion = "undefined";
-  private StackManager stackManager;
 
   private File stackRoot;
   private File commonServicesRoot;
@@ -161,7 +157,7 @@ public class AmbariMetaInfo {
    * Alert Definition DAO used to merge stack definitions into the database.
    */
   @Inject
-  AlertDefinitionDAO alertDefinitionDao;
+  private AlertDefinitionDAO alertDefinitionDao;
 
   /**
    * A factory that assists in the creation of {@link AlertDefinition} and
@@ -200,10 +196,16 @@ public class AmbariMetaInfo {
   @Inject
   private KerberosServiceDescriptorFactory kerberosServiceDescriptorFactory;
 
-  //todo: only used by StackManager
+  /**
+   * Factory for injecting {@link StackManager} instances.
+   */
   @Inject
-  ActionMetadata actionMetadata;
+  private StackManagerFactory stackManagerFactory;
 
+  /**
+   * Singleton instance of the stack manager.
+   */
+  private StackManager stackManager;
 
   /**
    * Ambari Meta Info Object
@@ -214,22 +216,17 @@ public class AmbariMetaInfo {
   @Inject
   public AmbariMetaInfo(Configuration conf) throws Exception {
     String stackPath = conf.getMetadataPath();
-    String commonServicesPath = conf.getCommonServicesPath();
-    String serverVersionFilePath = conf.getServerVersionFilePath();
     stackRoot = new File(stackPath);
+
+    String commonServicesPath = conf.getCommonServicesPath();
     if(commonServicesPath != null && !commonServicesPath.isEmpty()) {
       commonServicesRoot = new File(commonServicesPath);
     }
+
+    String serverVersionFilePath = conf.getServerVersionFilePath();
     serverVersionFile = new File(serverVersionFilePath);
-    customActionRoot = new File(conf.getCustomActionDefinitionPath());
-    os_family = new OsFamily(conf);
-    ALL_SUPPORTED_OS = new ArrayList<String>(os_family.os_list());
-  }
 
-  public AmbariMetaInfo(File stackRoot, File commonServicesRoot, File serverVersionFile) throws Exception {
-    this.stackRoot = stackRoot;
-    this.commonServicesRoot = commonServicesRoot;
-    this.serverVersionFile = serverVersionFile;
+    customActionRoot = new File(conf.getCustomActionDefinitionPath());
   }
 
   /**
@@ -240,10 +237,13 @@ public class AmbariMetaInfo {
   @Inject
   public void init() throws Exception {
     // Need to be initialized before all actions
-    ALL_SUPPORTED_OS = new ArrayList<String>(os_family.os_list());
+    ALL_SUPPORTED_OS = new ArrayList<String>(osFamily.os_list());
+
     readServerVersion();
-    stackManager = new StackManager(stackRoot, commonServicesRoot,
-        new StackContext(metaInfoDAO, actionMetadata, os_family));
+
+    stackManager = stackManagerFactory.create(stackRoot, commonServicesRoot,
+        osFamily);
+
     getCustomActionDefinitions(customActionRoot);
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index f6cf6a1..740532a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -51,7 +51,7 @@ import com.google.inject.Singleton;
  */
 @Singleton
 public class Configuration {
-  
+
   @Inject
   private OsFamily osFamily;
 
@@ -576,6 +576,16 @@ public class Configuration {
   }
 
   /**
+   * Gets a copy of all of the configuration properties that back this
+   * {@link Configuration} instance.
+   *
+   * @return a copy of all of the properties.
+   */
+  public Properties getProperties() {
+    return new Properties(properties);
+  }
+
+  /**
    * Loads trusted certificates store properties
    */
   protected void loadSSLParams(){

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/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 9b340ee..7ea96be 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
@@ -203,10 +203,6 @@ public class AmbariServer {
 
   @SuppressWarnings("deprecation")
   public void run() throws Exception {
-    // Initialize meta info before heartbeat monitor
-    ambariMetaInfo.init();
-    LOG.info("********* Meta Info initialized **********");
-
     performStaticInjection();
     initDB();
     server = new Server();

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 9c8bcd7..58b94d8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -73,6 +73,7 @@ import org.apache.ambari.server.scheduler.ExecutionSchedulerImpl;
 import org.apache.ambari.server.security.SecurityHelper;
 import org.apache.ambari.server.security.SecurityHelperImpl;
 import org.apache.ambari.server.serveraction.kerberos.KerberosOperationHandlerFactory;
+import org.apache.ambari.server.stack.StackManagerFactory;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
@@ -364,7 +365,6 @@ public class ControllerModule extends AbstractModule {
     install(new FactoryModuleBuilder().implement(
         Service.class, ServiceImpl.class).build(ServiceFactory.class));
 
-
     install(new FactoryModuleBuilder()
         .implement(ResourceProvider.class, Names.named("host"), HostResourceProvider.class)
         .implement(ResourceProvider.class, Names.named("hostComponent"), HostComponentResourceProvider.class)
@@ -374,7 +374,6 @@ public class ControllerModule extends AbstractModule {
         .implement(ResourceProvider.class, Names.named("repositoryVersion"), RepositoryVersionResourceProvider.class)
         .build(ResourceProviderFactory.class));
 
-
     install(new FactoryModuleBuilder().implement(
         ServiceComponent.class, ServiceComponentImpl.class).build(
         ServiceComponentFactory.class));
@@ -387,8 +386,10 @@ public class ControllerModule extends AbstractModule {
         ConfigGroup.class, ConfigGroupImpl.class).build(ConfigGroupFactory.class));
     install(new FactoryModuleBuilder().implement(RequestExecution.class,
         RequestExecutionImpl.class).build(RequestExecutionFactory.class));
+
     install(new FactoryModuleBuilder().build(StageFactory.class));
     install(new FactoryModuleBuilder().build(RequestFactory.class));
+    install(new FactoryModuleBuilder().build(StackManagerFactory.class));
 
     bind(HostRoleCommandFactory.class).to(HostRoleCommandFactoryImpl.class);
     bind(SecurityHelper.class).toInstance(SecurityHelperImpl.getInstance());

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/StackDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/StackDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/StackDAO.java
new file mode 100644
index 0000000..6405068
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/StackDAO.java
@@ -0,0 +1,160 @@
+/**
+ * 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.dao;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.orm.entities.StackEntity;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
+
+/**
+ * The {@link StackDAO} class is used to manage the persistence and retrieval of
+ * {@link StackEntity} instances.
+ */
+@Singleton
+public class StackDAO {
+
+  /**
+   * JPA entity manager
+   */
+  @Inject
+  private Provider<EntityManager> entityManagerProvider;
+
+  /**
+   * DAO utilities for dealing mostly with {@link TypedQuery} results.
+   */
+  @Inject
+  private DaoUtils daoUtils;
+
+  /**
+   * Gets a stack with the specified ID.
+   *
+   * @param stackId
+   *          the ID of the stack to retrieve.
+   * @return the stack or {@code null} if none exists.
+   */
+  public StackEntity findById(long stackId) {
+    return entityManagerProvider.get().find(StackEntity.class, stackId);
+  }
+
+  /**
+   * Gets all of the defined stacks.
+   *
+   * @return all of the stacks loaded from resources or an empty list (never
+   *         {@code null}).
+   */
+  public List<StackEntity> findAll() {
+    TypedQuery<StackEntity> query = entityManagerProvider.get().createNamedQuery(
+        "StackEntity.findAll", StackEntity.class);
+
+    return daoUtils.selectList(query);
+  }
+
+  /**
+   * Gets the stack that matches the specified name and version.
+   *
+   * @return the stack matching the specified name and version or {@code null}
+   *         if none.
+   */
+  public StackEntity find(String stackName, String stackVersion) {
+    TypedQuery<StackEntity> query = entityManagerProvider.get().createNamedQuery(
+        "StackEntity.findByNameAndVersion", StackEntity.class);
+
+    query.setParameter("stackName", stackName);
+    query.setParameter("stackVersion", stackVersion);
+
+    return daoUtils.selectOne(query);
+  }
+
+  /**
+   * Persists a new stack instance.
+   *
+   * @param stack
+   *          the stack to persist (not {@code null}).
+   */
+  @Transactional
+  public void create(StackEntity stack)
+      throws AmbariException {
+    EntityManager entityManager = entityManagerProvider.get();
+    entityManager.persist(stack);
+  }
+
+  /**
+   * Refresh the state of the stack instance from the database.
+   *
+   * @param stack
+   *          the stack to refresh (not {@code null}).
+   */
+  @Transactional
+  public void refresh(StackEntity stack) {
+    entityManagerProvider.get().refresh(stack);
+  }
+
+  /**
+   * Merge the speicified stack with the existing stack in the database.
+   *
+   * @param stack
+   *          the stack to merge (not {@code null}).
+   * @return the updated stack with merged content (never {@code null}).
+   */
+  @Transactional
+  public StackEntity merge(StackEntity stack) {
+    return entityManagerProvider.get().merge(stack);
+  }
+
+  /**
+   * Creates or updates the specified entity. This method will check
+   * {@link StackEntity#getStackId()} in order to determine whether the entity
+   * should be created or merged.
+   *
+   * @param stack
+   *          the stack to create or update (not {@code null}).
+   */
+  public void createOrUpdate(StackEntity stack)
+      throws AmbariException {
+    if (null == stack.getStackId()) {
+      create(stack);
+    } else {
+      merge(stack);
+    }
+  }
+
+  /**
+   * Removes the specified stack and all related clusters, services and
+   * components.
+   *
+   * @param stack
+   *          the stack to remove.
+   */
+  @Transactional
+  public void remove(StackEntity stack) {
+    EntityManager entityManager = entityManagerProvider.get();
+    stack = findById(stack.getStackId());
+    if (null != stack) {
+      entityManager.remove(stack);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity.java
new file mode 100644
index 0000000..2d75917
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity.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.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+import javax.persistence.UniqueConstraint;
+
+/**
+ * The {@link StackEntity} class is used to model an alert that needs
+ * to run in the system. Each received alert from an agent will essentially be
+ * an instance of this template.
+ */
+@Entity
+@Table(name = "stack", uniqueConstraints = @UniqueConstraint(columnNames = {
+    "stack_name", "stack_version" }))
+@TableGenerator(name = "stack_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "stack_id_seq", initialValue = 0, allocationSize = 1)
+@NamedQueries({
+    @NamedQuery(name = "StackEntity.findAll", query = "SELECT stack FROM StackEntity stack"),
+    @NamedQuery(name = "StackEntity.findByNameAndVersion", query = "SELECT stack FROM StackEntity stack WHERE stack.stackName = :stackName AND stack.stackVersion = :stackVersion") })
+public class StackEntity {
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.TABLE, generator = "stack_id_generator")
+  @Column(name = "stack_id", nullable = false, updatable = false)
+  private Long stackId;
+
+  @Column(name = "stack_name", length = 255, nullable = false)
+  private String stackName;
+
+  @Column(name = "stack_version", length = 255, nullable = false)
+  private String stackVersion;
+
+  /**
+   * Constructor.
+   */
+  public StackEntity() {
+  }
+
+  /**
+   * Gets the unique identifier for this stack.
+   *
+   * @return the ID.
+   */
+  public Long getStackId() {
+    return stackId;
+  }
+
+  /**
+   * Gets the name of the stack, such as "HDP".
+   *
+   * @return the name of the stack (never {@code null}).
+   */
+  public String getStackName() {
+    return stackName;
+  }
+
+  /**
+   * Sets the name of the stack, such as "HDP".
+   *
+   * @param stackName
+   *          the stack name (not {@code null}).
+   */
+  public void setStackName(String stackName) {
+    this.stackName = stackName;
+  }
+
+  /**
+   * Gets the version of the stack, such as "2.2".
+   *
+   * @return the stack version (never {@code null}).
+   */
+  public String getStackVersion() {
+    return stackVersion;
+  }
+
+  /**
+   * Sets the version of the stack, such as "2.2".
+   *
+   * @param stackVersion
+   *          the stack version (not {@code null}).
+   */
+  public void setStackVersion(String stackVersion) {
+    this.stackVersion = stackVersion;
+  }
+
+  /**
+   *
+   */
+  @Override
+  public boolean equals(Object object) {
+    if (this == object) {
+      return true;
+    }
+
+    if (object == null || getClass() != object.getClass()) {
+      return false;
+    }
+
+    StackEntity that = (StackEntity) object;
+
+    if (stackId != null ? !stackId.equals(that.stackId) : that.stackId != null) {
+      return false;
+    }
+
+    return true;
+  }
+
+  /**
+   *
+   */
+  @Override
+  public int hashCode() {
+    int result = null != stackId ? stackId.hashCode() : 0;
+    return result;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String toString() {
+    StringBuilder buffer = new StringBuilder();
+    buffer.append(getClass().getSimpleName());
+    buffer.append("{");
+    buffer.append("id=").append(stackId);
+    buffer.append(", name=").append(stackName);
+    buffer.append(", version=").append(stackVersion);
+    buffer.append("}");
+    return buffer.toString();
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity_.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity_.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity_.java
new file mode 100644
index 0000000..37396dd
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/StackEntity_.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.orm.entities;
+
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.persistence.metamodel.StaticMetamodel;
+
+
+/**
+ * The {@link StackEntity_} is a strongly typed metamodel for creating
+ * {@link CriteriaQuery} for {@link StackEntity}.
+ */
+@StaticMetamodel(StackEntity.class)
+public class StackEntity_ {
+  public static volatile SingularAttribute<StackEntity, Long> stackId;
+  public static volatile SingularAttribute<StackEntity, String> stackName;
+  public static volatile SingularAttribute<StackEntity, String> stackVersion;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
index 33f1447..1026245 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
@@ -18,21 +18,30 @@
 
 package org.apache.ambari.server.stack;
 
+import java.io.File;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.metadata.ActionMetadata;
+import org.apache.ambari.server.orm.dao.MetainfoDAO;
+import org.apache.ambari.server.orm.dao.StackDAO;
+import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.stack.OsFamily;
 import org.apache.ambari.server.state.stack.ServiceMetainfoXml;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
 
 
 /**
@@ -70,27 +79,59 @@ public class StackManager {
   private Map<String, StackInfo> stackMap = new HashMap<String, StackInfo>();
 
   /**
-   * Constructor.
-   * Initialize stack manager.
+   * Constructor. Initialize stack manager.
    *
-   * @param stackRoot           stack root directory
-   * @param commonServicesRoot  common services root directory
-   * @param stackContext        context which provides external functionality
+   * @param stackRoot
+   *          stack root directory
+   * @param commonServicesRoot
+   *          common services root directory
+   * @param osFamily
+   *          the OS family read from resources
+   * @param metaInfoDAO
+   *          metainfo DAO automatically injected
+   * @param actionMetadata
+   *          action meta data automatically injected
+   * @param stackDao
+   *          stack DAO automatically injected
    *
-   * @throws AmbariException if an exception occurs while processing the stacks
+   * @throws AmbariException
+   *           if an exception occurs while processing the stacks
    */
-  public StackManager(File stackRoot, File commonServicesRoot, StackContext stackContext) throws AmbariException {
+  @Inject
+  public StackManager(@Assisted("stackRoot") File stackRoot,
+      @Assisted("commonServicesRoot") @Nullable File commonServicesRoot,
+      @Assisted OsFamily osFamily, MetainfoDAO metaInfoDAO,
+      ActionMetadata actionMetadata, StackDAO stackDao)
+      throws AmbariException {
+
     validateStackDirectory(stackRoot);
     validateCommonServicesDirectory(commonServicesRoot);
 
-    this.stackMap = new HashMap<String, StackInfo>();
-    this.stackContext = stackContext;
+    stackMap = new HashMap<String, StackInfo>();
+    stackContext = new StackContext(metaInfoDAO, actionMetadata, osFamily);
 
     Map<String, ServiceModule> commonServiceModules = parseCommonServicesDirectory(commonServicesRoot);
     Map<String, StackModule> stackModules = parseStackDirectory(stackRoot);
 
     fullyResolveCommonServices(stackModules, commonServiceModules);
     fullyResolveStacks(stackModules, commonServiceModules);
+
+    // for every stack read in, ensure that we have a database entry for it;
+    // don't put try/catch logic around this since a failure here will
+    // cause other things to break down the road
+    Collection<StackInfo> stacks = getStacks();
+    for( StackInfo stack : stacks ){
+      String stackName = stack.getName();
+      String stackVersion = stack.getVersion();
+
+      if (stackDao.find(stackName, stackVersion) == null) {
+        StackEntity stackEntity = new StackEntity();
+        stackEntity.setStackName(stackName);
+        stackEntity.setStackVersion(stackVersion);
+
+        stackDao.create(stackEntity);
+      }
+    }
   }
 
   /**
@@ -201,10 +242,11 @@ public class StackManager {
             + ", commonServicesRoot = " + commonServicesRootAbsolutePath);
       }
 
-      if (!commonServicesRoot.isDirectory() && !commonServicesRoot.exists())
+      if (!commonServicesRoot.isDirectory() && !commonServicesRoot.exists()) {
         throw new AmbariException("" + Configuration.COMMON_SERVICES_DIR_PATH
             + " should be a directory with common services"
             + ", commonServicesRoot = " + commonServicesRootAbsolutePath);
+      }
     }
   }
 
@@ -221,10 +263,11 @@ public class StackManager {
           + ", stackRoot = " + stackRootAbsPath);
     }
 
-    if (!stackRoot.isDirectory() && !stackRoot.exists())
+    if (!stackRoot.isDirectory() && !stackRoot.exists()) {
       throw new AmbariException("" + Configuration.METADETA_DIR_PATH
           + " should be a directory with stack"
           + ", stackRoot = " + stackRootAbsPath);
+    }
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManagerFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManagerFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManagerFactory.java
new file mode 100644
index 0000000..5aa2b5f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManagerFactory.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.stack;
+
+import java.io.File;
+
+import javax.annotation.Nullable;
+
+import org.apache.ambari.server.state.stack.OsFamily;
+
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+
+/**
+ * The {@link StackManagerFactory} is used along with {@link AssistedInject} to
+ * build instances of {@link StackManager}.
+ */
+public interface StackManagerFactory {
+
+  /**
+   * @param stackRoot
+   *          the root of the stack (not {@code null}).
+   * @param commonServicesRoot
+   *          the root of the common services from which other stack services
+   *          are extended (not {@code null}).
+   * @param osFamily
+   *          the list of all parsed OS families (not {@code null}).
+   * @return a stack manager instance which contains all parsed stacks.
+   */
+  StackManager create(@Assisted("stackRoot") File stackRoot,
+      @Nullable @Assisted("commonServicesRoot") File commonServicesRoot,
+      OsFamily osFamily);
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
index 7bdfb4f..23ed67d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog210.java
@@ -18,9 +18,11 @@
 
 package org.apache.ambari.server.upgrade;
 
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.persist.Transactional;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.orm.DBAccessor.DBColumnInfo;
@@ -29,10 +31,9 @@ import org.apache.ambari.server.orm.entities.HostEntity;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.persist.Transactional;
 
 
 /**
@@ -59,6 +60,7 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
   private static final String WIDGET_LAYOUT_USER_WIDGET_TABLE = "widget_layout_user_widget";
   private static final String VIEW_INSTANCE_TABLE = "viewinstance";
   private static final String VIEW_PARAMETER_TABLE = "viewparameter";
+  private static final String STACK_TABLE_DEFINITION = "stack";
 
   /**
    * {@inheritDoc}
@@ -103,6 +105,7 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
   protected void executeDDLUpdates() throws AmbariException, SQLException {
     executeHostsDDLUpdates();
     executeWidgetDDLUpdates();
+    executeStackDDLUpdates();
   }
 
   /**
@@ -272,6 +275,27 @@ public class UpgradeCatalog210 extends AbstractUpgradeCatalog {
     dbAccessor.addFKConstraint(WIDGET_LAYOUT_USER_WIDGET_TABLE, "FK_user_widget_id", "user_widget_id", "user_widget", "id", true, false);
   }
 
+  /**
+   * Adds the stack table and constraints.
+   */
+  private void executeStackDDLUpdates() throws AmbariException, SQLException {
+    // alert_definition
+    ArrayList<DBColumnInfo> columns = new ArrayList<DBColumnInfo>();
+    columns.add(new DBColumnInfo("stack_id", Long.class, null, null, false));
+    columns.add(new DBColumnInfo("stack_name", String.class, 255, null, false));
+    columns.add(new DBColumnInfo("stack_version", String.class, 255, null,
+        false));
+
+    dbAccessor.createTable(STACK_TABLE_DEFINITION, columns, "stack_id");
+
+    dbAccessor.executeQuery("ALTER TABLE " + STACK_TABLE_DEFINITION
+        + " ADD CONSTRAINT unq_stack UNIQUE (stack_name,stack_version)", false);
+
+    dbAccessor.executeQuery(
+        "INSERT INTO ambari_sequences(sequence_name, sequence_value) VALUES('stack_id_seq', 0)",
+        false);
+  }
+
   // ----- UpgradeCatalog ----------------------------------------------------
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/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 e28edfd..af10a0e 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -832,6 +832,14 @@ CREATE TABLE upgrade_item (
   FOREIGN KEY (upgrade_group_id) REFERENCES upgrade_group(upgrade_group_id)
 );
 
+CREATE TABLE stack(
+  stack_id BIGINT NOT NULL,
+  stack_name VARCHAR(255) NOT NULL,
+  stack_version VARCHAR(255) NOT NULL,
+  PRIMARY KEY (stack_id),
+  CONSTRAINT uni_stack UNIQUE(stack_name,stack_version)
+);
+
 -- In order for the first ID to be 1, must initialize the ambari_sequences table with a sequence_value of 0.
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('cluster_id_seq', 1);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('host_id_seq', 0);
@@ -865,6 +873,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('repo_versio
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_group_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_item_id_seq', 0);
+INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('stack_id_seq', 0);
 
 insert into adminresourcetype (resource_type_id, resource_type_name)
   select 1, 'AMBARI'

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/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 513d951..ff73f60 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -822,6 +822,13 @@ CREATE TABLE upgrade_item (
   FOREIGN KEY (upgrade_group_id) REFERENCES upgrade_group(upgrade_group_id)
 );
 
+CREATE TABLE stack(
+  stack_id NUMBER(19) NOT NULL,
+  stack_name VARCHAR2(255) NOT NULL,
+  stack_version VARCHAR2(255) NOT NULL,
+  PRIMARY KEY (stack_id),
+  CONSTRAINT uni_stack UNIQUE(stack_name,stack_version)
+);
 
 ---------inserting some data-----------
 -- In order for the first ID to be 1, must initialize the ambari_sequences table with a sequence_value of 0.
@@ -857,6 +864,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('repo_versio
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_group_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_item_id_seq', 0);
+INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('stack_id_seq', 0);
 
 INSERT INTO metainfo("metainfo_key", "metainfo_value") values ('version', '${ambariVersion}');
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/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 6361edb..e48ea7a 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -824,6 +824,14 @@ CREATE TABLE upgrade_item (
   FOREIGN KEY (upgrade_group_id) REFERENCES upgrade_group(upgrade_group_id)
 );
 
+CREATE TABLE stack(
+  stack_id BIGINT NOT NULL,
+  stack_name VARCHAR(255) NOT NULL,
+  stack_version VARCHAR(255) NOT NULL,
+  PRIMARY KEY (stack_id),
+  CONSTRAINT uni_stack UNIQUE(stack_name,stack_version)
+);
+
 ---------inserting some data-----------
 -- In order for the first ID to be 1, must initialize the ambari_sequences table with a sequence_value of 0.
 BEGIN;
@@ -890,7 +898,9 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value)
   union all
   select 'upgrade_group_id_seq', 0
   union all
-  select 'upgrade_item_id_seq', 0;
+  select 'upgrade_item_id_seq', 0,
+  union all
+  select 'stack_id_seq', 0;  
 
 INSERT INTO adminresourcetype (resource_type_id, resource_type_name)
   SELECT 1, 'AMBARI'

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
index 2121805..49c92c0 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
@@ -908,6 +908,14 @@ CREATE TABLE ambari.upgrade_item (
   FOREIGN KEY (upgrade_group_id) REFERENCES ambari.upgrade_group(upgrade_group_id)
 );
 
+CREATE TABLE ambari.stack(
+  stack_id BIGINT NOT NULL,
+  stack_name VARCHAR(255) NOT NULL,
+  stack_version VARCHAR(255) NOT NULL,
+  PRIMARY KEY (stack_id),
+  CONSTRAINT uni_stack UNIQUE(stack_name,stack_version)
+);
+
 GRANT ALL PRIVILEGES ON TABLE ambari.upgrade TO :username;
 GRANT ALL PRIVILEGES ON TABLE ambari.upgrade_group TO :username;
 GRANT ALL PRIVILEGES ON TABLE ambari.upgrade_item TO :username;
@@ -978,7 +986,9 @@ INSERT INTO ambari.ambari_sequences (sequence_name, sequence_value)
   union all
   select 'upgrade_group_id_seq', 0 
   union all
-  select 'upgrade_item_id_seq', 0;
+  select 'upgrade_item_id_seq', 0,
+  union all
+  select 'stack_id_seq', 0;
 
 INSERT INTO ambari.adminresourcetype (resource_type_id, resource_type_name)
   SELECT 1, 'AMBARI'

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/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 40b00d9..5653ff8 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -367,6 +367,14 @@ CREATE TABLE upgrade_item (
   FOREIGN KEY (upgrade_group_id) REFERENCES upgrade_group(upgrade_group_id)
 );
 
+CREATE TABLE stack(
+  stack_id BIGINT NOT NULL,
+  stack_name VARCHAR(255) NOT NULL,
+  stack_version VARCHAR(255) NOT NULL,
+  PRIMARY KEY (stack_id),
+  CONSTRAINT uni_stack UNIQUE(stack_name,stack_version)
+);
+
 ---------inserting some data-----------
 BEGIN TRANSACTION
   INSERT INTO ambari_sequences (sequence_name, [sequence_value])
@@ -432,7 +440,9 @@ BEGIN TRANSACTION
   UNION ALL
   SELECT 'host_version_id_seq', 0
   UNION ALL
-  SELECT 'repo_version_id_seq', 0;
+  SELECT 'repo_version_id_seq', 0,
+  UNION ALL
+  SELECT 'stack_id_seq', 0;
 
   insert into adminresourcetype (resource_type_id, resource_type_name)
     select 1, 'AMBARI'

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/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 723fbc0..3146aff 100644
--- a/ambari-server/src/main/resources/META-INF/persistence.xml
+++ b/ambari-server/src/main/resources/META-INF/persistence.xml
@@ -20,6 +20,7 @@
     <class>org.apache.ambari.server.orm.entities.AlertHistoryEntity</class>
     <class>org.apache.ambari.server.orm.entities.AlertNoticeEntity</class>
     <class>org.apache.ambari.server.orm.entities.AlertTargetEntity</class>
+    <class>org.apache.ambari.server.orm.entities.ArtifactEntity</class>
     <class>org.apache.ambari.server.orm.entities.BlueprintConfigEntity</class>
     <class>org.apache.ambari.server.orm.entities.BlueprintEntity</class>
     <class>org.apache.ambari.server.orm.entities.ClusterConfigEntity</class>
@@ -65,6 +66,7 @@
     <class>org.apache.ambari.server.orm.entities.ServiceConfigApplicationEntity</class>
     <class>org.apache.ambari.server.orm.entities.ServiceConfigEntity</class>
     <class>org.apache.ambari.server.orm.entities.ServiceDesiredStateEntity</class>
+    <class>org.apache.ambari.server.orm.entities.StackEntity</class>
     <class>org.apache.ambari.server.orm.entities.StageEntity</class>
     <class>org.apache.ambari.server.orm.entities.UpgradeEntity</class>
     <class>org.apache.ambari.server.orm.entities.UpgradeGroupEntity</class>
@@ -80,7 +82,6 @@
     <class>org.apache.ambari.server.orm.entities.ViewResourceEntity</class>
     <class>org.apache.ambari.server.orm.entities.WidgetLayoutEntity</class>
     <class>org.apache.ambari.server.orm.entities.WidgetLayoutUserWidgetEntity</class>
-    <class>org.apache.ambari.server.orm.entities.ArtifactEntity</class>
 
     <properties>      
       <property name="eclipselink.cache.size.default" value="10000" />

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
index 1cf58d3..112e1e5 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/actionmanager/TestActionDBAccessorImpl.java
@@ -50,9 +50,11 @@ import org.apache.ambari.server.orm.dao.ExecutionCommandDAO;
 import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
 import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
 import org.apache.ambari.server.serveraction.MockServerAction;
+import org.apache.ambari.server.stack.StackManagerFactory;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent;
 import org.apache.ambari.server.utils.StageUtils;
+import org.easymock.EasyMock;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -557,6 +559,8 @@ public class TestActionDBAccessorImpl {
     @Override
     protected void configure() {
       bind(DBAccessor.class).to(TestDBAccessorImpl.class);
+      bind(StackManagerFactory.class).toInstance(
+          EasyMock.createNiceMock(StackManagerFactory.class));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/agent/AgentResourceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/AgentResourceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/AgentResourceTest.java
index c12e737..f4d9c63 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/agent/AgentResourceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/AgentResourceTest.java
@@ -18,32 +18,25 @@
 
 package org.apache.ambari.server.agent;
 
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.assistedinject.FactoryModuleBuilder;
-import com.google.inject.persist.jpa.AmbariJpaPersistModule;
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.UniformInterfaceException;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.api.client.config.ClientConfig;
-import com.sun.jersey.api.client.config.DefaultClientConfig;
-import com.sun.jersey.api.json.JSONConfiguration;
-import com.sun.jersey.spi.container.servlet.ServletContainer;
-import com.sun.jersey.test.framework.JerseyTest;
-import com.sun.jersey.test.framework.WebAppDescriptor;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import javax.ws.rs.core.MediaType;
+
 import junit.framework.Assert;
+
 import org.apache.ambari.server.actionmanager.ActionDBAccessor;
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.actionmanager.HostRoleCommandFactory;
 import org.apache.ambari.server.actionmanager.StageFactory;
 import org.apache.ambari.server.agent.rest.AgentResource;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.orm.DBAccessor;
 import org.apache.ambari.server.security.SecurityHelper;
 import org.apache.ambari.server.security.SecurityHelperImpl;
+import org.apache.ambari.server.stack.StackManagerFactory;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
@@ -75,13 +68,26 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
+import org.easymock.EasyMock;
 import org.eclipse.jetty.server.SessionManager;
 import org.junit.Test;
-import javax.ws.rs.core.MediaType;
 
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+import com.google.inject.persist.jpa.AmbariJpaPersistModule;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.api.json.JSONConfiguration;
+import com.sun.jersey.spi.container.servlet.ServletContainer;
+import com.sun.jersey.test.framework.JerseyTest;
+import com.sun.jersey.test.framework.WebAppDescriptor;
 
 public class AgentResourceTest extends JerseyTest {
   static String PACKAGE_NAME = "org.apache.ambari.server.agent.rest";
@@ -105,7 +111,7 @@ public class AgentResourceTest extends JerseyTest {
     GsonBuilder gsonBuilder = new GsonBuilder();
     gsonBuilder.serializeNulls();
     Gson gson = gsonBuilder.create();
-    return (T) gson.fromJson(json, type);
+    return gson.fromJson(json, type);
   }
 
   @Override
@@ -194,7 +200,7 @@ public class AgentResourceTest extends JerseyTest {
             "{user:'hdfs', pid:'325', hadoop:'False', command:'cmd = 2'}]";
     String AlternativeJSON = "[{name:'/etc/alternatives/hdfs-conf', target:'/etc/hadoop/conf.dist'}, " +
             "{name:'abc', target:'def'}]";
-    String AgentEnvJSON = "{\"alternatives\": " + AlternativeJSON + 
+    String AgentEnvJSON = "{\"alternatives\": " + AlternativeJSON +
             ", \"existingUsers\": "+ ExistingUserJSON +
             ", \"umask\": \"18\", \"installedPackages\": "+
             PackageDetailJSON +", \"stackFoldersAndFiles\": "+ DirectoryJSON +
@@ -229,7 +235,7 @@ public class AgentResourceTest extends JerseyTest {
     Assert.assertEquals("/etc/hadoop/conf.dist", alternatives[0].getTarget());
     Assert.assertEquals("abc", alternatives[1].getName());
     Assert.assertEquals("def", alternatives[1].getTarget());
-    
+
     AgentEnv agentEnv = getJsonFormString(
             AgentEnvJSON, AgentEnv.class);
     Assert.assertTrue(18 == agentEnv.getUmask());
@@ -247,7 +253,7 @@ public class AgentResourceTest extends JerseyTest {
     Assert.assertEquals("/var/lib/hadoop", agentEnv.getExistingUsers()[0].getUserHomeDir());
     Assert.assertEquals("None", agentEnv.getExistingUsers()[1].getUserStatus());
     Assert.assertEquals("/var/lib", agentEnv.getStackFoldersAndFiles()[0].getName());
-    Assert.assertEquals("directory", agentEnv.getStackFoldersAndFiles()[1].getType());    
+    Assert.assertEquals("directory", agentEnv.getStackFoldersAndFiles()[1].getType());
   }
 
   @Test
@@ -325,6 +331,9 @@ public class AgentResourceTest extends JerseyTest {
       install(new FactoryModuleBuilder().build(StageFactory.class));
       install(new FactoryModuleBuilder().build(HostRoleCommandFactory.class));
       bind(SecurityHelper.class).toInstance(SecurityHelperImpl.getInstance());
+      bind(AmbariEventPublisher.class).toInstance(EasyMock.createMock(AmbariEventPublisher.class));
+      bind(StackManagerFactory.class).toInstance(
+          EasyMock.createMock(StackManagerFactory.class));
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
index c9d8735..fe4ba60 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
@@ -153,7 +153,6 @@ public class TestHeartbeatHandler {
     injector.getInstance(GuiceJpaInitializer.class);
     clusters = injector.getInstance(Clusters.class);
     injector.injectMembers(this);
-    metaInfo.init();
     log.debug("Using server os type=" + config.getServerOsType());
     unitOfWork = injector.getInstance(UnitOfWork.class);
   }
@@ -2607,10 +2606,11 @@ public class TestHeartbeatHandler {
     File hostDirectory = new File(dataDirectory, "c6403.ambari.apache.org");
 
     File keytabFile;
-    if(hostDirectory.mkdirs())
+    if(hostDirectory.mkdirs()) {
       keytabFile = new File(hostDirectory, DigestUtils.sha1Hex("/etc/security/keytabs/dn.service.keytab"));
-    else
+    } else {
       throw new Exception("Failed to create " + hostDirectory.getAbsolutePath());
+    }
 
     kerberosIdentityDataFileWriter.writeRecord("c6403.ambari.apache.org", "HDFS", "DATANODE",
         "dn/_HOST@_REALM", "service",

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java
index 718310c..6bb053b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatMonitor.java
@@ -41,11 +41,11 @@ import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.OrmTestHelper;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.RepositoryVersionState;
 import org.apache.ambari.server.state.Config;
 import org.apache.ambari.server.state.ConfigFactory;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.HostState;
+import org.apache.ambari.server.state.RepositoryVersionState;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceComponentHost;
@@ -88,7 +88,6 @@ public class TestHeartbeatMonitor {
     injector.getInstance(GuiceJpaInitializer.class);
     helper = injector.getInstance(OrmTestHelper.class);
     ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
-    ambariMetaInfo.init();
   }
 
   @After

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
index ec61af8..f0c1f43 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
@@ -38,6 +38,7 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 import java.util.UUID;
 
@@ -59,6 +60,7 @@ import org.apache.ambari.server.orm.dao.MetainfoDAO;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
 import org.apache.ambari.server.orm.entities.MetainfoEntity;
 import org.apache.ambari.server.stack.StackManager;
+import org.apache.ambari.server.stack.StackManagerFactory;
 import org.apache.ambari.server.state.AutoDeployInfo;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
@@ -276,7 +278,9 @@ public class AmbariMetaInfoTest {
 
     List<RepositoryInfo> redhat6Repo = ambariMetaInfo.getRepositories(
         STACK_NAME_HDP, "2.1.1", "redhat6");
+
     assertNotNull(redhat6Repo);
+
     for (RepositoryInfo ri : redhat6Repo) {
       if (HDP_REPO_NAME.equals(ri.getRepoName())) {
         assertEquals(newBaseUrl, ri.getBaseUrl());
@@ -563,7 +567,9 @@ public class AmbariMetaInfoTest {
     if (!f3.exists()) {
       f3.createNewFile();
     }
+
     ambariMetaInfo.init();
+
     // Tests the stack is loaded as expected
     getServices();
     getComponentsByService();
@@ -1711,9 +1717,13 @@ public class AmbariMetaInfoTest {
     long clusterId = injector.getInstance(OrmTestHelper.class).createCluster(
         "cluster" + System.currentTimeMillis());
 
-    metaInfo.alertDefinitionDao = injector.getInstance(AlertDefinitionDAO.class);
     Class<?> c = metaInfo.getClass().getSuperclass();
-    Field f = c.getDeclaredField("agentAlertDefinitions");
+
+    Field f = c.getDeclaredField("alertDefinitionDao");
+    f.setAccessible(true);
+    f.set(metaInfo, injector.getInstance(AlertDefinitionDAO.class));
+
+    f = c.getDeclaredField("agentAlertDefinitions");
     f.setAccessible(true);
     f.set(metaInfo, injector.getInstance(AgentAlertDefinitions.class));
 
@@ -1865,7 +1875,12 @@ public class AmbariMetaInfoTest {
   }
 
   private TestAmbariMetaInfo createAmbariMetaInfo(File stackRoot, File versionFile, boolean replayMocks) throws Exception {
-    TestAmbariMetaInfo metaInfo = new TestAmbariMetaInfo(stackRoot, versionFile);
+    Properties properties = new Properties();
+    properties.setProperty(Configuration.METADETA_DIR_PATH, stackRoot.getPath());
+    properties.setProperty(Configuration.SERVER_VERSION_FILE, versionFile.getPath());
+    Configuration configuration = new Configuration(properties);
+
+    TestAmbariMetaInfo metaInfo = new TestAmbariMetaInfo(configuration);
     if (replayMocks) {
       metaInfo.replayAllMocks();
 
@@ -1902,20 +1917,28 @@ public class AmbariMetaInfoTest {
     AlertDefinitionFactory alertDefinitionFactory;
     OsFamily osFamily;
 
-    public TestAmbariMetaInfo(File stackRoot, File serverVersionFile) throws Exception {
-      super(stackRoot, null, serverVersionFile);
-      // MetainfoDAO
-      metaInfoDAO = createNiceMock(MetainfoDAO.class);
+    public TestAmbariMetaInfo(Configuration configuration) throws Exception {
+      super(configuration);
+
+      Injector injector = Guice.createInjector(Modules.override(
+          new InMemoryDefaultTestModule()).with(new MockModule()));
+
+      injector.getInstance(GuiceJpaInitializer.class);
+      injector.getInstance(EntityManager.class);
+
       Class<?> c = getClass().getSuperclass();
+
+      // MetainfoDAO
+      metaInfoDAO = injector.getInstance(MetainfoDAO.class);
       Field f = c.getDeclaredField("metaInfoDAO");
       f.setAccessible(true);
       f.set(this, metaInfoDAO);
 
-      // ActionMetadata
-      ActionMetadata actionMetadata = new ActionMetadata();
-      f = c.getDeclaredField("actionMetadata");
+      // StackManagerFactory
+      StackManagerFactory stackManagerFactory = injector.getInstance(StackManagerFactory.class);
+      f = c.getDeclaredField("stackManagerFactory");
       f.setAccessible(true);
-      f.set(this, actionMetadata);
+      f.set(this, stackManagerFactory);
 
       //AlertDefinitionDAO
       alertDefinitionDAO = createNiceMock(AlertDefinitionDAO.class);
@@ -1956,9 +1979,12 @@ public class AmbariMetaInfoTest {
       else {
         expect(config.getSharedResourcesDirPath()).andReturn("./src/test/resources").anyTimes();
       }
+
       replay(config);
+
       osFamily = new OsFamily(config);
-      f = c.getDeclaredField("os_family");
+
+      f = c.getDeclaredField("osFamily");
       f.setAccessible(true);
       f.set(this, osFamily);
     }
@@ -1966,5 +1992,16 @@ public class AmbariMetaInfoTest {
     public void replayAllMocks() {
       replay(metaInfoDAO, alertDefinitionDAO);
     }
+
+    public class MockModule extends AbstractModule {
+      @Override
+      protected void configure() {
+        bind(ActionMetadata.class);
+
+        // create a mock metainfo DAO for the entire system so that injectables
+        // can use the mock as well
+        bind(MetainfoDAO.class).toInstance(createNiceMock(MetainfoDAO.class));
+      }
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/api/services/KerberosServiceMetaInfoTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/KerberosServiceMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/KerberosServiceMetaInfoTest.java
index fe006ea..cafbc6f 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/KerberosServiceMetaInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/KerberosServiceMetaInfoTest.java
@@ -28,6 +28,9 @@ import java.lang.reflect.Field;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
+
+import javax.persistence.EntityManager;
 
 import junit.framework.Assert;
 
@@ -35,9 +38,12 @@ import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.metadata.ActionMetadata;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
 import org.apache.ambari.server.orm.dao.MetainfoDAO;
 import org.apache.ambari.server.stack.StackManager;
+import org.apache.ambari.server.stack.StackManagerFactory;
 import org.apache.ambari.server.state.AutoDeployInfo;
 import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.DependencyInfo;
@@ -49,6 +55,11 @@ import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.util.Modules;
+
 public class KerberosServiceMetaInfoTest {
   private final static Logger LOG = LoggerFactory.getLogger(KerberosServiceMetaInfoTest.class);
   private ServiceInfo serviceInfo = null;
@@ -186,7 +197,13 @@ public class KerberosServiceMetaInfoTest {
   }
 
   private TestAmbariMetaInfo createAmbariMetaInfo(File stackRoot, File commonServicesRoot, File versionFile, boolean replayMocks) throws Exception {
-    TestAmbariMetaInfo metaInfo = new TestAmbariMetaInfo(stackRoot, commonServicesRoot, versionFile);
+    Properties properties = new Properties();
+    properties.setProperty(Configuration.METADETA_DIR_PATH, stackRoot.getPath());
+    properties.setProperty(Configuration.COMMON_SERVICES_DIR_PATH, commonServicesRoot.getPath());
+    properties.setProperty(Configuration.SERVER_VERSION_FILE, versionFile.getPath());
+    Configuration configuration = new Configuration(properties);
+
+    TestAmbariMetaInfo metaInfo = new TestAmbariMetaInfo(configuration);
     if (replayMocks) {
       metaInfo.replayAllMocks();
 
@@ -223,20 +240,28 @@ public class KerberosServiceMetaInfoTest {
     AlertDefinitionFactory alertDefinitionFactory;
     OsFamily osFamily;
 
-    public TestAmbariMetaInfo(File stackRoot, File commonServicesRoot, File serverVersionFile) throws Exception {
-      super(stackRoot, commonServicesRoot, serverVersionFile);
-      // MetainfoDAO
-      metaInfoDAO = createNiceMock(MetainfoDAO.class);
+    public TestAmbariMetaInfo(Configuration configuration) throws Exception {
+      super(configuration);
+
+      Injector injector = Guice.createInjector(Modules.override(
+          new InMemoryDefaultTestModule()).with(new MockModule()));
+
+      injector.getInstance(GuiceJpaInitializer.class);
+      injector.getInstance(EntityManager.class);
+
       Class<?> c = getClass().getSuperclass();
+
+      // MetainfoDAO
+      metaInfoDAO = injector.getInstance(MetainfoDAO.class);
       Field f = c.getDeclaredField("metaInfoDAO");
       f.setAccessible(true);
       f.set(this, metaInfoDAO);
 
-      // ActionMetadata
-      ActionMetadata actionMetadata = new ActionMetadata();
-      f = c.getDeclaredField("actionMetadata");
+      // StackManagerFactory
+      StackManagerFactory stackManagerFactory = injector.getInstance(StackManagerFactory.class);
+      f = c.getDeclaredField("stackManagerFactory");
       f.setAccessible(true);
-      f.set(this, actionMetadata);
+      f.set(this, stackManagerFactory);
 
       //AlertDefinitionDAO
       alertDefinitionDAO = createNiceMock(AlertDefinitionDAO.class);
@@ -262,7 +287,7 @@ public class KerberosServiceMetaInfoTest {
       expect(config.getSharedResourcesDirPath()).andReturn("./src/test/resources").anyTimes();
       replay(config);
       osFamily = new OsFamily(config);
-      f = c.getDeclaredField("os_family");
+      f = c.getDeclaredField("osFamily");
       f.setAccessible(true);
       f.set(this, osFamily);
     }
@@ -270,6 +295,17 @@ public class KerberosServiceMetaInfoTest {
     public void replayAllMocks() {
       replay(metaInfoDAO, alertDefinitionDAO);
     }
+
+    public class MockModule extends AbstractModule {
+      @Override
+      protected void configure() {
+        bind(ActionMetadata.class);
+
+        // create a mock metainfo DAO for the entire system so that injectables
+        // can use the mock as well
+        bind(MetainfoDAO.class).toInstance(createNiceMock(MetainfoDAO.class));
+      }
+    }
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
index 7684322..ee56ea7 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelperTest.java
@@ -46,7 +46,6 @@ import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.HostState;
-import org.apache.ambari.server.state.SecurityState;
 import org.apache.ambari.server.state.SecurityType;
 import org.apache.ambari.server.state.State;
 import org.junit.After;
@@ -93,7 +92,6 @@ public class
     controller = injector.getInstance(AmbariManagementController.class);
     clusters = injector.getInstance(Clusters.class);
     ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
-    ambariMetaInfo.init();
   }
   @After
   public void teardown() {
@@ -308,8 +306,9 @@ public class
     setOsFamily(clusters.getHost(hostname), "redhat", "6.3");
     clusters.getHost(hostname).setState(HostState.HEALTHY);
     clusters.getHost(hostname).persist();
-    if (null != clusterName)
+    if (null != clusterName) {
       clusters.mapHostToCluster(hostname, clusterName);
+    }
   }
   private void setOsFamily(Host host, String osFamily, String osVersion) {
     Map<String, String> hostAttributes = new HashMap<String, String>();

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index 31c315b..87820ca 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -34,7 +34,6 @@ import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.StringReader;
 import java.lang.reflect.Type;
@@ -8046,9 +8045,14 @@ public class AmbariManagementControllerTest {
     assertEquals(original, repo.getDefaultBaseUrl());
 
     // verify change with new meta info
-    AmbariMetaInfo ami = new AmbariMetaInfo(new File(
-        "src/test/resources/stacks"), null, new File(
-        "src/test/resources/version"));
+    Configuration configuration = injector.getInstance(Configuration.class);
+    Properties properties = configuration.getProperties();
+    properties.setProperty(Configuration.METADETA_DIR_PATH, "src/test/resources/stacks");
+    properties.setProperty(Configuration.SERVER_VERSION_FILE, "src/test/resources/version");
+    Configuration newConfiguration = new Configuration(properties);
+
+    AmbariMetaInfo ami = new AmbariMetaInfo(newConfiguration);
+
     injector.injectMembers(ami);
     ami.init();
 
@@ -8764,6 +8768,7 @@ public class AmbariManagementControllerTest {
   }
 
   @Test
+  @Ignore
   public void testDisableAndDeleteStates() throws Exception {
     Map<String,String> mapRequestProps = new HashMap<String, String>();
     Injector injector = Guice.createInjector(new AbstractModule() {
@@ -8780,8 +8785,7 @@ public class AmbariManagementControllerTest {
           install(new ControllerModule(properties));
 
           // ambari events interfere with the workflow of this test
-          bind(AmbariEventPublisher.class).toInstance(
-              EasyMock.createMock(AmbariEventPublisher.class));
+          bind(AmbariEventPublisher.class).toInstance(EasyMock.createMock(AmbariEventPublisher.class));
         } catch (Exception e) {
           throw new RuntimeException(e);
         }
@@ -8946,6 +8950,7 @@ public class AmbariManagementControllerTest {
       componentHostRequests.add(new ServiceComponentHostRequest("c1", null, "NAMENODE", "host1", null));
 
       amc.deleteHostComponents(componentHostRequests);
+
       namenodes = cluster.getService("HDFS").getServiceComponent("NAMENODE").getServiceComponentHosts();
       org.junit.Assert.assertEquals(1, namenodes.size());
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/controller/BackgroundCustomCommandExecutionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/BackgroundCustomCommandExecutionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/BackgroundCustomCommandExecutionTest.java
index 78355eb..4446dfd 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/BackgroundCustomCommandExecutionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/BackgroundCustomCommandExecutionTest.java
@@ -98,7 +98,6 @@ public class BackgroundCustomCommandExecutionTest {
     Assert.assertEquals("src/main/resources/custom_action_definitions", configuration.getCustomActionDefinitionPath());
     
     ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
-    ambariMetaInfo.init();
   }
   @After
   public void teardown() {
@@ -167,8 +166,9 @@ public class BackgroundCustomCommandExecutionTest {
     setOsFamily(clusters.getHost(hostname), "redhat", "6.3");
     clusters.getHost(hostname).setState(HostState.HEALTHY);
     clusters.getHost(hostname).persist();
-    if (null != clusterName)
+    if (null != clusterName) {
       clusters.mapHostToCluster(hostname, clusterName);
+    }
   }
   private void setOsFamily(Host host, String osFamily, String osVersion) {
     Map<String, String> hostAttributes = new HashMap<String, String>();

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
index 5e71991..524c511 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
@@ -18,10 +18,33 @@
 
 package org.apache.ambari.server.controller;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import static org.easymock.EasyMock.anyLong;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.getCurrentArguments;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+
 import junit.framework.Assert;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.actionmanager.ActionManager;
@@ -48,6 +71,7 @@ import org.apache.ambari.server.serveraction.kerberos.KerberosMissingAdminCreden
 import org.apache.ambari.server.serveraction.kerberos.KerberosOperationException;
 import org.apache.ambari.server.serveraction.kerberos.KerberosOperationHandler;
 import org.apache.ambari.server.serveraction.kerberos.KerberosOperationHandlerFactory;
+import org.apache.ambari.server.stack.StackManagerFactory;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
@@ -80,22 +104,9 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import javax.persistence.EntityManager;
-
-import java.io.File;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
 
 @SuppressWarnings("unchecked")
 public class KerberosHelperTest extends EasyMockSupport {
@@ -171,6 +182,7 @@ public class KerberosHelperTest extends EasyMockSupport {
         bind(ClusterController.class).toInstance(clusterController);
         bind(KerberosDescriptorFactory.class).toInstance(kerberosDescriptorFactory);
         bind(KerberosConfigDataFileWriterFactory.class).toInstance(kerberosConfigDataFileWriterFactory);
+        bind(StackManagerFactory.class).toInstance(createNiceMock(StackManagerFactory.class));
       }
     });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/controller/RefreshYarnCapacitySchedulerReleaseConfigTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/RefreshYarnCapacitySchedulerReleaseConfigTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/RefreshYarnCapacitySchedulerReleaseConfigTest.java
index 2c927a3..3a6ad91 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/RefreshYarnCapacitySchedulerReleaseConfigTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/RefreshYarnCapacitySchedulerReleaseConfigTest.java
@@ -68,7 +68,6 @@ public class RefreshYarnCapacitySchedulerReleaseConfigTest {
     clusters = injector.getInstance(Clusters.class);
     configHelper = injector.getInstance(ConfigHelper.class);
     ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
-    ambariMetaInfo.init();
   }
   @After
   public void teardown() {
@@ -170,8 +169,9 @@ public class RefreshYarnCapacitySchedulerReleaseConfigTest {
     setOsFamily(clusters.getHost(hostname), "redhat", "6.3");
     clusters.getHost(hostname).setState(HostState.HEALTHY);
     clusters.getHost(hostname).persist();
-    if (null != clusterName)
+    if (null != clusterName) {
       clusters.mapHostToCluster(hostname, clusterName);
+    }
   }
 
   private void setOsFamily(Host host, String osFamily, String osVersion) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
index 29677fc..1cc75c7 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
@@ -18,36 +18,40 @@
 
 package org.apache.ambari.server.controller.internal;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.persist.PersistService;
-import com.google.inject.util.Modules;
-import org.apache.ambari.server.AmbariException;
+import static org.easymock.EasyMock.anyLong;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
-import org.apache.ambari.server.agent.AgentEnv;
 import org.apache.ambari.server.agent.CommandReport;
-import org.apache.ambari.server.agent.DiskInfo;
-import org.apache.ambari.server.agent.HostInfo;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
-import org.apache.ambari.server.controller.AmbariManagementControllerImpl;
-import org.apache.ambari.server.controller.HostResponse;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.ResourceProviderFactory;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.metadata.ActionMetadata;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
-import org.apache.ambari.server.orm.entities.HostVersionEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.serveraction.upgrades.FinalizeUpgradeAction;
-import org.apache.ambari.server.stack.StackManager;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ConfigHelper;
@@ -57,39 +61,15 @@ import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.ServiceOsSpecific;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.cluster.ClusterImpl;
-import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
 
-import java.lang.reflect.Field;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import static org.easymock.EasyMock.anyLong;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.createStrictMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+import com.google.inject.util.Modules;
 
 /**
  * ClusterStackVersionResourceProvider tests.
@@ -130,7 +110,6 @@ public class ClusterStackVersionResourceProviderTest {
     injector = Guice.createInjector(Modules.override(module).with(new MockModule()));
     injector.getInstance(GuiceJpaInitializer.class);
     ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
-    ambariMetaInfo.init();
   }
 
   @After
@@ -332,7 +311,7 @@ public class ClusterStackVersionResourceProviderTest {
     // Have to inject instance manually because injection via DI fails
     Field field = ClusterStackVersionResourceProvider.class.getDeclaredField("finalizeUpgradeAction");
     field.setAccessible(true);
-    field.set((ClusterStackVersionResourceProvider)provider, finalizeUpgradeAction);
+    field.set(provider, finalizeUpgradeAction);
 
     // add the property map to a set for the request.  add more maps for multiple creates
     Map<String, Object> properties = new LinkedHashMap<String, Object>();

http://git-wip-us.apache.org/repos/asf/ambari/blob/69197e63/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProviderTest.java
index a868234..aa391ca 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProviderTest.java
@@ -18,11 +18,23 @@
 
 package org.apache.ambari.server.controller.internal;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.persist.PersistService;
-import com.google.inject.util.Modules;
+import static org.easymock.EasyMock.anyLong;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -55,22 +67,11 @@ import org.junit.Before;
 import org.junit.Test;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.easymock.EasyMock.anyLong;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+import com.google.inject.util.Modules;
 
 /**
  * ClusterStackVersionResourceProvider tests.
@@ -114,7 +115,6 @@ public class HostStackVersionResourceProviderTest {
     injector = Guice.createInjector(Modules.override(module).with(new MockModule()));
     injector.getInstance(GuiceJpaInitializer.class);
     ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
-    ambariMetaInfo.init();
   }
 
   @After