You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by mr...@apache.org on 2017/06/05 19:27:13 UTC

ambari git commit: AMBARI-21150: Mpack API and DB Schema changes (mradhakrishnan)

Repository: ambari
Updated Branches:
  refs/heads/branch-feature-AMBARI-14714 14f60af1b -> e30f8384a


AMBARI-21150: Mpack API and DB Schema changes (mradhakrishnan)


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

Branch: refs/heads/branch-feature-AMBARI-14714
Commit: e30f8384a7fb2890a7f0c1009a8385388fbbb8e2
Parents: 14f60af
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
Authored: Mon Jun 5 12:25:48 2017 -0700
Committer: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
Committed: Mon Jun 5 12:25:48 2017 -0700

----------------------------------------------------------------------
 ambari-server/conf/unix/ambari.properties       |   1 +
 ambari-server/conf/windows/ambari.properties    |   1 +
 .../api/resources/MpackResourceDefinition.java  |  50 +++++
 .../resources/ResourceInstanceFactoryImpl.java  |   4 +
 .../api/services/AbstractVersionService.java    |  10 +
 .../server/api/services/AmbariMetaInfo.java     |  54 +++++
 .../server/api/services/MpacksService.java      | 102 +++++++++
 .../server/configuration/Configuration.java     |  17 ++
 .../controller/AmbariManagementController.java  |  20 ++
 .../AmbariManagementControllerImpl.java         |  45 ++--
 .../server/controller/ControllerModule.java     |   2 +
 .../ambari/server/controller/MpackRequest.java  |  82 ++++++++
 .../ambari/server/controller/MpackResponse.java |  99 +++++++++
 .../internal/DefaultProviderModule.java         |   8 +-
 .../internal/MpackResourceProvider.java         | 209 +++++++++++++++++++
 .../ambari/server/controller/spi/Resource.java  |   2 +
 .../system/impl/AmbariMetricSinkImpl.java       |   2 -
 .../ambari/server/mpack/MpackManager.java       | 194 +++++++++++++++++
 .../server/mpack/MpackManagerFactory.java       |  37 ++++
 .../apache/ambari/server/orm/dao/MpackDAO.java  |  99 +++++++++
 .../ambari/server/orm/entities/MpackEntity.java | 158 ++++++++++++++
 .../org/apache/ambari/server/state/Mpacks.java  | 114 ++++++++++
 .../org/apache/ambari/server/state/Packlet.java |  65 ++++++
 .../main/resources/Ambari-DDL-Derby-CREATE.sql  |  19 ++
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |  18 ++
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |  18 ++
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |  18 ++
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql |  18 ++
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |  18 ++
 .../src/main/resources/META-INF/persistence.xml |   1 +
 .../system/impl/TestAmbariMetricsSinkImpl.java  |   2 -
 31 files changed, 1449 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/conf/unix/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/unix/ambari.properties b/ambari-server/conf/unix/ambari.properties
index b8b645d..282335e 100644
--- a/ambari-server/conf/unix/ambari.properties
+++ b/ambari-server/conf/unix/ambari.properties
@@ -131,6 +131,7 @@ views.http.pragma=no-cache
 views.http.charset=utf-8
 
 mpacks.staging.path=$ROOT/var/lib/ambari-server/resources/mpacks
+mpacks-v2.staging.path=$ROOT/var/lib/ambari-server/resources/mpacks-v2
 
 # exclude some ciphers that are not supported by old versions of ssl (this fix was added for SLES12)
 security.server.disabled.ciphers=TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384|TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384|TLS_RSA_WITH_AES_256_CBC_SHA256|TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384|TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384|TLS_DHE_RSA_WITH_AES_256_CBC_SHA256|TLS_DHE_DSS_WITH_AES_256_CBC_SHA256|TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA|TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA|TLS_RSA_WITH_AES_256_CBC_SHA|TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA|TLS_ECDH_RSA_WITH_AES_256_CBC_SHA|TLS_DHE_RSA_WITH_AES_256_CBC_SHA|TLS_DHE_DSS_WITH_AES_256_CBC_SHA|TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256|TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256|TLS_RSA_WITH_AES_128_CBC_SHA256|TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256|TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256|TLS_DHE_RSA_WITH_AES_128_CBC_SHA256|TLS_DHE_DSS_WITH_AES_128_CBC_SHA256|TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA|TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA|TLS_RSA_WITH_AES_128_CBC_SHA|TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA|TLS_ECDH_RSA_WITH_AES_128_CBC_SHA|TLS_DHE_RSA_WITH_AES_128_CBC_SHA|TLS_DHE
 _DSS_WITH_AES_128_CBC_SHA|TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA|TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA|TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA|TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA|SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA|SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA|TLS_EMPTY_RENEGOTIATION_INFO_SCSV|TLS_DH_anon_WITH_AES_256_CBC_SHA256|TLS_ECDH_anon_WITH_AES_256_CBC_SHA|TLS_DH_anon_WITH_AES_256_CBC_SHA|TLS_DH_anon_WITH_AES_128_CBC_SHA256|TLS_ECDH_anon_WITH_AES_128_CBC_SHA|TLS_DH_anon_WITH_AES_128_CBC_SHA|TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA|SSL_DH_anon_WITH_3DES_EDE_CBC_SHA|SSL_RSA_WITH_DES_CBC_SHA|SSL_DHE_RSA_WITH_DES_CBC_SHA|SSL_DHE_DSS_WITH_DES_CBC_SHA|SSL_DH_anon_WITH_DES_CBC_SHA|SSL_RSA_EXPORT_WITH_DES40_CBC_SHA|SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA|SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA|SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA|TLS_RSA_WITH_NULL_SHA256|TLS_ECDHE_ECDSA_WITH_NULL_SHA|TLS_ECDHE_RSA_WITH_NULL_SHA|SSL_RSA_WITH_NULL_SHA|TLS_ECDH_ECDSA_WITH_NULL_SHA|TLS_ECDH_RSA_WITH_NULL_SHA|TLS_ECDH_anon_WITH_NULL_
 SHA|SSL_RSA_WITH_NULL_MD5|TLS_KRB5_WITH_3DES_EDE_CBC_SHA|TLS_KRB5_WITH_3DES_EDE_CBC_MD5|TLS_KRB5_WITH_DES_CBC_SHA|TLS_KRB5_WITH_DES_CBC_MD5|TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA|TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/conf/windows/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/windows/ambari.properties b/ambari-server/conf/windows/ambari.properties
index 80d14ff..f1db315 100644
--- a/ambari-server/conf/windows/ambari.properties
+++ b/ambari-server/conf/windows/ambari.properties
@@ -109,6 +109,7 @@ views.http.pragma=no-cache
 views.http.charset=utf-8
 
 mpacks.staging.path=resources\\mpacks
+mpacks-v2.staging.path=resources\\mpacks-v2
 
 views.skip.home-directory-check.file-system.list=wasb,adls,adl
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/api/resources/MpackResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/MpackResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/MpackResourceDefinition.java
new file mode 100644
index 0000000..e33cd31
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/MpackResourceDefinition.java
@@ -0,0 +1,50 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.api.resources;
+
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Resource Definition for Mpack Resource types.
+ */
+public class MpackResourceDefinition extends BaseResourceDefinition {
+
+  private final static Logger LOG =
+          LoggerFactory.getLogger(MpackResourceDefinition.class);
+
+  public MpackResourceDefinition(Type resourceType) {
+    super(Resource.Type.Mpack);
+  }
+
+  public MpackResourceDefinition() {
+    super(Resource.Type.Mpack);
+  }
+
+  @Override
+  public String getPluralName() {
+    return "mpacks";
+  }
+
+  @Override
+  public String getSingularName() {
+    return "mpack";
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
index 7f7da80..1466b86 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
@@ -153,6 +153,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
         resourceDefinition = new MemberResourceDefinition();
         break;
 
+      case Mpack:
+        resourceDefinition = new MpackResourceDefinition();
+        break;
+
       case Request:
         resourceDefinition = new RequestResourceDefinition();
         break;

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/api/services/AbstractVersionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AbstractVersionService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AbstractVersionService.java
index 915595a..2d81602 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AbstractVersionService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AbstractVersionService.java
@@ -348,5 +348,15 @@ public abstract class AbstractVersionService {
     return new KdcServerReachabilityCheck();
   }
 
+  /**
+   * Handles /mpacks request.
+   *
+   * @return mpacks service
+   */
+  @Path("/mpacks")
+  public MpacksService getMpacksService(@PathParam("apiVersion") String apiVersion) {
+    return new MpacksService(ApiVersion.valueOf(apiVersion));
+  }
+
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/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 c655c62..ee3b8e5 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
@@ -44,7 +44,10 @@ import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ParentObjectNotFoundException;
 import org.apache.ambari.server.StackAccessException;
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.MpackRequest;
+import org.apache.ambari.server.controller.MpackResponse;
 import org.apache.ambari.server.controller.RootServiceResponseFactory.Services;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.customactions.ActionDefinition;
 import org.apache.ambari.server.customactions.ActionDefinitionManager;
@@ -52,6 +55,8 @@ 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.AmbariServiceAlertDefinitions;
+import org.apache.ambari.server.mpack.MpackManager;
+import org.apache.ambari.server.mpack.MpackManagerFactory;
 import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
 import org.apache.ambari.server.orm.dao.MetainfoDAO;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
@@ -71,6 +76,7 @@ import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.Packlet;
 import org.apache.ambari.server.state.alert.AlertDefinition;
 import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
 import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
@@ -169,6 +175,7 @@ public class AmbariMetaInfo {
   private File extensionsRoot;
   private File serverVersionFile;
   private File customActionRoot;
+  private File mpacksV2Staging;
   private Map<String, VersionDefinitionXml> versionDefinitions = null;
 
 
@@ -229,6 +236,18 @@ public class AmbariMetaInfo {
    */
   private StackManager stackManager;
 
+  /**
+   * Factory for injecting {@link MpackManager} instances.
+   */
+  @Inject
+  private MpackManagerFactory mpackManagerFactory;
+
+  /**
+  * Singleton instance of mpack manager
+  */
+  private MpackManager mpackManager;
+
+
   private Configuration conf;
 
   /**
@@ -257,6 +276,10 @@ public class AmbariMetaInfo {
     serverVersionFile = new File(serverVersionFilePath);
 
     customActionRoot = new File(conf.getCustomActionDefinitionPath());
+
+    String mpackV2StagingPath = conf.getMpacksV2StagingPath();
+    mpacksV2Staging = new File(mpackV2StagingPath);
+
   }
 
   /**
@@ -274,6 +297,8 @@ public class AmbariMetaInfo {
     stackManager = stackManagerFactory.create(stackRoot, commonServicesRoot, extensionsRoot,
         osFamily, false);
 
+    mpackManager = mpackManagerFactory.create(mpacksV2Staging);
+
     getCustomActionDefinitions(customActionRoot);
   }
 
@@ -286,6 +311,14 @@ public class AmbariMetaInfo {
   }
 
   /**
+   * Obtain the underlying mpack manager.
+   * @return mpack manager
+   */
+  public MpackManager getMpackManager() {
+    return mpackManager;
+  }
+
+  /**
    * Get components by service
    *
    * @param stackName     stack name
@@ -622,6 +655,27 @@ public class AmbariMetaInfo {
     return stackManager.getStacks();
   }
 
+  /**
+   * Calls the registerMpack method from mpackManager to support a POST /mpacks request
+   * @param mpackRequest
+   * @return MpackResponse
+   * @throws IOException
+   * @throws ResourceAlreadyExistsException
+   */
+  public MpackResponse registerMpack(MpackRequest mpackRequest) throws IOException, ResourceAlreadyExistsException {
+    return mpackManager.registerMpack(mpackRequest);
+  }
+
+  /**
+   * Gets the packlet information for given mpack.
+   * @param mpackId
+   * @return List of Packlets.
+   */
+  public ArrayList<Packlet> getPacklets(Long mpackId) {
+    return mpackManager.getPacklets(mpackId);
+  }
+
+
   public Collection<StackInfo> getStacks(String stackName) throws AmbariException {
     Collection<StackInfo> stacks = stackManager.getStacks(stackName);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/api/services/MpacksService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/MpacksService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/MpacksService.java
new file mode 100644
index 0000000..9912f88
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/MpacksService.java
@@ -0,0 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.api.services;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.api.util.ApiVersion;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.Collections;
+
+/**
+ * Service for Mpacks Management.
+ * Endpoint for Mpack Data
+ */
+
+public class MpacksService extends BaseService {
+
+  public MpacksService(ApiVersion apiVersion) {
+    super(apiVersion);
+  }
+
+  /**
+   * Handles: GET /mpacks/
+   *
+   * @param headers http headers
+   * @param ui      uri info
+   * @param body    request body
+   * @return All the existing mpack definitions
+   *
+   */
+  @GET
+  @Produces("text/plain")
+  public Response getMpacks(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+    return handleRequest(headers, body, ui, Request.Type.GET,
+            createMpackResource(null));
+  }
+
+  /**
+   * Handles: POST /mpacks/
+   *
+   * @param headers http headers
+   * @param ui      uri info
+   * @param body    request body
+   * @return information regarding the created mpack
+   */
+  @POST
+  @Produces("text/plain")
+  public Response createMpacks(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+    return handleRequest(headers, body, ui, Request.Type.POST, createMpackResource(null));
+  }
+
+  /***
+   * Handles: GET /mpacks/{mpack_id}
+   * Return a specific mpack given an mpack_id
+   *
+   * @param
+   */
+  @GET
+  @Path("{mpack_id}")
+  @Produces("text/plain")
+  public Response getMpack(String body, @Context HttpHeaders headers, @Context UriInfo ui, @PathParam("mpack_id") String mpackId) {
+
+    return handleRequest(headers, body, ui, Request.Type.GET,
+            createMpackResource(mpackId));
+  }
+
+  /**
+   * Create an mpack resource instance
+   * @param mpackId
+   * @return ResourceInstance
+   */
+  private ResourceInstance createMpackResource(String mpackId) {
+    return createResource(Resource.Type.Mpack,
+            Collections.singletonMap(Resource.Type.Mpack, mpackId));
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/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 114046f..fb07214 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
@@ -721,6 +721,15 @@ public class Configuration {
       "mpacks.staging.path", null);
 
   /**
+   * The Ambari Management Pack v2 staging directory on the Ambari Server.
+   */
+  @Markdown(
+          description = "The Ambari Management Pack version-2 staging directory on the Ambari Server.",
+          examples = { "/var/lib/ambari-server/resources/mpacks-v2" })
+  public static final ConfigurationProperty<String> MPACKS_V2_STAGING_DIR_PATH = new ConfigurationProperty<>(
+          "mpacks-v2.staging.path", null);
+
+  /**
    * The full path to the file which contains the Ambari Server version.
    */
   @Markdown(
@@ -3564,6 +3573,14 @@ public class Configuration {
     return getProperty(MPACKS_STAGING_DIR_PATH);
   }
 
+  /**
+   * Gets ambari v2 management packs staging directory
+   * @return String
+   */
+  public String getMpacksV2StagingPath() {
+    return getProperty(MPACKS_V2_STAGING_DIR_PATH);
+  }
+
 
   public String getServerVersionFilePath() {
     return getProperty(SERVER_VERSION_FILE);

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/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 b6b481f..de7ef5e 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
@@ -18,10 +18,12 @@
 
 package org.apache.ambari.server.controller;
 
+import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.ArrayList;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.RoleCommand;
@@ -36,6 +38,7 @@ import org.apache.ambari.server.controller.logging.LoggingSearchPropertyProvider
 import org.apache.ambari.server.controller.metrics.MetricPropertyProviderFactory;
 import org.apache.ambari.server.controller.metrics.MetricsCollectorHAManager;
 import org.apache.ambari.server.controller.metrics.timeline.cache.TimelineMetricCacheProvider;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 import org.apache.ambari.server.events.AmbariEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.metadata.RoleCommandOrder;
@@ -59,6 +62,7 @@ import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.ServiceOsSpecific;
 import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.Packlet;
 import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityController;
 import org.apache.ambari.server.state.scheduler.RequestExecutionFactory;
@@ -145,6 +149,15 @@ public interface AmbariManagementController {
    */
   void createMembers(Set<MemberRequest> requests) throws AmbariException;
 
+  /**
+   * Register the mpack defined by the attributes in the given request object.
+   *
+   * @param request the request object which defines the mpack to be created
+   * @throws AmbariException        thrown if the mpack cannot be created
+   * @throws AuthorizationException thrown if the authenticated user is not authorized to perform this operation
+   */
+  MpackResponse registerMpack(MpackRequest request) throws IOException, AuthorizationException, ResourceAlreadyExistsException;
+
 
   // ----- Read -------------------------------------------------------------
 
@@ -921,5 +934,12 @@ public interface AmbariManagementController {
    */
   QuickLinkVisibilityController getQuicklinkVisibilityController();
 
+  /**
+   * Fetch the packlet info for a given mpack.
+   *
+   * @param mpackId
+   * @return List of packlets
+   */
+  ArrayList<Packlet> getPacklets(Long mpackId);
 }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/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 c950940..7f173e9 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
@@ -105,6 +105,7 @@ import org.apache.ambari.server.controller.metrics.MetricPropertyProviderFactory
 import org.apache.ambari.server.controller.metrics.MetricsCollectorHAManager;
 import org.apache.ambari.server.controller.metrics.timeline.cache.TimelineMetricCacheProvider;
 import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 import org.apache.ambari.server.customactions.ActionDefinition;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.metadata.ActionMetadata;
@@ -152,38 +153,9 @@ import org.apache.ambari.server.stack.ExtensionHelper;
 import org.apache.ambari.server.stack.RepoUtil;
 import org.apache.ambari.server.stageplanner.RoleGraph;
 import org.apache.ambari.server.stageplanner.RoleGraphFactory;
-import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.CommandScriptDefinition;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.Config;
-import org.apache.ambari.server.state.ConfigFactory;
-import org.apache.ambari.server.state.ConfigHelper;
-import org.apache.ambari.server.state.DesiredConfig;
-import org.apache.ambari.server.state.ExtensionInfo;
-import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.HostComponentAdminState;
-import org.apache.ambari.server.state.HostState;
-import org.apache.ambari.server.state.MaintenanceState;
-import org.apache.ambari.server.state.OperatingSystemInfo;
-import org.apache.ambari.server.state.PropertyDependencyInfo;
-import org.apache.ambari.server.state.PropertyInfo;
+import org.apache.ambari.server.state.*;
+import org.apache.ambari.server.state.PropertyInfo.PropertyType;
 import org.apache.ambari.server.state.PropertyInfo.PropertyType;
-import org.apache.ambari.server.state.RepositoryInfo;
-import org.apache.ambari.server.state.RepositoryVersionState;
-import org.apache.ambari.server.state.SecurityType;
-import org.apache.ambari.server.state.Service;
-import org.apache.ambari.server.state.ServiceComponent;
-import org.apache.ambari.server.state.ServiceComponentFactory;
-import org.apache.ambari.server.state.ServiceComponentHost;
-import org.apache.ambari.server.state.ServiceComponentHostEvent;
-import org.apache.ambari.server.state.ServiceComponentHostFactory;
-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.StackInfo;
-import org.apache.ambari.server.state.State;
-import org.apache.ambari.server.state.UnlimitedKeyJCERequirement;
 import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityController;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityControllerFactory;
@@ -511,6 +483,17 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   }
 
   @Override
+  public MpackResponse registerMpack(MpackRequest request) throws IOException, AuthorizationException, ResourceAlreadyExistsException{
+    MpackResponse mpackResponse = ambariMetaInfo.registerMpack(request);
+    return mpackResponse;
+  }
+
+  @Override
+  public ArrayList<Packlet> getPacklets(Long mpackId) {
+    return ambariMetaInfo.getPacklets(mpackId);
+  }
+
+  @Override
   public synchronized void createHostComponents(Set<ServiceComponentHostRequest> requests)
       throws AmbariException, AuthorizationException {
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/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 4fa2362..404f394 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
@@ -91,6 +91,7 @@ import org.apache.ambari.server.metadata.CachedRoleCommandOrderProvider;
 import org.apache.ambari.server.metadata.RoleCommandOrderProvider;
 import org.apache.ambari.server.metrics.system.MetricsService;
 import org.apache.ambari.server.metrics.system.impl.MetricsServiceImpl;
+import org.apache.ambari.server.mpack.MpackManagerFactory;
 import org.apache.ambari.server.notifications.DispatchFactory;
 import org.apache.ambari.server.notifications.NotificationDispatcher;
 import org.apache.ambari.server.notifications.dispatchers.AlertScriptDispatcher;
@@ -492,6 +493,7 @@ public class ControllerModule extends AbstractModule {
     install(new FactoryModuleBuilder().build(ExecutionCommandWrapperFactory.class));
     install(new FactoryModuleBuilder().build(MetricPropertyProviderFactory.class));
     install(new FactoryModuleBuilder().build(UpgradeContextFactory.class));
+    install(new FactoryModuleBuilder().build(MpackManagerFactory.class));
 
     bind(HostRoleCommandFactory.class).to(HostRoleCommandFactoryImpl.class);
     bind(SecurityHelper.class).toInstance(SecurityHelperImpl.getInstance());

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/controller/MpackRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/MpackRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/MpackRequest.java
new file mode 100644
index 0000000..fa6dd1d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/MpackRequest.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller;
+
+import org.apache.ambari.server.orm.entities.MpackEntity;
+
+/**
+ * The {@link MpackRequest} encapsulates the data necessary to make a
+ * backend request for {@link MpackEntity}.
+ *
+ */
+public class MpackRequest {
+
+  private String mpackId;
+  private String mpackName;
+  private String mpackVersion;
+  private String mpackUrl;
+  private String registryId;
+
+  public MpackRequest(String mpackId) {
+    this.setMpackId(mpackId);
+  }
+
+  public MpackRequest() {
+  }
+
+  public String getMpackId() {
+    return mpackId;
+  }
+
+  public void setMpackId(String mpackId) {
+    this.mpackId = mpackId;
+  }
+
+  public String getMpackName() {
+    return mpackName;
+  }
+
+  public void setMpackName(String mpackName) {
+    this.mpackName = mpackName;
+  }
+
+  public String getMpackVersion() {
+    return mpackVersion;
+  }
+
+  public void setMpackVersion(String mpackVersion) {
+    this.mpackVersion = mpackVersion;
+  }
+
+  public String getMpackUrl() {
+    return mpackUrl;
+  }
+
+  public void setMpackUrl(String mpackUrl) {
+    this.mpackUrl = mpackUrl;
+  }
+
+  public String getRegistryId() {
+    return registryId;
+  }
+
+  public void setRegistryId(String registryId) {
+    this.registryId = registryId;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/controller/MpackResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/MpackResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/MpackResponse.java
new file mode 100644
index 0000000..d7cca79
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/MpackResponse.java
@@ -0,0 +1,99 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller;
+
+import org.apache.ambari.server.state.Mpacks;
+
+/**
+ * Represents a mpack response.
+ */
+public class MpackResponse {
+
+  private Long mpackId;
+  private String mpackVersion;
+  private String mpackName;
+  private String mpackUrl;
+  private String registryId;
+
+  public MpackResponse(Mpacks mpacks) {
+    this.mpackId = mpacks.getMpackId();
+    this.mpackVersion = mpacks.getVersion();
+    this.mpackUrl = mpacks.getMpacksUrl();
+    this.mpackName = mpacks.getName();
+    this.registryId = mpacks.getRegistryId();
+  }
+
+  public String getMpackVersion() {
+    return mpackVersion;
+  }
+
+  public String getMpackUrl() {
+    return mpackUrl;
+  }
+
+  public Long getMpackId() {
+    return mpackId;
+  }
+
+  public String getMpackName() {
+    return mpackName;
+  }
+
+  public String getRegistryId() {
+    return registryId;
+  }
+
+  public void setMpackVersion(String mpackVersion) {
+    this.mpackVersion = mpackVersion;
+  }
+
+  public void setMpackName(String mpackName) {
+    this.mpackName = mpackName;
+  }
+
+  public void setMpackUrl(String mpackUrl) {
+    this.mpackUrl = mpackUrl;
+  }
+
+  public void setRegistryId(String registryId) {
+    this.registryId = registryId;
+  }
+
+  public void setMpackId(Long mpackId) {
+    this.mpackId = mpackId;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = 1;
+    result = 31 + getMpackId().hashCode();
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (!(obj instanceof MpackResponse)) {
+      return false;
+    }
+    if (this == obj) {
+      return true;
+    }
+    MpackResponse MpackResponse = (MpackResponse) obj;
+    return getMpackId().equals(MpackResponse.getMpackId());
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
index 35fdcf6..e7ecd65 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
@@ -6,9 +6,9 @@
  * 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
  * 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.
@@ -90,6 +90,8 @@ public class DefaultProviderModule extends AbstractProviderModule {
         return new GroupPrivilegeResourceProvider();
       case Alert:
         return new AlertResourceProvider(managementController);
+      case Mpack:
+        return new MpackResourceProvider(managementController);
       case AlertDefinition:
         return new AlertDefinitionResourceProvider(managementController);
       case AlertHistory:

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java
new file mode 100644
index 0000000..7b4682a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/MpackResourceProvider.java
@@ -0,0 +1,209 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller.internal;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.inject.Inject;
+import org.apache.ambari.server.StaticallyInject;
+import org.apache.ambari.server.api.services.parsers.BodyParseException;
+import org.apache.ambari.server.controller.spi.RequestStatus;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.MpackResponse;
+import org.apache.ambari.server.controller.MpackRequest;
+
+
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
+import org.apache.ambari.server.orm.dao.MpackDAO;
+
+import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.apache.ambari.server.state.Packlet;
+
+/**
+ * ResourceProvider for Mpack instances
+ */
+@StaticallyInject
+public class MpackResourceProvider extends AbstractControllerResourceProvider {
+
+  public static final String MPACK_ID = "MpackInfo/mpack_id";
+  public static final String REGISTRY_ID = "MpackInfo/registry_id";
+  public static final String MPACK_NAME = "MpackInfo/mpack_name";
+  public static final String MPACK_VERSION = "MpackInfo/mpack_version";
+  public static final String MPACK_URL = "MpackInfo/mpack_url";
+  public static final String PACKLETS = "MpackInfo/packlets";
+
+
+  private static Set<String> pkPropertyIds = new HashSet<>(
+          Arrays.asList(MPACK_ID));
+
+  /**
+   * The property ids for an mpack resource.
+   */
+  private static final Set<String> PROPERTY_IDS = new HashSet<>();
+
+  /**
+   * The key property ids for a mpack resource.
+   */
+  private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = new HashMap<>();
+
+  @Inject
+  protected static MpackDAO mpackDAO;
+
+  static {
+    // properties
+    PROPERTY_IDS.add(MPACK_ID);
+    PROPERTY_IDS.add(REGISTRY_ID);
+    PROPERTY_IDS.add(MPACK_NAME);
+    PROPERTY_IDS.add(MPACK_VERSION);
+    PROPERTY_IDS.add(MPACK_URL);
+    PROPERTY_IDS.add(PACKLETS);
+
+    // keys
+    KEY_PROPERTY_IDS.put(Resource.Type.Mpack, MPACK_ID);
+
+  }
+
+  MpackResourceProvider(AmbariManagementController controller) {
+    super(PROPERTY_IDS, KEY_PROPERTY_IDS, controller);
+  }
+
+  @Override
+  protected Set<String> getPKPropertyIds() {
+    return pkPropertyIds;
+  }
+
+  @Override
+  public RequestStatus createResources(final Request request)
+          throws SystemException, UnsupportedPropertyException,
+          ResourceAlreadyExistsException, NoSuchParentResourceException, IllegalArgumentException {
+    Set<Resource> associatedResources = new HashSet<>();
+    try {
+      MpackRequest mpackRequest = getRequest(request);
+      if (mpackRequest == null)
+        throw new BodyParseException("Please provide " + MPACK_NAME + " ," + MPACK_VERSION + " ," + MPACK_URL);
+      MpackResponse response = getManagementController().registerMpack(mpackRequest);
+      if (response != null) {
+        notifyCreate(Resource.Type.Mpack, request);
+        Resource resource = new ResourceImpl(Resource.Type.Mpack);
+        resource.setProperty(MPACK_ID, response.getMpackId());
+        resource.setProperty(REGISTRY_ID, response.getRegistryId());
+        resource.setProperty(MPACK_NAME, response.getMpackName());
+        resource.setProperty(MPACK_VERSION, response.getMpackVersion());
+        resource.setProperty(MPACK_URL, response.getMpackUrl());
+
+        associatedResources.add(resource);
+        return getRequestStatus(null, associatedResources);
+      }
+    } catch (IOException e) {
+      e.printStackTrace();
+    } catch (BodyParseException e1) {
+      e1.printStackTrace();
+    }
+    return null;
+  }
+
+  public MpackRequest getRequest(Request request) {
+    MpackRequest mpackRequest = new MpackRequest();
+    Set<Map<String, Object>> properties = request.getProperties();
+    for (Map propertyMap : properties) {
+      //Mpack Download url is either given in the request body or is fetched using the registry id
+      if (!propertyMap.containsKey(MPACK_URL) && !propertyMap.containsKey(REGISTRY_ID))
+        return null;
+      //Fetch Mpack Download Url using the given registry id
+      else if (!propertyMap.containsKey(MPACK_URL)) {
+        mpackRequest.setRegistryId((String) propertyMap.get(REGISTRY_ID));
+        mpackRequest.setMpackName((String) propertyMap.get(MPACK_NAME));
+        mpackRequest.setMpackVersion((String) propertyMap.get(MPACK_VERSION));
+      }
+      //Directle download the mpack using the given url
+      else
+        mpackRequest.setMpackUrl((String) propertyMap.get(MPACK_URL));
+    }
+    return mpackRequest;
+
+  }
+
+  @Override
+  public Set<Resource> getResources(Request request, Predicate predicate)
+          throws SystemException, UnsupportedPropertyException,
+          NoSuchResourceException, NoSuchParentResourceException {
+
+    Set<Resource> results = new LinkedHashSet<>();
+
+    //Fetch all mpacks
+    if (predicate == null) {
+      List<MpackEntity> entities = mpackDAO.findAll();
+      if (null == entities) {
+        entities = Collections.emptyList();
+      }
+      for (MpackEntity entity : entities) {
+        Resource resource = new ResourceImpl(Resource.Type.Mpack);
+        resource.setProperty(MPACK_ID, entity.getMpackId());
+        resource.setProperty(MPACK_NAME, entity.getMpackName());
+        resource.setProperty(MPACK_VERSION, entity.getMpackVersion());
+        resource.setProperty(MPACK_URL, entity.getMpackUrl());
+        resource.setProperty(REGISTRY_ID, entity.getRegistryId());
+        results.add(resource);
+      }
+    } //Fetch a particular mpack based on id
+    else {
+      Map<String, Object> propertyMap = new HashMap<>(PredicateHelper.getProperties(predicate));
+      if (propertyMap.containsKey(MPACK_ID)) {
+        String mpackId = (String) propertyMap.get(MPACK_ID);
+        MpackEntity entity = mpackDAO.findById(Long.parseLong((mpackId)));
+        Resource resource = new ResourceImpl(Resource.Type.Mpack);
+        if (null != entity) {
+          resource.setProperty(MPACK_ID, entity.getMpackId());
+          resource.setProperty(MPACK_NAME, entity.getMpackName());
+          resource.setProperty(MPACK_VERSION, entity.getMpackVersion());
+          resource.setProperty(MPACK_URL, entity.getMpackUrl());
+          resource.setProperty(REGISTRY_ID, entity.getRegistryId());
+
+          ArrayList<Packlet> packletArrayList = getManagementController().getPacklets(entity.getMpackId());
+          resource.setProperty(PACKLETS, packletArrayList);
+          results.add(resource);
+        }
+      }
+      if (results.isEmpty()) {
+        throw new NoSuchResourceException(
+                "The requested resource doesn't exist: " + predicate);
+      }
+    }
+
+    return results;
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
index 58bad50..58c48c8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
@@ -90,6 +90,7 @@ public interface Resource {
     User,
     Group,
     Member,
+    Mpack,
     Stack,
     StackVersion,
     ExtensionLink,
@@ -211,6 +212,7 @@ public interface Resource {
     public static final Type User = InternalType.User.getType();
     public static final Type Group = InternalType.Group.getType();
     public static final Type Member = InternalType.Member.getType();
+    public static final Type Mpack = InternalType.Mpack.getType();
     public static final Type Stack = InternalType.Stack.getType();
     public static final Type StackVersion = InternalType.StackVersion.getType();
     public static final Type ExtensionLink = InternalType.ExtensionLink.getType();

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AmbariMetricSinkImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AmbariMetricSinkImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AmbariMetricSinkImpl.java
index a0765bf..9b6fbf9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AmbariMetricSinkImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/AmbariMetricSinkImpl.java
@@ -300,12 +300,10 @@ public class AmbariMetricSinkImpl extends AbstractTimelineMetricsSink implements
     return hostName;
   }
 
-  @Override
   protected boolean isHostInMemoryAggregationEnabled() {
     return false;
   }
 
-  @Override
   protected int getHostInMemoryAggregationPort() {
     return 0;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java b/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java
new file mode 100644
index 0000000..dd4a4b3
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManager.java
@@ -0,0 +1,194 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.mpack;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import org.apache.ambari.server.controller.MpackRequest;
+import org.apache.ambari.server.controller.MpackResponse;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.orm.dao.MpackDAO;
+import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.apache.ambari.server.state.Mpacks;
+import org.apache.ambari.server.state.Packlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+
+/**
+ * Manages all mpack related behavior including parsing of stacks and providing access to
+ * mpack information.
+ */
+public class MpackManager {
+  protected Map<Long, Mpacks> mpackMap = new HashMap<>();
+  private File mpackStaging;
+  private MpackDAO mpackDAO;
+
+  private final static Logger LOG = LoggerFactory.getLogger(MpackManager.class);
+
+  @AssistedInject
+  public MpackManager(@Assisted("mpackv2Staging") File mpackStagingLoc, MpackDAO mpackDAOObj) {
+    mpackStaging = mpackStagingLoc;
+    mpackDAO = mpackDAOObj;
+    //Todo : Madhu Load all mpack.json into mpackMap during ambari-server startup
+  }
+
+  /**
+   * Parses mpack.json to fetch mpack and associated packlet information and
+   * stores the mpack to the database and mpackMap
+   *
+   * @param mpackRequest
+   * @return MpackResponse
+   * @throws IOException
+   * @throws IllegalArgumentException
+   * @throws ResourceAlreadyExistsException
+   */
+  public MpackResponse registerMpack(MpackRequest mpackRequest) throws IOException, IllegalArgumentException, ResourceAlreadyExistsException {
+    //Todo : Madhu Expand the folders
+    //Todo : Madhu Update StacksAPI
+    Long mpackId;
+    Mpacks mpacks = new Mpacks();
+    String mpackName = "";
+    String mpackVersion = "";
+    boolean isValidMetadata = true;
+    if (mpackRequest.getRegistryId() != null) {
+      mpackName = mpackRequest.getMpackName();
+      mpackVersion = mpackRequest.getMpackVersion();
+      mpacks = parseMpacksJson(mpackName, mpackVersion);
+      mpacks.setRegistryId(mpackRequest.getRegistryId());
+      //Validate the Post request
+      isValidMetadata = validateMpackInfo(mpackName, mpackVersion, mpacks.getName(), mpacks.getVersion());
+    } else {
+      //Download the mpack and return the path.
+      String[] urlSplit = mpackRequest.getMpackUrl().split("/");
+      String mpackNameVersion = urlSplit[urlSplit.length - 1];
+      final String patternStrName = "([a-zA-Z]+)-([a-zA-Z]+)-([a-zA-Z]+)";
+      final String patternStrVersion = "([0-9]).([0-9]).([0-9]).([0-9])-([0-9]+)";
+      Pattern REGEX = Pattern.compile(patternStrName);
+      Matcher patternMatchObj = REGEX.matcher(mpackNameVersion);
+      if (patternMatchObj.find()) {
+        mpackName = patternMatchObj.group();
+      }
+      REGEX = Pattern.compile(patternStrVersion);
+      patternMatchObj = REGEX.matcher(mpackNameVersion);
+      if (patternMatchObj.find()) {
+        mpackVersion = patternMatchObj.group();
+      }
+      mpacks = parseMpacksJson(mpackName, mpackVersion);
+      mpacks.setMpacksUrl(mpackRequest.getMpackUrl());
+    }
+    if (isValidMetadata) {
+      mpackId = populateDB(mpacks);
+      if (mpackId != null) {
+        mpackMap.put(mpackId, mpacks);
+        mpacks.setMpackId(mpackId);
+        return new MpackResponse(mpacks);
+      } else {
+        String message = "Mpack :" + mpackRequest.getMpackName() + " version: " + mpackRequest.getMpackVersion() + " already exists in server";
+        throw new ResourceAlreadyExistsException(message);
+      }
+    } else {
+      String message = "Incorrect information : Mismatch in - (" + mpackName + "," + mpacks.getName() + ") or (" + mpackVersion + "," + mpacks.getVersion() + ")";
+      throw new IllegalArgumentException(message); //Mismatch in information
+    }
+  }
+
+  /**
+   * Compares if the user's mpack information matches the downloaded mpack information.
+   *
+   * @param expectedMpackName
+   * @param expectedMpackVersion
+   * @param actualMpackName
+   * @param actualMpackVersion
+   * @return boolean
+   */
+  protected boolean validateMpackInfo(String expectedMpackName, String expectedMpackVersion, String actualMpackName, String actualMpackVersion) {
+    if (expectedMpackName.equalsIgnoreCase(actualMpackName) && expectedMpackVersion.equalsIgnoreCase(actualMpackVersion))
+      return true;
+    else
+      LOG.info("Incorrect information : Mismatch in - (" + expectedMpackName + "," + actualMpackName + ") or (" + expectedMpackVersion + "," + actualMpackVersion + ")");
+    return false;
+  }
+
+  /**
+   * Parses the mpack.json file for mpack information and stores in memory for powering /mpacks/{mpack_id}
+   *
+   * @return Mpacks
+   * @throws IOException
+   * @param mpackName
+   * @param mpackVersion
+   */
+  protected Mpacks parseMpacksJson(String mpackName, String mpackVersion) throws IOException {
+    Type type = new TypeToken<Mpacks>() {
+    }.getType();
+    Gson gson = new Gson();
+    String mpackJson = mpackName + "-" + mpackVersion + ".json";
+    JsonReader jsonReader = new JsonReader(new FileReader(mpackStaging + "/" + mpackName +"/" + mpackVersion + "/" + mpackJson));
+    Mpacks mpacks = gson.fromJson(jsonReader, type);
+    return mpacks;
+  }
+
+  /**
+   * Make an entry in the mpacks database for the newly registered mpack.
+   *
+   * @param mpacks
+   * @return
+   * @throws IOException
+   */
+  protected Long populateDB(Mpacks mpacks) throws IOException {
+    String mpackName = mpacks.getName();
+    String mpackVersion = mpacks.getVersion();
+    List resultSet = mpackDAO.findByNameVersion(mpackName, mpackVersion);
+    if (resultSet.size() == 0) {
+      LOG.info("Adding mpack {}-{} to the database", mpackName, mpackVersion);
+      MpackEntity mpackEntity = new MpackEntity();
+      mpackEntity.setMpackName(mpackName);
+      mpackEntity.setMpackVersion(mpackVersion);
+      mpackEntity.setMpackUrl(mpacks.getMpacksUrl());
+
+      Long mpackId = mpackDAO.create(mpackEntity);
+      return mpackId;
+    }
+    //mpack already exists
+    return null;
+  }
+
+  /**
+   * Fetches the packlet info stored in the memory for mpacks/{mpack_id} call.
+   */
+  public ArrayList<Packlet> getPacklets(Long mpackId) {
+    Mpacks mpack = mpackMap.get(mpackId);
+    if(mpack.getPacklets()!=null)
+      return mpack.getPacklets();
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManagerFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManagerFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManagerFactory.java
new file mode 100644
index 0000000..67820c8
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/mpack/MpackManagerFactory.java
@@ -0,0 +1,37 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.mpack;
+
+import java.io.File;
+
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+
+/**
+ * The {@link MpackManagerFactory} is used along with {@link AssistedInject} to
+ * build instances of {@link MpackManager}.
+ */
+public interface MpackManagerFactory {
+
+  /**
+   * @param mpackStaging
+   *        the folder location where mpack is downloaded. (not {@code null}).
+   * @return a mpack manager instance.
+   */
+  MpackManager create(@Assisted("mpackv2Staging") File mpackStaging);
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/MpackDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/MpackDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/MpackDAO.java
new file mode 100644
index 0000000..e41edd2
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/MpackDAO.java
@@ -0,0 +1,99 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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 com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
+import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import java.util.List;
+
+
+@Singleton
+public class MpackDAO {
+  protected final static Logger LOG = LoggerFactory.getLogger(MpackDAO.class);
+
+  /**
+   * JPA entity manager
+   */
+  @Inject
+  private Provider<EntityManager> m_entityManagerProvider;
+
+  /**
+   * DAO utilities for dealing mostly with {@link TypedQuery} results.
+   */
+  @Inject
+  private DaoUtils m_daoUtils;
+
+  /**
+   * Persists a new mpack
+   */
+  @Transactional
+  public Long create(MpackEntity mpackEntity) {
+    m_entityManagerProvider.get().persist(mpackEntity);
+    return mpackEntity.getMpackId();
+  }
+
+  /**
+   * Gets an mpack with the specified ID.
+   *
+   * @param mpackId
+   *          the ID of the alert to retrieve.
+   * @return the mpack or {@code null} if none exists.
+   */
+  @RequiresSession
+  public MpackEntity findById(long mpackId) {
+    return m_entityManagerProvider.get().find(MpackEntity.class, mpackId);
+  }
+
+  /**
+   * Gets mpacks with specified mpack name and mpack version.
+   *
+   * @param mpackName
+   * @param mpackVersion
+   * @return the mpack or {@code null} if none exists.
+   */
+  @RequiresSession
+  public List<MpackEntity> findByNameVersion(String mpackName, String mpackVersion) {
+    TypedQuery<MpackEntity> query = m_entityManagerProvider.get().createNamedQuery("MpackEntity.findByNameVersion", MpackEntity.class);
+    query.setParameter("mpackName", mpackName);
+    query.setParameter("mpackVersion", mpackVersion);
+    return m_daoUtils.selectList(query);
+  }
+
+  /**
+   * Gets all mpacks stored in the database across all clusters.
+   *
+   * @return all mpacks or an empty list if none exist (never {@code null}).
+   */
+  @RequiresSession
+  public List<MpackEntity> findAll() {
+    TypedQuery<MpackEntity> query = m_entityManagerProvider.get().createNamedQuery(
+            "MpackEntity.findAll", MpackEntity.class);
+    return m_daoUtils.selectList(query);
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackEntity.java
new file mode 100644
index 0000000..addba17
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/MpackEntity.java
@@ -0,0 +1,158 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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 org.apache.commons.lang.builder.EqualsBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.NamedQuery;
+import javax.persistence.NamedQueries;
+import javax.persistence.Table;
+import javax.persistence.Entity;
+import javax.persistence.TableGenerator;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Column;
+import java.util.Objects;
+
+/**
+ * The {@link MpackEntity} class represents the mpack objects in the cluster.
+ */
+
+@Table(name = "mpacks")
+@Entity
+@TableGenerator(name = "mpack_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "mpack_id_seq", initialValue = 1)
+@NamedQueries({
+        @NamedQuery(name = "MpackEntity.findById", query = "SELECT mpack FROM MpackEntity mpack where mpack.mpackId = :mpackId"),
+        @NamedQuery(name = "MpackEntity.findAll", query = "SELECT mpack FROM MpackEntity mpack"),
+        @NamedQuery(name = "MpackEntity.findByNameVersion", query = "SELECT mpack FROM MpackEntity mpack where mpack.mpackName = :mpackName and mpack.mpackVersion = :mpackVersion")})
+
+public class MpackEntity {
+  protected final static Logger LOG = LoggerFactory.getLogger(MpackEntity.class);
+  @Id
+  @GeneratedValue(strategy = GenerationType.TABLE, generator = "mpack_id_generator")
+  @Column(name = "id", nullable = false, updatable = false)
+  private Long mpackId;
+
+  @Column(name = "registry_id", nullable = true, insertable = true, updatable = false, length = 10)
+  private Long registryId;
+
+  @Column(name = "mpack_name", nullable = false, updatable = true)
+  private String mpackName;
+
+  @Column(name = "mpack_version", nullable = false)
+  private String mpackVersion;
+
+  @Column(name = "mpack_uri", nullable = false)
+  private String mpackUrl;
+
+  public Long getMpackId() {
+    return mpackId;
+  }
+
+  public Long getRegistryId() {
+    return registryId;
+  }
+
+  public String getMpackName() {
+    return mpackName;
+  }
+
+  public String getMpackVersion() {
+    return mpackVersion;
+  }
+
+  public String getMpackUrl() {
+    return mpackUrl;
+  }
+
+  public void setMpackId(Long mpackId) {
+    this.mpackId = mpackId;
+  }
+
+  public void setRegistryId(Long registryId) {
+    this.registryId = registryId;
+  }
+
+  public void setMpackName(String mpackName) {
+    this.mpackName = mpackName;
+  }
+
+  public void setMpackVersion(String mpackVersion) {
+    this.mpackVersion = mpackVersion;
+  }
+
+  public void setMpackUrl(String mpackUrl) {
+    this.mpackUrl = mpackUrl;
+  }
+
+  public MpackEntity() {
+
+  }
+
+  @Override
+  public boolean equals(Object object) {
+    if (this == object) {
+      return true;
+    }
+
+    if (object == null || getClass() != object.getClass()) {
+      return false;
+    }
+
+    MpackEntity that = (MpackEntity) object;
+    EqualsBuilder equalsBuilder = new EqualsBuilder();
+
+    equalsBuilder.append(mpackId, that.mpackId);
+    return equalsBuilder.isEquals();
+  }
+
+  /**
+   * Generates a hash for the mpack based on the following criteria:
+   * <ul>
+   * <li>{@link #mpackId}
+   * </ul>
+   * <p/>
+   * <p/>
+   * {@inheritDoc}
+   */
+  @Override
+  public int hashCode() {
+    return Objects.hash(mpackId);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String toString() {
+    StringBuilder buffer = new StringBuilder("MpackEntity{");
+    buffer.append("mpackId=").append(mpackId);
+    if (null != registryId) {
+      buffer.append(", registryId=").append(registryId);
+    }
+    buffer.append(", mpackName=").append(mpackName);
+    buffer.append(", mpackVersion=").append(mpackVersion);
+    buffer.append(", mpackUrl=").append(mpackUrl);
+    buffer.append("}");
+    return buffer.toString();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/state/Mpacks.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpacks.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpacks.java
new file mode 100644
index 0000000..7abac7e
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpacks.java
@@ -0,0 +1,114 @@
+/**
+ * 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.state;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Represents the state of an mpack.
+ */
+public class Mpacks {
+
+    private Long mpackId;
+
+    private String registryId;
+
+    @SerializedName("name")
+    private String name;
+
+    @SerializedName("version")
+    private String version;
+
+    @SerializedName("description")
+    private String description;
+
+    @SerializedName("prerequisites")
+    private HashMap<String,String> prerequisites;
+
+    @SerializedName("packlets")
+    private ArrayList<Packlet> packlets;
+
+    private String mpacksUrl;
+
+    public Long getMpackId() {
+        return mpackId;
+    }
+
+    public void setMpackId(Long mpackId) {
+        this.mpackId = mpackId;
+    }
+
+    public String getRegistryId() {
+        return registryId;
+    }
+
+    public void setRegistryId(String registryId) {
+        this.registryId = registryId;
+    }
+
+    public String getMpacksUrl() {
+        return mpacksUrl;
+    }
+
+    public void setMpacksUrl(String mpacksUrl) {
+        this.mpacksUrl = mpacksUrl;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public HashMap<String, String> getPrerequisites() {
+        return prerequisites;
+    }
+
+    public void setPrerequisites(HashMap<String, String> prerequisites) {
+        this.prerequisites = prerequisites;
+    }
+
+    public ArrayList<Packlet> getPacklets() {
+        return packlets;
+    }
+
+    public void setPacklets(ArrayList<Packlet> packlets) {
+        this.packlets = packlets;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/java/org/apache/ambari/server/state/Packlet.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Packlet.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Packlet.java
new file mode 100644
index 0000000..5c91232
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Packlet.java
@@ -0,0 +1,65 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.state;
+
+import com.google.gson.annotations.SerializedName;
+
+
+public class Packlet {
+  @SerializedName("type")
+  private String type;
+  @SerializedName("name")
+  private String name;
+  @SerializedName("version")
+  private String version;
+  @SerializedName("source_dir")
+  private String sourceDir;
+
+  public String getType() {
+    return type;
+  }
+
+  public void setType(String type) {
+    this.type = type;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public String getVersion() {
+    return version;
+  }
+
+  public void setVersion(String version) {
+    this.version = version;
+  }
+
+  public String getSourceDir() {
+    return sourceDir;
+  }
+
+  public void setSourceDir(String sourceDir) {
+    this.sourceDir = sourceDir;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
index 15670f3..d01a670 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -898,6 +898,23 @@ CREATE TABLE ambari_operation_history(
   CONSTRAINT PK_ambari_operation_history PRIMARY KEY (id)
 );
 
+CREATE TABLE registries(
+ id BIGINT NOT NULL,
+ registy_name VARCHAR(255) NOT NULL,
+ registry_type VARCHAR(255) NOT NULL,
+ registry_uri VARCHAR(255) NOT NULL,
+ CONSTRAINT PK_registries PRIMARY KEY (id));
+
+CREATE TABLE mpacks(
+ id BIGINT NOT NULL,
+ mpack_name VARCHAR(255) NOT NULL,
+ mpack_version VARCHAR(255) NOT NULL,
+ mpack_uri VARCHAR(255),
+ registry_id BIGINT,
+ CONSTRAINT PK_mpacks PRIMARY KEY (id),
+ CONSTRAINT FK_registries FOREIGN KEY (registry_id) REFERENCES registries(id),
+ CONSTRAINT uni_mpack_name_version UNIQUE(mpack_name, mpack_version));
+
 -- tasks indices --
 CREATE INDEX idx_stage_request_id ON stage (request_id);
 CREATE INDEX idx_hrc_request_id ON host_role_command (request_id);
@@ -1125,6 +1142,8 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value)
   union all
   select 'stack_id_seq', 0 FROM SYSIBM.SYSDUMMY1
   union all
+  select 'mpack_id_seq', 0 FROM SYSIBM.SYSDUMMY1
+  union all
   select 'extension_id_seq', 0 FROM SYSIBM.SYSDUMMY1
   union all
   select 'link_id_seq', 0 FROM SYSIBM.SYSDUMMY1

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/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 7e41399..415350a 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -1062,6 +1062,23 @@ CREATE TABLE alert_notice (
   FOREIGN KEY (history_id) REFERENCES alert_history(alert_id)
 );
 
+CREATE TABLE registries(
+ id BIGINT NOT NULL,
+ registy_name VARCHAR(255) NOT NULL,
+ registry_type VARCHAR(255) NOT NULL,
+ registry_uri VARCHAR(255) NOT NULL,
+ CONSTRAINT PK_registries PRIMARY KEY (id));
+
+CREATE TABLE mpacks(
+ id BIGINT NOT NULL,
+ mpack_name VARCHAR(255) NOT NULL,
+ mpack_version VARCHAR(255) NOT NULL,
+ mpack_uri VARCHAR(255),
+ registry_id BIGINT,
+ CONSTRAINT PK_mpacks PRIMARY KEY (id),
+ CONSTRAINT uni_mpack_name_version UNIQUE(mpack_name, mpack_version),
+ CONSTRAINT FK_registries FOREIGN KEY (registry_id) REFERENCES registries(id));
+
 CREATE INDEX idx_alert_history_def_id on alert_history(alert_definition_id);
 CREATE INDEX idx_alert_history_service on alert_history(service_name);
 CREATE INDEX idx_alert_history_host on alert_history(host_name);
@@ -1105,6 +1122,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) VALUES
   ('upgrade_group_id_seq', 0),
   ('upgrade_item_id_seq', 0),
   ('stack_id_seq', 0),
+  ('mpack_id_seq', 0),
   ('extension_id_seq', 0),
   ('link_id_seq', 0),
   ('widget_id_seq', 0),

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/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 4d0274f..bb2a559 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -1041,6 +1041,23 @@ CREATE TABLE alert_notice (
   FOREIGN KEY (history_id) REFERENCES alert_history(alert_id)
 );
 
+CREATE TABLE registries(
+ id BIGINT NOT NULL,
+ registy_name VARCHAR(255) NOT NULL,
+ registry_type VARCHAR(255) NOT NULL,
+ registry_uri VARCHAR(255) NOT NULL,
+ CONSTRAINT PK_registries PRIMARY KEY (id));
+
+CREATE TABLE mpacks(
+ id BIGINT NOT NULL,
+ mpack_name VARCHAR(255) NOT NULL,
+ mpack_version VARCHAR(255) NOT NULL,
+ mpack_uri VARCHAR(255),
+ registry_id BIGINT,
+ CONSTRAINT PK_mpacks PRIMARY KEY (id),
+ CONSTRAINT uni_mpack_name_version UNIQUE(mpack_name, mpack_version),
+ CONSTRAINT FK_registries FOREIGN KEY (registry_id) REFERENCES registries(id));
+
 CREATE INDEX idx_alert_history_def_id on alert_history(alert_definition_id);
 CREATE INDEX idx_alert_history_service on alert_history(service_name);
 CREATE INDEX idx_alert_history_host on alert_history(host_name);
@@ -1084,6 +1101,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_id_
 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 ambari_sequences(sequence_name, sequence_value) values ('mpack_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('extension_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('link_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('widget_id_seq', 0);

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/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 cc933fa..de9eb68 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -1087,6 +1087,7 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value) VALUES
   ('widget_layout_id_seq', 0),
   ('upgrade_item_id_seq', 0),
   ('stack_id_seq', 0),
+  ('mpack_id_seq',0),
   ('extension_id_seq', 0),
   ('link_id_seq', 0),
   ('topology_host_info_id_seq', 0),
@@ -1556,6 +1557,23 @@ CREATE TABLE qrtz_locks
   PRIMARY KEY (SCHED_NAME,LOCK_NAME)
 );
 
+CREATE TABLE registries(
+ id BIGINT NOT NULL,
+ registy_name VARCHAR(255) NOT NULL,
+ registry_type VARCHAR(255) NOT NULL,
+ registry_uri VARCHAR(255) NOT NULL,
+ CONSTRAINT PK_registries PRIMARY KEY (id));
+
+CREATE TABLE mpacks(
+ id BIGINT NOT NULL,
+ mpack_name VARCHAR(255) NOT NULL,
+ mpack_version VARCHAR(255) NOT NULL,
+ mpack_uri VARCHAR(255),
+ registry_id BIGINT,
+ CONSTRAINT PK_mpacks PRIMARY KEY (id),
+ CONSTRAINT FK_registries FOREIGN KEY (registry_id) REFERENCES registries(id)
+ CONSTRAINT uni_mpack_name_version UNIQUE(mpack_name, mpack_version));
+
 create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);
 create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
index 5fc14d4..fb9b878 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -1041,6 +1041,23 @@ CREATE TABLE alert_notice (
   FOREIGN KEY (history_id) REFERENCES alert_history(alert_id)
 );
 
+CREATE TABLE registries(
+ id BIGINT NOT NULL,
+ registy_name VARCHAR(255) NOT NULL,
+ registry_type VARCHAR(255) NOT NULL,
+ registry_uri VARCHAR(255) NOT NULL,
+ CONSTRAINT PK_registries PRIMARY KEY (id));
+
+CREATE TABLE mpacks(
+ id BIGINT NOT NULL,
+ mpack_name VARCHAR(255) NOT NULL,
+ mpack_version VARCHAR(255) NOT NULL,
+ mpack_uri VARCHAR(255),
+ registry_id BIGINT,
+ CONSTRAINT PK_mpacks PRIMARY KEY (id),
+ CONSTRAINT uni_mpack_name_version UNIQUE(mpack_name, mpack_version),
+ CONSTRAINT FK_registries FOREIGN KEY (registry_id) REFERENCES registries(id));
+
 CREATE INDEX idx_alert_history_def_id on alert_history(alert_definition_id);
 CREATE INDEX idx_alert_history_service on alert_history(service_name);
 CREATE INDEX idx_alert_history_host on alert_history(host_name);
@@ -1083,6 +1100,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('upgrade_id_
 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 ambari_sequences(sequence_name, sequence_value) values ('mpack_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('extension_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('link_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('widget_id_seq', 0);

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/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 12e66f9..c42892f 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -1065,6 +1065,23 @@ CREATE TABLE alert_notice (
   FOREIGN KEY (history_id) REFERENCES alert_history(alert_id)
 );
 
+CREATE TABLE registries(
+ id BIGINT NOT NULL,
+ registy_name VARCHAR(255) NOT NULL,
+ registry_type VARCHAR(255) NOT NULL,
+ registry_uri VARCHAR(255) NOT NULL,
+ CONSTRAINT PK_registries PRIMARY KEY (id));
+
+CREATE TABLE mpacks(
+ id BIGINT NOT NULL,
+ mpack_name VARCHAR(255) NOT NULL,
+ mpack_version VARCHAR(255) NOT NULL,
+ mpack_uri VARCHAR(255),
+ registry_id BIGINT,
+ CONSTRAINT PK_mpacks PRIMARY KEY (id),
+ CONSTRAINT uni_mpack_name_version UNIQUE(mpack_name, mpack_version),
+ CONSTRAINT FK_registries FOREIGN KEY (registry_id) REFERENCES registries(id));
+
 CREATE INDEX idx_alert_history_def_id on alert_history(alert_definition_id);
 CREATE INDEX idx_alert_history_service on alert_history(service_name);
 CREATE INDEX idx_alert_history_host on alert_history(host_name);
@@ -1112,6 +1129,7 @@ BEGIN TRANSACTION
     ('widget_layout_id_seq', 0),
     ('upgrade_item_id_seq', 0),
     ('stack_id_seq', 0),
+    ('mpack_id_seq', 0),
     ('extension_id_seq', 0),
     ('link_id_seq', 0),
     ('topology_host_info_id_seq', 0),

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/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 0375650..3755321 100644
--- a/ambari-server/src/main/resources/META-INF/persistence.xml
+++ b/ambari-server/src/main/resources/META-INF/persistence.xml
@@ -98,6 +98,7 @@
     <class>org.apache.ambari.server.orm.entities.KerberosDescriptorEntity</class>
     <class>org.apache.ambari.server.orm.entities.RemoteAmbariClusterEntity</class>
     <class>org.apache.ambari.server.orm.entities.RemoteAmbariClusterServiceEntity</class>
+    <class>org.apache.ambari.server.orm.entities.MpackEntity</class>
 
     <properties>
       <property name="eclipselink.cache.size.default" value="10000" />

http://git-wip-us.apache.org/repos/asf/ambari/blob/e30f8384/ambari-server/src/test/java/org/apache/ambari/server/metric/system/impl/TestAmbariMetricsSinkImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/metric/system/impl/TestAmbariMetricsSinkImpl.java b/ambari-server/src/test/java/org/apache/ambari/server/metric/system/impl/TestAmbariMetricsSinkImpl.java
index 3ee8ebc..9ac9e13 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/metric/system/impl/TestAmbariMetricsSinkImpl.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/metric/system/impl/TestAmbariMetricsSinkImpl.java
@@ -73,12 +73,10 @@ public class TestAmbariMetricsSinkImpl extends AbstractTimelineMetricsSink imple
     return "localhost";
   }
 
-  @Override
   protected boolean isHostInMemoryAggregationEnabled() {
     return true;
   }
 
-  @Override
   protected int getHostInMemoryAggregationPort() {
     return 61888;
   }