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 2018/09/28 21:20:31 UTC

[ambari] branch AMBARI-24711 created (now a6536f3)

This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a change to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git.


      at a6536f3  Modifications to choose only necessary changes from Ambari3.0 to Ambari2.8 (mradhakrishnan)

This branch includes the following new commits:

     new d3e45e9  AMBARI-21150: Mpack API and DB Schema changes (mradhakrishnan)
     new cf2b52a  AMBARI-21231: Download and extract mpacks. Add unit tests (mradhakrishnan)
     new 9106dcc  AMBARI-21231: Mpack to Stack Linkage and Parsing mpacks at bootstrap  (mradhakrishnan)
     new f9d7051  AMBARI-21077: Fix build issues after reverting patch for AMBARI-21077 and merging latest trunk (jluniya)
     new ab5721c  AMBARI-21523: DELETE Api for Mpacks  (mradhakrishnan)
     new 32023fb  AMBARI-21796 : Clear versionDefinition map during new mpack registration and mpack deletion (mradhakrishnan)
     new 4ae9222  AMBARI-21849 : Clean up repo_version table during mpack delete, add create validation for mpacks (mradhakrishnan)
     new 4cfd7a9  AMBARI-21849 : Addendum to fix checkstyle issues and null check (mradhakrishnan)
     new a82e169  AMBARI-22082: Create missing parent directory when expanding mpack tarball (jluniya)
     new 3959182  AMBARI-22283 : Add stack name and version to mpack API (mradhakrishnan)
     new aaa56f2  AMBARI-22283 : Add stack name and version to mpack API (mradhakrishnan)
     new 562e52b  AMBARI-22283 : Add stack name and version to mpack API (mradhakrishnan)
     new 10bf7ba  [AMBARI-22904] Revised mpack APIs (#252)
     new 29aa64d  AMBARI-22971: Remove current_mpack_id to mpack_id in stacks table (jluniya)
     new 27f19ad  [AMBARI-22992] Update error handling during mpack installation (#363)
     new a77b2f9  AMBARI-22979: Update software registry API to support new mpack schema (jluniya) (#433)
     new ffe161f  [AMBARI-23223] Stack Mpack link broken in stacks api
     new 9360b63  [AMBARI-23254] Mpack should have both displayName and description
     new fab74c2  [AMBARI-23223] Review comments
     new a6536f3  Modifications to choose only necessary changes from Ambari3.0 to Ambari2.8 (mradhakrishnan)

The 20 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[ambari] 20/20: Modifications to choose only necessary changes from Ambari3.0 to Ambari2.8 (mradhakrishnan)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit a6536f3c6fb0fa5415b42b63ff994fd2bc78c621
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Thu Sep 27 15:51:56 2018 -0700

    Modifications to choose only necessary changes from Ambari3.0 to Ambari2.8 (mradhakrishnan)
---
 ambari-server/src/main/assemblies/server.xml       |   5 -
 .../api/services/AbstractVersionService.java       | 362 ---------------------
 .../ambari/server/api/services/AmbariMetaInfo.java |   4 +-
 .../ambari/server/api/services/MpacksService.java  |   7 +-
 .../controller/AmbariManagementController.java     |   1 -
 .../controller/AmbariManagementControllerImpl.java |  43 +--
 .../ambari/server/controller/MpackResponse.java    |   3 +-
 .../controller/internal/MpackResourceProvider.java |  32 +-
 .../apache/ambari/server/mpack/MpackManager.java   |  14 +-
 .../org/apache/ambari/server/orm/dao/MpackDAO.java |  18 +-
 .../ambari/server/orm/entities/MpackEntity.java    |  22 +-
 .../apache/ambari/server/stack/StackManager.java   |   3 +-
 .../org/apache/ambari/server/state/Module.java     |  25 ++
 .../ambari/server/state/ModuleComponent.java       |  11 +
 .../java/org/apache/ambari/server/state/Mpack.java |   8 +-
 .../api/resources/MpackResourceDefinitionTest.java |   1 +
 .../server/api/services/AmbariMetaInfoTest.java    |  51 ++-
 .../server/api/services/MpackServiceTest.java      |  94 ------
 .../AmbariManagementControllerImplTest.java        |  28 +-
 .../ambari/server/controller/MpackRequestTest.java |   2 +-
 .../server/controller/MpackResponseTest.java       |   3 -
 .../internal/AbstractResourceProviderTest.java     |   2 +-
 .../internal/ClusterControllerImplTest.java        |   2 +-
 .../internal/MpackResourceProviderTest.java        |  35 +-
 .../apache/ambari/server/orm/dao/MpackDAOTest.java |  20 +-
 .../server/orm/entities/MpackEntityTest.java       |   6 +-
 .../org/apache/ambari/server/state/MpackTest.java  |   4 +-
 .../org/apache/ambari/server/state/MpacksTest.java |  95 ------
 .../ambari/msi/AbstractResourceProviderTest.java   |   7 +-
 29 files changed, 151 insertions(+), 757 deletions(-)

diff --git a/ambari-server/src/main/assemblies/server.xml b/ambari-server/src/main/assemblies/server.xml
index 464972f..21524ee 100644
--- a/ambari-server/src/main/assemblies/server.xml
+++ b/ambari-server/src/main/assemblies/server.xml
@@ -316,11 +316,6 @@
     </file>
     <file>
       <fileMode>755</fileMode>
-      <source>target/classes/cluster-settings.xml</source>
-      <outputDirectory>/var/lib/ambari-server/resources</outputDirectory>
-    </file>
-    <file>
-      <fileMode>755</fileMode>
       <source>target/classes/Ambari-DDL-Postgres-CREATE.sql</source>
       <outputDirectory>/var/lib/ambari-server/resources</outputDirectory>
     </file>
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
deleted file mode 100644
index 2d81602..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AbstractVersionService.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/**
- * 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.api.services;
-
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-
-import org.apache.ambari.server.api.rest.BootStrapResource;
-import org.apache.ambari.server.api.rest.HealthCheck;
-import org.apache.ambari.server.api.rest.KdcServerReachabilityCheck;
-import org.apache.ambari.server.api.util.ApiVersion;
-
-/**
- * Abstract class for single entry point for an API version
- */
-public abstract class AbstractVersionService {
-
-  /**
-   * Handles /actions request.
-   *
-   * @return action service
-   */
-  @Path("/actions")
-  public ActionService getActionService(@PathParam("apiVersion") String apiVersion) {
-    return new ActionService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /alert_targets request.
-   *
-   * @return alert targets service
-   */
-  @Path("/alert_targets")
-  public AlertTargetService getAlertTargetService(@PathParam("apiVersion") String apiVersion) {
-    return new AlertTargetService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /privileges request.
-   *
-   * @return privileges service
-   */
-  @Path("/privileges")
-  public AmbariPrivilegeService getAmbariPrivilegeService(@PathParam("apiVersion") String apiVersion) {
-    return new AmbariPrivilegeService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /blueprints request.
-   *
-   * @return blueprints service
-   */
-  @Path("/blueprints")
-  public BlueprintService getBlueprintService(@PathParam("apiVersion") String apiVersion) {
-    return new BlueprintService(ApiVersion.valueOf(apiVersion));
-  }
-
-
-  /**
-   * Handles /links request.
-   *
-   * @return extension links service
-   */
-  @Path("/links")
-  public ExtensionLinksService getExtensionLinksService(@PathParam("apiVersion") String apiVersion) {
-    return new ExtensionLinksService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /extensions request.
-   *
-   * @return extensions service
-   */
-  @Path("/extensions")
-  public ExtensionsService getExtensionsService(@PathParam("apiVersion") String apiVersion) {
-    return new ExtensionsService(ApiVersion.valueOf(apiVersion));
-  }
-
-
-  /**
-   * Handles /clusters request.
-   *
-   * @return cluster service
-   */
-  @Path("/clusters")
-  public ClusterService getClusterService(@PathParam("apiVersion") String apiVersion) {
-    return new ClusterService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /feeds request.
-   * TODO: Cleanup?
-   *
-   * @return feed service
-   */
-  @Path("/feeds")
-  public FeedService getFeedService(@PathParam("apiVersion") String apiVersion) {
-    return new FeedService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /groups request.
-   *
-   * @return group service
-   */
-  @Path("/groups")
-  public GroupService getGroupService(@PathParam("apiVersion") String apiVersion) {
-    return new GroupService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /hosts request.
-   *
-   * @return host service
-   */
-  @Path("/hosts")
-  public HostService getHostService(@PathParam("apiVersion") String apiVersion) {
-    return new HostService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /instances request.
-   * TODO: Cleanup?
-   *
-   * @return instance service
-   */
-  @Path("/instances")
-  public InstanceService getInstanceService(@PathParam("apiVersion") String apiVersion) {
-    return new InstanceService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /kerberos_descriptors request.
-   *
-   * @return kerberos descriptor service
-   */
-  @Path("/kerberos_descriptors")
-  public KerberosDescriptorService getKerberosDescriptorService(@PathParam("apiVersion") String apiVersion) {
-    return new KerberosDescriptorService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /keys request.
-   *
-   * @return key service
-   */
-  @Path("/keys")
-  public KeyService getKeyService(@PathParam("apiVersion") String apiVersion) {
-    return new KeyService();
-  }
-
-  /**
-   * Handles /ldap_sync_events request.
-   *
-   * @return Ldap sync event service
-   */
-  @Path("/ldap_sync_events")
-  public LdapSyncEventService getLdapSyncEventService(@PathParam("apiVersion") String apiVersion) {
-    return new LdapSyncEventService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /logout request.
-   *
-   * @return logout service
-   */
-  @Path("/logout")
-  public LogoutService getLogoutService(@PathParam("apiVersion") String apiVersion) {
-    return new LogoutService();
-  }
-
-  /**
-   * Handles /permissions request.
-   *
-   * @return permission service
-   */
-  @Path("/permissions")
-  public PermissionService getPermissionService(@PathParam("apiVersion") String apiVersion) {
-    return new PermissionService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /persist request.
-   *
-   * @return persist service
-   */
-  @Path("/persist")
-  public PersistKeyValueService getPersistKeyValueService(@PathParam("apiVersion") String apiVersion) {
-    return new PersistKeyValueService();
-  }
-
-  /**
-   * Handles /remoteclusters request
-   *
-   * @return remote clusters service
-   */
-  @Path("/remoteclusters")
-  public RemoteClustersService getRemoteClustersService(@PathParam("apiVersion") String apiVersion) {
-    return new RemoteClustersService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /requests request.
-   *
-   * @return request service
-   */
-  @Path("/requests")
-  public RequestService getRequestService(@PathParam("apiVersion") String apiVersion) {
-    return new RequestService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /settings request.
-   *
-   * @return request service
-   */
-  @Path("/settings")
-  public SettingService getSettingService(@PathParam("apiVersion") String apiVersion) {
-    return new SettingService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /authorizations request.
-   *
-   * @return role authorization service
-   */
-  @Path("/authorizations")
-  public RoleAuthorizationService getRoleAuthorizationService(@PathParam("apiVersion") String apiVersion) {
-    return new RoleAuthorizationService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /services request.
-   *
-   * @return root service service
-   */
-  @Path("/services")
-  public RootServiceService getRootServiceService(@PathParam("apiVersion") String apiVersion) {
-    return new RootServiceService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /targets request.
-   * TODO: Cleanup?
-   *
-   * @return target cluster service
-   */
-  @Path("/targets")
-  public TargetClusterService getTargetClusterService(@PathParam("apiVersion") String apiVersion) {
-    return new TargetClusterService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /users request.
-   *
-   * @return user service
-   */
-  @Path("/users")
-  public UserService getUserService(@PathParam("apiVersion") String apiVersion) {
-    return new UserService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /version_definitions request.
-   *
-   * @return version definition service
-   */
-  @Path("/version_definitions")
-  public VersionDefinitionService getVersionDefinitionService(@PathParam("apiVersion") String apiVersion) {
-    return new VersionDefinitionService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /views request.
-   *
-   * @return view service
-   */
-  @Path("/views")
-  public ViewService getViewService(@PathParam("apiVersion") String apiVersion) {
-    return new ViewService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /view/urls request.
-   *
-   * @return view urls service
-   */
-  @Path("/view/urls")
-  public ViewUrlsService getViewUrlsService(@PathParam("apiVersion") String apiVersion) {
-    return new ViewUrlsService(ApiVersion.valueOf(apiVersion));
-  }
-
-  /**
-   * Handles /stacks request.
-   *
-   * @return stacks service
-   */
-  @Path("/stacks")
-  public StacksService getStacksService(@PathParam("apiVersion") String apiVersion) {
-    return new StacksService(ApiVersion.valueOf(apiVersion));
-  }
-
-
-  /**
-   * Handles /bootstrap request.
-   *
-   * @return bootstrap service
-   */
-  @Path("/bootstrap")
-  public BootStrapResource getBootStrapResource(@PathParam("apiVersion") String apiVersion) {
-    return new BootStrapResource();
-  }
-
-
-  /**
-   * Handles /check request.
-   *
-   * @return health check service
-   */
-  @Path("/check")
-  public HealthCheck getHealthCheck(@PathParam("apiVersion") String apiVersion) {
-    return new HealthCheck();
-  }
-
-  /**
-   * Handles /kdc_check request.
-   *
-   * @return kdc server reachability service
-   */
-  @Path("/kdc_check")
-  public KdcServerReachabilityCheck getKdcServerReachabilityCheck(@PathParam("apiVersion") String apiVersion) {
-    return new KdcServerReachabilityCheck();
-  }
-
-  /**
-   * Handles /mpacks request.
-   *
-   * @return mpacks service
-   */
-  @Path("/mpacks")
-  public MpacksService getMpacksService(@PathParam("apiVersion") String apiVersion) {
-    return new MpacksService(ApiVersion.valueOf(apiVersion));
-  }
-
-
-}
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 6180a13..6e5c66e 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,9 +44,9 @@ 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.RootService;
 import org.apache.ambari.server.controller.MpackRequest;
 import org.apache.ambari.server.controller.MpackResponse;
+import org.apache.ambari.server.controller.RootService;
 import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.customactions.ActionDefinition;
@@ -59,11 +59,9 @@ 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.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
 import org.apache.ambari.server.orm.entities.MpackEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
-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.stack.upgrade.ConfigUpgradePack;
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
index 4694841..902b8df 100644
--- 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
@@ -17,10 +17,7 @@
  */
 package org.apache.ambari.server.api.services;
 
-import org.apache.ambari.server.api.resources.ResourceInstance;
-
-
-import org.apache.ambari.server.controller.spi.Resource;
+import java.util.Collections;
 
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -33,8 +30,6 @@ import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
-import java.util.Collections;
-
 
 import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.controller.MpackResponse.MpackResponseWrapper;
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 d94fcbc..212ecb6 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
@@ -23,7 +23,6 @@ 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;
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 6061640..f910172 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
@@ -133,8 +133,8 @@ 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.SystemException;
 import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.customactions.ActionDefinition;
 import org.apache.ambari.server.events.MetadataUpdateEvent;
 import org.apache.ambari.server.events.TopologyUpdateEvent;
@@ -157,9 +157,9 @@ import org.apache.ambari.server.orm.entities.ClusterEntity;
 import org.apache.ambari.server.orm.entities.ExtensionLinkEntity;
 import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.orm.entities.MpackEntity;
 import org.apache.ambari.server.orm.entities.RepoDefinitionEntity;
 import org.apache.ambari.server.orm.entities.RepoOsEntity;
-import org.apache.ambari.server.orm.entities.MpackEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.SettingEntity;
@@ -206,20 +206,6 @@ import org.apache.ambari.server.state.Mpack;
 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.Clusters;
-import org.apache.ambari.server.state.ServiceComponentFactory;
-import org.apache.ambari.server.state.ServiceComponentHostFactory;
-import org.apache.ambari.server.state.ConfigFactory;
-import org.apache.ambari.server.state.StackId;
-import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.ConfigHelper;
-import org.apache.ambari.server.state.StackInfo;
-import org.apache.ambari.server.state.State;
-import org.apache.ambari.server.state.Service;
-import org.apache.ambari.server.state.ServiceComponent;
-import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.ServiceComponentHost;
-import org.apache.ambari.server.state.CommandScriptDefinition;
 import org.apache.ambari.server.state.PropertyInfo.PropertyType;
 import org.apache.ambari.server.state.RepositoryInfo;
 import org.apache.ambari.server.state.SecurityType;
@@ -235,26 +221,8 @@ 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.*;
 import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
-import org.apache.ambari.server.state.PropertyInfo;
-import org.apache.ambari.server.state.Config;
-import org.apache.ambari.server.state.DesiredConfig;
-import org.apache.ambari.server.state.MaintenanceState;
-import org.apache.ambari.server.state.SecurityType;
-import org.apache.ambari.server.state.HostState;
-import org.apache.ambari.server.state.ServiceComponentHostEvent;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.ServiceInfo;
-import org.apache.ambari.server.state.RepositoryVersionState;
-import org.apache.ambari.server.state.ServiceOsSpecific;
-import org.apache.ambari.server.state.UnlimitedKeyJCERequirement;
-import org.apache.ambari.server.state.ExtensionInfo;
-import org.apache.ambari.server.state.RepositoryInfo;
-import org.apache.ambari.server.state.OperatingSystemInfo;
-import org.apache.ambari.server.state.HostComponentAdminState;
-import org.apache.ambari.server.state.PropertyDependencyInfo;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityController;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityControllerFactory;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinksProfile;
@@ -4746,13 +4714,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       configs = ambariMetaInfo.getStackProperties(stackName, stackVersion);
     }
 
-    //settings : stackSettings
-    if(configs.size() == 0){
-      if (propertyName != null) {
-        configs = ambariMetaInfo.getStackSettingsByName(stackName, stackVersion, propertyName);
-      } else
-        configs = ambariMetaInfo.getStackSettings(stackName, stackVersion);
-    }
     for (PropertyInfo property: configs) {
       response.add(property.convertToResponse());
     }
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
index 70ddabe..308a2bb 100644
--- 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
@@ -18,8 +18,9 @@
 package org.apache.ambari.server.controller;
 
 
-import org.apache.ambari.server.state.Mpack;
 import org.apache.ambari.server.controller.internal.MpackResourceProvider;
+import org.apache.ambari.server.state.Mpack;
+
 
 import io.swagger.annotations.ApiModelProperty;
 
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
index ba52639..86802d5 100644
--- 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
@@ -17,36 +17,35 @@
  */
 package org.apache.ambari.server.controller.internal;
 
-import java.io.IOException;
 
-import java.util.HashSet;
-import java.util.Set;
+
+import java.io.IOException;
 import java.net.URI;
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Map;
-import java.util.HashMap;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashSet;
-import java.util.ArrayList;
 import java.util.List;
-import com.google.inject.Inject;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.ambari.server.AmbariException;
 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.AmbariManagementController;
+import org.apache.ambari.server.controller.MpackRequest;
+import org.apache.ambari.server.controller.MpackResponse;
 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.Request;
+import org.apache.ambari.server.controller.spi.RequestStatus;
 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.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.PredicateHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.dao.MpackDAO;
@@ -60,6 +59,7 @@ import org.apache.commons.lang.Validate;
 
 import com.google.inject.Inject;
 
+
 /**
  * ResourceProvider for Mpack instances
  */
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
index 123b587..6bfacee 100644
--- 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
@@ -18,10 +18,6 @@
 package org.apache.ambari.server.mpack;
 
 
-import com.google.gson.Gson;
-import com.google.inject.assistedinject.Assisted;
-import com.google.inject.assistedinject.AssistedInject;
-
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -34,6 +30,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -50,21 +47,18 @@ import org.apache.ambari.server.orm.entities.MpackEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.Module;
 import org.apache.ambari.server.state.Mpack;
-import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.stack.StackMetainfoXml;
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
-
 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
-
 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.HashMap;
-
-
+import com.google.gson.Gson;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
 
 /**
  * Manages all mpack related behavior including parsing of stacks and providing access to
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
index d0068c2..87e06cb 100644
--- 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
@@ -17,19 +17,21 @@
  */
 package org.apache.ambari.server.orm.dao;
 
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+
 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;
-
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
 
 @Singleton
 public class MpackDAO {
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
index d555f91..f63440d 100644
--- 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
@@ -17,20 +17,22 @@
  */
 package org.apache.ambari.server.orm.entities;
 
-import org.apache.commons.lang.builder.EqualsBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.util.Objects;
 
-import javax.persistence.NamedQuery;
-import javax.persistence.NamedQueries;
-import javax.persistence.Table;
+import javax.persistence.Column;
 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;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 
 /**
  * The {@link MpackEntity} class represents the mpack objects in the cluster.
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 ca3ff30..aea75dc 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
@@ -140,7 +140,7 @@ public class StackManager {
    *           if an exception occurs while processing the stacks
    */
   @AssistedInject
-  public StackManager(@Assisted("stackRoot") File stackRootDir,
+  public StackManager(@Assisted("stackRoot") File stackRoot,
       @Assisted("commonServicesRoot") @Nullable File commonServicesRoot,
       @Assisted("extensionRoot") @Nullable File extensionRoot,
       @Assisted OsFamily osFamily, @Assisted boolean validate,
@@ -150,7 +150,6 @@ public class StackManager {
 
     LOG.info("Initializing the stack manager...");
 
-    stackRoot = stackRootDir;
     if (validate) {
       validateStackDirectory(stackRoot);
       validateCommonServicesDirectory(commonServicesRoot);
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Module.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Module.java
index 800a9e0..9ceabf2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Module.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Module.java
@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.state;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Objects;
 
@@ -51,6 +52,8 @@ public class Module {
   @SerializedName("components")
   private List<ModuleComponent> components;
 
+  private HashMap<String, ModuleComponent> componentHashMap;
+
   public Category getCategory() {
     return category;
   }
@@ -127,6 +130,15 @@ public class Module {
     this.components = components;
   }
 
+  /**
+   * Fetch a particular module component by the component name.
+   * @param moduleComponentName
+   * @return
+   */
+  public ModuleComponent getModuleComponent(String moduleComponentName) {
+    return componentHashMap.get(moduleComponentName);
+  }
+
 
   @Override
   public boolean equals(Object o) {
@@ -160,4 +172,17 @@ public class Module {
             ", components=" + components +
             '}';
   }
+
+  /**
+   * Loads the components into a map (component name, component) for ease of access.
+   */
+  public void populateComponentMap() {
+    componentHashMap = new HashMap<>();
+    for (ModuleComponent moduleComponent : getComponents()){
+      // set reverse lookup
+      moduleComponent.setModule(this);
+
+      componentHashMap.put(moduleComponent.getName(), moduleComponent);
+    }
+  }
 }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ModuleComponent.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ModuleComponent.java
index 56c82af..dc90d3b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ModuleComponent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ModuleComponent.java
@@ -17,6 +17,7 @@
  */
 package org.apache.ambari.server.state;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.google.gson.annotations.SerializedName;
 
 public class ModuleComponent {
@@ -32,6 +33,12 @@ public class ModuleComponent {
   @SerializedName("version")
   private String version;
 
+  /**
+   * The owning module for this module component.
+   */
+  @JsonIgnore
+  private transient Module module;
+
   public String getId() {
     return id;
   }
@@ -106,4 +113,8 @@ public class ModuleComponent {
             ", version='" + version + '\'' +
             '}';
   }
+
+  public void setModule(Module module) {
+    this.module = module;
+  }
 }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
index 3e76338..766cafb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
@@ -17,14 +17,16 @@
  */
 package org.apache.ambari.server.state;
 
-import com.google.gson.annotations.SerializedName;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.builder.EqualsBuilder;
 
 import java.util.HashMap;
 import java.util.List;
 import java.util.Objects;
 
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
+
+import com.google.gson.annotations.SerializedName;
+
 /**
  * Represents the state of an mpack.
  */
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/MpackResourceDefinitionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/MpackResourceDefinitionTest.java
index 08166b8..08e6c68 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/MpackResourceDefinitionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/MpackResourceDefinitionTest.java
@@ -20,6 +20,7 @@
 package org.apache.ambari.server.api.resources;
 
 import static junit.framework.Assert.assertEquals;
+
 import org.junit.Test;
 
 /**
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 64287d7..ef202ce 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
@@ -18,27 +18,6 @@
 
 package org.apache.ambari.server.api.services;
 
-import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
-import org.apache.ambari.server.orm.dao.MetainfoDAO;
-import org.apache.ambari.server.state.AutoDeployInfo;
-import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.CustomCommandDefinition;
-import org.apache.ambari.server.state.DependencyInfo;
-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.RepositoryInfo;
-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.Mpacks;
-import org.apache.ambari.server.controller.MpackRequest;
-import org.apache.ambari.server.controller.MpackResponse;
-import org.apache.ambari.server.mpack.MpackManager;
-import org.apache.ambari.server.mpack.MpackManagerFactory;
 import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
@@ -53,6 +32,7 @@ import java.io.File;
 import java.io.FileReader;
 import java.lang.reflect.Field;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -60,8 +40,6 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 import java.util.UUID;
-import java.util.HashMap;
-import java.util.ArrayList;
 
 import javax.persistence.EntityManager;
 
@@ -69,18 +47,38 @@ import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.H2DatabaseCleaner;
 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.internal.DeleteHostComponentStatusMetaData;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.metadata.ActionMetadata;
 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.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.OrmTestHelper;
+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.RepositoryVersionEntity;
 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;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.CustomCommandDefinition;
+import org.apache.ambari.server.state.DependencyInfo;
+import org.apache.ambari.server.state.Mpack;
+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.RepositoryInfo;
+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.alert.AlertDefinition;
 import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
 import org.apache.ambari.server.state.alert.MetricSource;
@@ -354,13 +352,12 @@ public class AmbariMetaInfoTest {
   public void testRegisterMpacks() throws Exception{
     MpackManager mm = metaInfo.getMpackManager();
     MpackRequest mpackRequest = createNiceMock(MpackRequest.class);
-    Mpacks mpacks = new Mpacks();
-    mpacks.setMpackId((long)100);
-    mpacks.setPacklets(new ArrayList<Packlet>());
+    Mpack mpacks = new Mpack();
+    mpacks.setMpackId("100");
     mpacks.setPrerequisites(new HashMap<String, String>());
     mpacks.setRegistryId(new Long(100));
     mpacks.setVersion("3.0");
-    mpacks.setMpacksUri("abc.tar.gz");
+    mpacks.setMpackUri("abc.tar.gz");
     mpacks.setDescription("Test mpacks");
     mpacks.setName("testMpack");
     MpackResponse mpackResponse = new MpackResponse(mpacks);
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/MpackServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/MpackServiceTest.java
deleted file mode 100644
index 06eb15d..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/MpackServiceTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * 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.api.services;
-
-import org.apache.ambari.server.api.resources.ResourceInstance;
-import org.apache.ambari.server.api.services.parsers.RequestBodyParser;
-import org.apache.ambari.server.api.services.serializers.ResultSerializer;
-
-import org.apache.ambari.server.api.util.ApiVersion;
-import org.apache.ambari.server.controller.spi.Resource;
-
-
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.UriInfo;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit tests for MpackService
- */
-public class MpackServiceTest extends BaseServiceTest{
-  @Override
-  public List<BaseServiceTest.ServiceTestInvocation> getTestInvocations() throws Exception {
-    List<BaseServiceTest.ServiceTestInvocation> listInvocations = new ArrayList<>();
-
-    // getMpacks
-    MpacksService service = new TestMpackService("null");
-    Method m = service.getClass().getMethod("getMpacks", String.class, HttpHeaders.class, UriInfo.class);
-    Object[] args = new Object[]{null, getHttpHeaders(), getUriInfo()};
-    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
-
-    // getMpack
-    service = new TestMpackService("1");
-    m = service.getClass().getMethod("getMpack", String.class, HttpHeaders.class, UriInfo.class, String.class);
-    args = new Object[]{null, getHttpHeaders(), getUriInfo(), ""};
-    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
-
-    //createMpacks
-    service = new TestMpackService(null);
-    m = service.getClass().getMethod("createMpacks", String.class, HttpHeaders.class, UriInfo.class);
-    args = new Object[]{"body", getHttpHeaders(), getUriInfo()};
-    listInvocations.add(new ServiceTestInvocation(Request.Type.POST, service, m, args, "body"));
-
-    return listInvocations;
-  }
-  private class TestMpackService extends MpacksService {
-
-    private String m_mpackId;
-
-    private TestMpackService(String mpackId) {
-      super(ApiVersion.Default);
-      m_mpackId = mpackId;
-    }
-
-    @Override
-    protected ResourceInstance createResource(Resource.Type type, Map<Resource.Type, String> mapIds) {
-      return getTestResource();
-    }
-
-    @Override
-    RequestFactory getRequestFactory() {
-      return getTestRequestFactory();
-    }
-
-    @Override
-    protected RequestBodyParser getBodyParser() {
-      return getTestBodyParser();
-    }
-
-    @Override
-    protected ResultSerializer getResultSerializer() {
-      return getTestResultSerializer();
-    }
-  }
-
-
-}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
index 1e06d18..ad7bdb3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
@@ -24,29 +24,7 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JAVA_VERS
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.NOT_MANAGED_HDFS_PATH_LIST;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_NAME;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_VERSION;
-import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.security.authorization.Users;
-import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.Config;
-import org.apache.ambari.server.state.ConfigHelper;
-import org.apache.ambari.server.state.DesiredConfig;
-import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.MaintenanceState;
-import org.apache.ambari.server.state.PropertyInfo;
-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.ServiceComponentHost;
-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.Mpack;
+
 import static org.easymock.EasyMock.anyBoolean;
 import static org.easymock.EasyMock.anyLong;
 import static org.easymock.EasyMock.anyObject;
@@ -98,10 +76,12 @@ import org.apache.ambari.server.agent.stomp.MetadataHolder;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.internal.RequestStageContainer;
+import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.entities.LdapSyncSpecEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.security.authorization.Users;
 import org.apache.ambari.server.security.authorization.internal.InternalAuthenticationToken;
 import org.apache.ambari.server.security.encryption.CredentialStoreService;
 import org.apache.ambari.server.security.encryption.CredentialStoreType;
@@ -2457,7 +2437,7 @@ public class AmbariManagementControllerImplTest {
     mpack.setPrerequisites(new HashMap<String, String>());
     mpack.setRegistryId(new Long(100));
     mpack.setVersion("3.0");
-    mpack.setMpacksUri("abc.tar.gz");
+    mpack.setMpackUri("abc.tar.gz");
     mpack.setDescription("Test mpack");
     mpack.setName("testMpack");
     MpackResponse mpackResponse = new MpackResponse(mpack);
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackRequestTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackRequestTest.java
index 630fb15..9a518a4 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackRequestTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackRequestTest.java
@@ -18,8 +18,8 @@
 package org.apache.ambari.server.controller;
 
 
-import org.junit.Test;
 import org.junit.Assert;
+import org.junit.Test;
 
 /**
  * Unit tests for MpackRequest
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java
index 3ef98c6..4572f57 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java
@@ -25,9 +25,6 @@ import org.apache.ambari.server.state.Module;
 import org.apache.ambari.server.state.Mpack;
 import org.junit.Assert;
 import org.junit.Test;
-import org.junit.Assert;
-import java.util.ArrayList;
-import java.util.HashMap;
 
 /**
  * Unit tests for MpackResponse
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AbstractResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AbstractResourceProviderTest.java
index 0ed8fba..2c126d9 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AbstractResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AbstractResourceProviderTest.java
@@ -838,7 +838,7 @@ public class AbstractResourceProviderTest {
   public static class TestResourceProvider extends AbstractResourceProvider {
 
     protected TestResourceProvider() {
-      super(propertyIds, keyPropertyIds);
+      super(propertyIds, AbstractResourceProviderTest.keyPropertyIds);
     }
 
     @Override
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterControllerImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterControllerImplTest.java
index 686b5cd..0238617 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterControllerImplTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterControllerImplTest.java
@@ -1159,7 +1159,7 @@ public class ClusterControllerImplTest {
 
   private static class TestStackVersionResourceProvider extends TestResourceProvider {
     private TestStackVersionResourceProvider() {
-      super(StackVersionResourceProvider.propertyIds, StackVersionResourceProvider.keyPropertyIds);
+      super(StackVersionResourceProvider.PROPERTY_IDS, StackVersionResourceProvider.KEY_PROPERTY_IDS);
     }
 
     @Override
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
index f453684..dbe2ca4 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
@@ -17,8 +17,7 @@
  */
 package org.apache.ambari.server.controller.internal;
 
-import com.google.inject.util.Modules;
-import org.apache.ambari.server.state.Module;
+
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
@@ -31,44 +30,32 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-
-import com.google.inject.Injector;
-import com.google.inject.Binder;
-import com.google.inject.Guice;
+import javax.persistence.EntityManager;
 
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.MpackRequest;
 import org.apache.ambari.server.controller.MpackResponse;
+import org.apache.ambari.server.controller.spi.Predicate;
+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.spi.Request;
-import org.apache.ambari.server.controller.spi.Predicate;
-import org.apache.ambari.server.controller.MpackRequest;
-import org.apache.ambari.server.controller.utilities.*;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.dao.MpackDAO;
 import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.apache.ambari.server.state.Module;
 import org.apache.ambari.server.state.Mpack;
 
 import org.easymock.EasyMock;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.verify;
-import org.junit.Test;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Test;
 
 import com.google.inject.Binder;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-
-
-import javax.persistence.EntityManager;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.List;
+import com.google.inject.util.Modules;
 
 public class MpackResourceProviderTest {
 
@@ -271,7 +258,7 @@ public class MpackResourceProviderTest {
     mpack.setPrerequisites(new HashMap<String, String>());
     mpack.setRegistryId(new Long(100));
     mpack.setVersion("3.0");
-    mpack.setMpacksUri("../../../../../../../resources/mpacks-v2/abc.tar.gz");
+    mpack.setMpackUri("../../../../../../../resources/mpacks-v2/abc.tar.gz");
     mpack.setDescription("Test mpack");
     mpack.setName("testMpack");
 
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/MpackDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/MpackDAOTest.java
index f589fe8..c56ff93 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/MpackDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/MpackDAOTest.java
@@ -17,19 +17,23 @@
  */
 package org.apache.ambari.server.orm.dao;
 
-import com.google.inject.Injector;
-import com.google.inject.Guice;
-import org.apache.ambari.server.orm.entities.MpackEntity;
-import org.junit.Before;
-import org.junit.Test;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
 import com.google.inject.persist.UnitOfWork;
 
-import java.util.List;
-import java.util.ArrayList;
 
 /**
  * Tests {@link MpackDAO}.
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/MpackEntityTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/MpackEntityTest.java
index 4677837..d2d2476 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/MpackEntityTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/MpackEntityTest.java
@@ -18,11 +18,11 @@
 
 package org.apache.ambari.server.orm.entities;
 
-import org.junit.Test;
-import org.junit.Assert;
-
 import java.util.Objects;
 
+import org.junit.Assert;
+import org.junit.Test;
+
 /**
  * Tests methods on {@link MpackEntity}.
  */
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
index e478968..2096dde 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
@@ -33,13 +33,13 @@ public class MpackTest {
     mpack.setResourceId((long)100);
     mpack.setDescription("desc");
     mpack.setVersion("3.0");
-    mpack.setMpacksUri("abc.tar.gz");
+    mpack.setMpackUri("abc.tar.gz");
     mpack.setRegistryId(new Long(100));
 
     Assert.assertEquals("name", mpack.getName());
     Assert.assertEquals(new Long(100), mpack.getResourceId());
     Assert.assertEquals("desc", mpack.getDescription());
-    Assert.assertEquals("abc.tar.gz", mpack.getMpacksUri());
+    Assert.assertEquals("abc.tar.gz", mpack.getMpackUri());
     Assert.assertEquals(new Long(100), mpack.getRegistryId());
 
   }
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/MpacksTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/MpacksTest.java
deleted file mode 100644
index 6d87a60..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/MpacksTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * 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.Gson;
-import org.junit.Test;
-import org.junit.Assert;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class MpacksTest {
-  @Test
-  public void testMpacks() {
-    Mpacks mpacks = new Mpacks();
-    mpacks.setName("name");
-    mpacks.setMpackId((long)100);
-    mpacks.setDescription("desc");
-    mpacks.setVersion("3.0");
-    mpacks.setMpacksUri("abc.tar.gz");
-    mpacks.setRegistryId(new Long(100));
-
-    Assert.assertEquals("name", mpacks.getName());
-    Assert.assertEquals(new Long(100), mpacks.getMpackId());
-    Assert.assertEquals("desc", mpacks.getDescription());
-    Assert.assertEquals("abc.tar.gz", mpacks.getMpacksUri());
-    Assert.assertEquals(new Long(100), mpacks.getRegistryId());
-
-  }
-
-  @Test
-  public void testMpacksUsingGson() {
-    String mpackJsonContents = "{\n" +
-            "  \"name\" : \"hdf-ambari-mpack\",\n" +
-            "  \"version\": \"3.0.0.0-111\",\n" +
-            "  \"description\" : \"HDF 3.0.0 Ambari Management Pack\",\n" +
-            "  \"prerequisites\": {\n" +
-            "    \"min-ambari-version\" : \"3.0.0.0\"\n" +
-            "  },\n" +
-            "  \"packlets\": [\n" +
-            "    {\n" +
-            "      \"type\" : \"service-packlet\",\n" +
-            "      \"name\" : \"NIFI\",\n" +
-            "      \"version\" : \"1.2.0.0-123\",\n" +
-            "      \"source_dir\": \"packlets/NIFI-1.2.0.0-123.tar.gz\"\n" +
-            "    },\n" +
-            "    {\n" +
-            "      \"type\" : \"service-packlet\",\n" +
-            "      \"name\" : \"STREAMLINE\",\n" +
-            "      \"version\" : \"1.0.0.0-100\",\n" +
-            "      \"source_dir\": \"packlets/STREAMLINE-1.0.0.0-100.tar.gz\"\n" +
-            "    }\n" +
-            "  ]\n" +
-            "}\n";
-    HashMap<String, String> expectedPrereq = new HashMap<>();
-    expectedPrereq.put("min-ambari-version","3.0.0.0");
-    ArrayList<Packlet> expectedPacklets = new ArrayList<>();
-    Packlet nifi = new Packlet();
-    nifi.setType("service-packlet");
-    nifi.setVersion("1.2.0.0-123");
-    nifi.setSourceDir("packlets/NIFI-1.2.0.0-123.tar.gz");
-    nifi.setName("NIFI");
-    Packlet streamline = new Packlet();
-    streamline.setName("STREAMLINE");
-    streamline.setType("service-packlet");
-    streamline.setSourceDir("packlets/STREAMLINE-1.0.0.0-100.tar.gz");
-    streamline.setVersion("1.0.0.0-100");
-    expectedPacklets.add(nifi);
-    expectedPacklets.add(streamline);
-
-    Gson gson = new Gson();
-    Mpacks mpacks = gson.fromJson(mpackJsonContents, Mpacks.class);
-    Assert.assertEquals("hdf-ambari-mpack",mpacks.getName());
-    Assert.assertEquals("3.0.0.0-111", mpacks.getVersion());
-    Assert.assertEquals("HDF 3.0.0 Ambari Management Pack",mpacks.getDescription());
-    Assert.assertEquals(expectedPrereq, mpacks.getPrerequisites());
-    Assert.assertEquals(expectedPacklets.toString(), mpacks.getPacklets().toString());
-  }
-
-}
diff --git a/contrib/ambari-scom/ambari-scom-server/src/test/java/org/apache/ambari/msi/AbstractResourceProviderTest.java b/contrib/ambari-scom/ambari-scom-server/src/test/java/org/apache/ambari/msi/AbstractResourceProviderTest.java
index dc5999b..ed77855 100644
--- a/contrib/ambari-scom/ambari-scom-server/src/test/java/org/apache/ambari/msi/AbstractResourceProviderTest.java
+++ b/contrib/ambari-scom/ambari-scom-server/src/test/java/org/apache/ambari/msi/AbstractResourceProviderTest.java
@@ -18,17 +18,12 @@
 
 package org.apache.ambari.msi;
 
+
 import org.apache.ambari.scom.TestClusterDefinitionProvider;
 import org.apache.ambari.scom.TestHostInfoProvider;
-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.junit.Assert;
 import org.junit.Test;
 
-import java.util.HashSet;
-import java.util.Set;
-
 /**
  * AbstractResourceProvider tests.
  */


[ambari] 07/20: AMBARI-21849 : Clean up repo_version table during mpack delete, add create validation for mpacks (mradhakrishnan)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 4ae922209f7173f492aa4a58b9e9c5c3fc34437b
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Wed Aug 30 11:37:24 2017 -0700

    AMBARI-21849 : Clean up repo_version table during mpack delete, add create validation for mpacks (mradhakrishnan)
---
 .../ambari/server/api/services/AmbariMetaInfo.java |  4 +-
 .../controller/internal/MpackResourceProvider.java | 53 +++++++++++++++++-
 .../server/orm/dao/RepositoryVersionDAO.java       | 15 ++++-
 .../internal/MpackResourceProviderTest.java        | 65 ++++++++++++----------
 4 files changed, 104 insertions(+), 33 deletions(-)

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 6812bf2..6ae0e1c 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
@@ -1554,7 +1554,9 @@ public class AmbariMetaInfo {
    * @throws IOException
    */
   public void removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException {
-    versionDefinitions.clear();
+    if(versionDefinitions != null) {
+      versionDefinitions.clear();
+    }
     boolean stackDelete = mpackManager.removeMpack(mpackEntity, stackEntity);
 
     if(stackDelete) {
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
index 7366390..c4833d1 100644
--- 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
@@ -18,8 +18,12 @@
 package org.apache.ambari.server.controller.internal;
 
 import java.io.IOException;
+
 import java.util.HashSet;
 import java.util.Set;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Map;
 import java.util.HashMap;
@@ -47,11 +51,16 @@ import org.apache.ambari.server.controller.MpackRequest;
 import org.apache.ambari.server.controller.utilities.PredicateHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.dao.MpackDAO;
+import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.MpackEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.Packlet;
 
+import org.apache.ambari.server.state.StackId;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.Validate;
+
 /**
  * ResourceProvider for Mpack instances
  */
@@ -88,6 +97,9 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
   @Inject
   protected static StackDAO stackDAO;
 
+  @Inject
+  protected static RepositoryVersionDAO repositoryVersionDAO;
+
   static {
     // properties
     PROPERTY_IDS.add(MPACK_ID);
@@ -122,8 +134,10 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     Set<Resource> associatedResources = new HashSet<>();
     try {
       MpackRequest mpackRequest = getRequest(request);
-      if (mpackRequest == null)
+      if (mpackRequest == null) {
         throw new BodyParseException("Please provide " + MPACK_NAME + " ," + MPACK_VERSION + " ," + MPACK_URI);
+      }
+      validateCreateRequest(mpackRequest);
       MpackResponse response = getManagementController().registerMpack(mpackRequest);
       if (response != null) {
         notifyCreate(Resource.Type.Mpack, request);
@@ -145,8 +159,39 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     return null;
   }
 
-  public MpackRequest getRequest(Request request) {
-    MpackRequest mpackRequest = new MpackRequest();
+  /***
+   * Validates the request body for the required properties in order to create an Mpack resource.
+   * @param mpackRequest
+   */
+  private void validateCreateRequest(MpackRequest mpackRequest) {
+    final String mpackName = mpackRequest.getMpackName();
+    final String mpackUrl = mpackRequest.getMpackUri();
+    final Long registryId = mpackRequest.getRegistryId();
+    final String mpackVersion = mpackRequest.getMpackVersion();
+
+    if(registryId == null) {
+      Validate.isTrue(mpackUrl != null);
+      LOG.info("Received a createMpack request"
+              + ", mpackUrl=" + mpackUrl);
+    } else {
+      Validate.notNull(mpackName, "MpackName should not be null");
+      Validate.notNull(mpackVersion, "MpackVersion should not be null");
+      LOG.info("Received a createMpack request"
+              + ", mpackName=" + mpackName
+              + ", mpackVersion=" + mpackVersion
+              + ", registryId=" + registryId);
+    }
+    try {
+      URI uri = new URI(mpackUrl);
+      URL url = uri.toURL();
+      String jsonString = IOUtils.toString(url);
+    }catch(Exception e){
+      Validate.isTrue(e == null, e.getMessage() + " is an invalid mpack uri. Please check the download link for the mpack again.");
+    }
+  }
+
+  public MpackRequest getRequest(Request request) throws AmbariException {
+     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
@@ -260,6 +305,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
 
           MpackEntity mpackEntity = mpackDAO.findById(mpackId);
           StackEntity stackEntity = stackDAO.findByMpack(mpackId);
+
           try {
             getManagementController().removeMpack(mpackEntity, stackEntity);
             if (mpackEntity != null) {
@@ -267,6 +313,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
                 @Override
                 public DeleteStatusMetaData invoke() throws AmbariException {
                   if (stackEntity != null) {
+                    repositoryVersionDAO.removeByStack(new StackId(stackEntity.getStackName() + "-" + stackEntity.getStackVersion()));
                     stackDAO.removeByMpack(mpackId);
                     notifyDelete(Resource.Type.Stack, predicate);
                   }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
index eaccdb0..30b7adf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/RepositoryVersionDAO.java
@@ -255,8 +255,21 @@ public class RepositoryVersionDAO extends CrudDAO<RepositoryVersionEntity, Long>
   @RequiresSession
   public List<RepositoryVersionEntity> findByServiceDesiredVersion(List<RepositoryVersionEntity> matching) {
     TypedQuery<RepositoryVersionEntity> query = entityManagerProvider.get().
-          createNamedQuery("findByServiceDesiredVersion", RepositoryVersionEntity.class);
+            createNamedQuery("findByServiceDesiredVersion", RepositoryVersionEntity.class);
 
     return daoUtils.selectList(query, matching);
   }
+   /**
+   * Removes the specified repoversion entry based on stackid.
+   *
+   * @param stackId
+   *
+   */
+  @Transactional
+  public void removeByStack(StackId stackId) {
+    List<RepositoryVersionEntity> repoVersionDeleteCandidates = findByStack(stackId);
+    for(RepositoryVersionEntity repositoryVersionEntity : repoVersionDeleteCandidates) {
+      entityManagerProvider.get().remove(repositoryVersionEntity);
+    }
+  }
 }
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
index d6638c6..0e38b08 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
@@ -17,6 +17,20 @@
  */
 package org.apache.ambari.server.controller.internal;
 
+import org.apache.commons.io.IOUtils;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.net.URI;
+import java.net.URL;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 
 import com.google.inject.Injector;
@@ -110,10 +124,8 @@ public class MpackResourceProviderTest {
     replay(m_dao);
 
     ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
-            type,
-            PropertyHelper.getPropertyIds(type),
-            PropertyHelper.getKeyPropertyIds(type),
-            m_amc);
+            type
+    );
 
     // create the request
     Request request = PropertyHelper.getReadRequest();
@@ -183,10 +195,7 @@ public class MpackResourceProviderTest {
     replay(m_dao,m_amc);
 
     ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
-            type,
-            PropertyHelper.getPropertyIds(type),
-            PropertyHelper.getKeyPropertyIds(type),
-            m_amc);
+            type);
 
     // create the request
     Request request = PropertyHelper.getReadRequest();
@@ -210,12 +219,13 @@ public class MpackResourceProviderTest {
   @Test
   public void testCreateResources() throws Exception {
     MpackRequest mpackRequest = new MpackRequest();
-    mpackRequest.setMpackUri("abc.tar.gz");
+    String mpackUri = Paths.get("src/test/resources/mpacks-v2/abc.tar.gz").toUri().toURL().toString();
+    mpackRequest.setMpackUri(mpackUri);
     Request request = createMock(Request.class);
-    MpackResponse response = new MpackResponse(setupMpacks());
+    MpackResponse response = new MpackResponse(setupMpack());
     Set<Map<String, Object>> properties = new HashSet<>();
     Map propertyMap = new HashMap();
-    propertyMap.put(MpackResourceProvider.MPACK_URI,"abc.tar.gz");
+    propertyMap.put(MpackResourceProvider.MPACK_URI,mpackUri);
     properties.add(propertyMap);
 
     // set expectations
@@ -225,10 +235,8 @@ public class MpackResourceProviderTest {
     // end expectations
 
     ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
-            Resource.Type.Mpack,
-            PropertyHelper.getPropertyIds(Resource.Type.Mpack),
-            PropertyHelper.getKeyPropertyIds(Resource.Type.Mpack),
-            m_amc);
+            Resource.Type.Mpack 
+            );
 
     AbstractResourceProviderTest.TestObserver observer = new AbstractResourceProviderTest.TestObserver();
     ((ObservableResourceProvider)provider).addObserver(observer);
@@ -241,7 +249,7 @@ public class MpackResourceProviderTest {
       Assert.assertEquals((long)100,r.getPropertyValue(MpackResourceProvider.MPACK_ID));
       Assert.assertEquals("testMpack",r.getPropertyValue(MpackResourceProvider.MPACK_NAME));
       Assert.assertEquals("3.0",r.getPropertyValue(MpackResourceProvider.MPACK_VERSION));
-      Assert.assertEquals("abc.tar.gz",r.getPropertyValue(MpackResourceProvider.MPACK_URI));
+      Assert.assertEquals("../../../../../../../resources/mpacks-v2/abc.tar.gz",r.getPropertyValue(MpackResourceProvider.MPACK_URI));
     }
     ResourceProviderEvent lastEvent = observer.getLastEvent();
     Assert.assertNotNull(lastEvent);
@@ -253,18 +261,19 @@ public class MpackResourceProviderTest {
     verify(m_amc,request);
   }
 
-  public Mpacks setupMpacks(){
-    Mpacks mpacks = new Mpacks();
-    mpacks.setMpackId((long)100);
-    mpacks.setPacklets(new ArrayList<Packlet>());
-    mpacks.setPrerequisites(new HashMap<String, String>());
-    mpacks.setRegistryId(new Long(100));
-    mpacks.setVersion("3.0");
-    mpacks.setMpacksUri("abc.tar.gz");
-    mpacks.setDescription("Test mpacks");
-    mpacks.setName("testMpack");
-
-    return mpacks;
+
+  public Mpacks setupMpack() {
+    Mpacks mpack = new Mpacks();
+    mpack.setMpackId((long)100);
+    mpack.setPacklets(new ArrayList<Packlet>());
+    mpack.setPrerequisites(new HashMap<String, String>());
+    mpack.setRegistryId(new Long(100));
+    mpack.setVersion("3.0");
+    mpack.setMpacksUri("../../../../../../../resources/mpacks-v2/abc.tar.gz");
+    mpack.setDescription("Test mpack");
+    mpack.setName("testMpack");
+
+    return mpack;
   }
 
   /**


[ambari] 11/20: AMBARI-22283 : Add stack name and version to mpack API (mradhakrishnan)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit aaa56f26c351df0170d4931c21f3ac80aa37f414
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Tue Oct 24 14:44:07 2017 -0700

    AMBARI-22283 : Add stack name and version to mpack API (mradhakrishnan)
---
 .../api/resources/MpackResourceDefinition.java     |  16 ++-
 .../resources/StackVersionResourceDefinition.java  |  50 ++++++++
 .../internal/AbstractResourceProvider.java         |   2 +-
 .../internal/StackVersionResourceProvider.java     | 134 +++++++++++++--------
 .../apache/ambari/server/mpack/MpackManager.java   |   2 +-
 5 files changed, 152 insertions(+), 52 deletions(-)

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
index 26972d8..167e773 100644
--- 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
@@ -17,6 +17,12 @@
  */
 package org.apache.ambari.server.api.resources;
 
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.ambari.server.api.services.Request;
 import org.apache.ambari.server.api.util.TreeNode;
 import org.apache.ambari.server.controller.internal.ResourceImpl;
@@ -25,9 +31,6 @@ import org.apache.ambari.server.controller.spi.Resource.Type;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Map;
-import java.util.List;
-import java.util.ArrayList;
 
 /**
  * Resource Definition for Mpack Resource types.
@@ -56,6 +59,13 @@ public class MpackResourceDefinition extends BaseResourceDefinition {
   }
 
   @Override
+  public Set<SubResourceDefinition> getSubResourceDefinitions() {
+    Set<SubResourceDefinition> setChildren = new HashSet<>();
+    setChildren.add(new SubResourceDefinition(Resource.Type.StackVersion, null, false));
+    return setChildren;
+  }
+
+  @Override
   public List<PostProcessor> getPostProcessors() {
     List<PostProcessor> listProcessors = new ArrayList<>();
     listProcessors.add(new MpackHrefProcessor());
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
index 14f8b4f..b0786e1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
@@ -18,8 +18,14 @@
 
 package org.apache.ambari.server.api.resources;
 
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.ambari.server.controller.internal.ResourceImpl;
 import org.apache.ambari.server.controller.spi.Resource;
 
 public class StackVersionResourceDefinition extends BaseResourceDefinition {
@@ -53,4 +59,48 @@ public class StackVersionResourceDefinition extends BaseResourceDefinition {
     return children;
   }
 
+  @Override
+  public List<PostProcessor> getPostProcessors() {
+    List<PostProcessor> listProcessors = new ArrayList<>();
+    listProcessors.add(new StackVersionHrefProcessor());
+    listProcessors.add(new StackVersionPostProcessor());
+    return listProcessors;
+  }
+
+  /**
+   * Post Processing the mpack href when the call comes from stack endpoint to ensure that the
+   * href is a backreference to the mpacks end point
+   */
+  private class StackVersionHrefProcessor extends BaseHrefPostProcessor {
+    @Override
+    public void process(Request request, TreeNode<Resource> resultNode, String href) {
+      if (href.contains("/mpacks/")) {
+        ResourceImpl mpack = (ResourceImpl) resultNode.getObject();
+        Map<String, Map<String, Object>> mapInfo = mpack.getPropertiesMap();
+        Map<String, Object> versionInfo = mapInfo.get("Versions");
+
+        int idx = href.indexOf("mpacks/");
+        String stackName = (String)versionInfo.get("stack_name");
+        String stackVersion = (String)versionInfo.get("stack_version");
+        href = href.substring(0, idx) + "stacks/" + stackName + "/versions/" + stackVersion;
+        resultNode.setProperty("href", href);
+      } else {
+        super.process(request, resultNode, href);
+      }
+    }
+  }
+
+  /***
+   * Post processing to change the name of the result node to current_mpack
+   */
+  private class StackVersionPostProcessor implements PostProcessor {
+    @Override
+    public void process(Request request, TreeNode<Resource> resultNode, String href) {
+      if (href.contains("/mpacks/")) {
+        resultNode.setName("stack");
+
+      }
+    }
+  }
+
  }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
index 21a70ca..810f191 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
@@ -61,7 +61,7 @@ public abstract class AbstractResourceProvider extends BaseProvider implements R
   /**
    * Key property mapping by resource type.
    */
-  private final Map<Resource.Type, String> keyPropertyIds;
+  protected final Map<Resource.Type, String> keyPropertyIds;
 
   /**
    * Observers of this observable resource provider.
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
index f2e6d1a..86a994a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
@@ -19,7 +19,9 @@
 
 package org.apache.ambari.server.controller.internal;
 
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -34,71 +36,108 @@ import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.spi.Resource.Type;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.dao.StackDAO;
+import org.apache.ambari.server.orm.entities.StackEntity;
+
+import com.google.inject.Inject;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Sets;
 
 @StaticallyInject
 public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
-
-  public static final String STACK_VERSION_PROPERTY_ID     = PropertyHelper.getPropertyId("Versions", "stack_version");
-  public static final String STACK_NAME_PROPERTY_ID        = PropertyHelper.getPropertyId("Versions", "stack_name");
-  public static final String STACK_MIN_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("Versions", "min_upgrade_version");
-  public static final String STACK_ACTIVE_PROPERTY_ID      = PropertyHelper.getPropertyId("Versions", "active");
-  public static final String STACK_VALID_PROPERTY_ID      = PropertyHelper.getPropertyId("Versions", "valid");
-  public static final String STACK_ERROR_SET      = PropertyHelper.getPropertyId("Versions", "stack-errors");
-  public static final String STACK_CONFIG_TYPES            = PropertyHelper.getPropertyId("Versions", "config_types");
-  public static final String STACK_PARENT_PROPERTY_ID      = PropertyHelper.getPropertyId("Versions", "parent_stack_version");
-  public static final String UPGRADE_PACKS_PROPERTY_ID = PropertyHelper.getPropertyId("Versions", "upgrade_packs");
-  public static final String STACK_MIN_JDK     = PropertyHelper.getPropertyId("Versions", "min_jdk");
-  public static final String STACK_MAX_JDK     = PropertyHelper.getPropertyId("Versions", "max_jdk");
+  public static final String RESPONSE_KEY = "Versions";
+  public static final String ALL_PROPERTIES = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "*";
+  public static final String STACK_VERSION_PROPERTY_ID     = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_version";
+  public static final String STACK_NAME_PROPERTY_ID        = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_name";
+  public static final String STACK_MIN_VERSION_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "min_upgrade_version";
+  public static final String STACK_ACTIVE_PROPERTY_ID      = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "active";
+  public static final String STACK_VALID_PROPERTY_ID      = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "valid";
+  public static final String STACK_ERROR_SET      = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP +"stack-errors";
+  public static final String STACK_CONFIG_TYPES            = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "config_types";
+  public static final String STACK_PARENT_PROPERTY_ID      = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "parent_stack_version";
+  public static final String UPGRADE_PACKS_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "upgrade_packs";
+  public static final String STACK_MIN_JDK     = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "min_jdk";
+  public static final String STACK_MAX_JDK     = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "max_jdk";
+  public static final String MPACK_ID     = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_id";
+
+  public static final Set<String> PROPERTY_IDS = new HashSet<>();
+
+  @Inject
+  protected static StackDAO stackDAO;
+
+
+  private static Set<String> pkPropertyIds = new HashSet<>(
+    Arrays.asList(new String[]{STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID, MPACK_ID}));
 
   /**
-   * The key property ids for a StackVersion resource.
+   * The key property ids for a mpack resource.
    */
-  protected static Map<Resource.Type, String> keyPropertyIds = ImmutableMap.<Resource.Type, String>builder()
-      .put(Type.Stack, STACK_NAME_PROPERTY_ID)
-      .put(Type.StackVersion, STACK_VERSION_PROPERTY_ID)
-      .build();
+  public static final Map<Resource.Type, String> KEY_PROPERTY_IDS = new HashMap<>();
+
+  static {
+    // properties
+    PROPERTY_IDS.add(MPACK_ID);
+    PROPERTY_IDS.add(STACK_VERSION_PROPERTY_ID);
+    PROPERTY_IDS.add(STACK_NAME_PROPERTY_ID);
+    PROPERTY_IDS.add(STACK_MIN_VERSION_PROPERTY_ID);
+    PROPERTY_IDS.add(STACK_ACTIVE_PROPERTY_ID);
+    PROPERTY_IDS.add(STACK_VALID_PROPERTY_ID);
+    PROPERTY_IDS.add(STACK_ERROR_SET);
+    PROPERTY_IDS.add(STACK_CONFIG_TYPES);
+    PROPERTY_IDS.add(STACK_PARENT_PROPERTY_ID);
+    PROPERTY_IDS.add(UPGRADE_PACKS_PROPERTY_ID);
+    PROPERTY_IDS.add(STACK_MIN_JDK);
+    PROPERTY_IDS.add(STACK_MAX_JDK);
+
+    // keys
+    KEY_PROPERTY_IDS.put(Resource.Type.Mpack, MPACK_ID);
+    KEY_PROPERTY_IDS.put(Resource.Type.Stack, STACK_NAME_PROPERTY_ID);
+    KEY_PROPERTY_IDS.put(Resource.Type.StackVersion, STACK_VERSION_PROPERTY_ID);
 
-  /**
-   * The property ids for a StackVersion resource.
-   */
-  protected static Set<String> propertyIds = Sets.newHashSet(
-      STACK_VERSION_PROPERTY_ID,
-      STACK_NAME_PROPERTY_ID,
-      STACK_MIN_VERSION_PROPERTY_ID,
-      STACK_ACTIVE_PROPERTY_ID,
-      STACK_VALID_PROPERTY_ID,
-      STACK_ERROR_SET,
-      STACK_CONFIG_TYPES,
-      STACK_PARENT_PROPERTY_ID,
-      UPGRADE_PACKS_PROPERTY_ID,
-      STACK_MIN_JDK,
-      STACK_MAX_JDK);
-
-  protected StackVersionResourceProvider(AmbariManagementController managementController) {
-    super(Type.StackVersion, propertyIds, keyPropertyIds, managementController);
   }
 
+  StackVersionResourceProvider(AmbariManagementController controller) {
+    super(Resource.Type.StackVersion, PROPERTY_IDS, KEY_PROPERTY_IDS, controller);
+  }
+
+
   @Override
   public Set<Resource> getResources(Request request, Predicate predicate)
       throws SystemException, UnsupportedPropertyException,
       NoSuchResourceException, NoSuchParentResourceException {
 
     final Set<StackVersionRequest> requests = new HashSet<>();
+    Set<Resource> resources = new HashSet<>();
 
     if (predicate == null) {
       requests.add(getRequest(Collections.emptyMap()));
     } else {
-      for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
-        requests.add(getRequest(propertyMap));
-      }
-    }
+      Map<String, Object> propertyMap = new HashMap<>(PredicateHelper.getProperties(predicate));
+      if (propertyMap.containsKey(MPACK_ID)) {
+        Resource resource = new ResourceImpl(Resource.Type.StackVersion);
+        Long mpackId = Long.valueOf((String) propertyMap.get(MPACK_ID));
+        StackEntity stackEntity = stackDAO.findByMpack(mpackId);
+        requests.add(new StackVersionRequest(stackEntity.getStackName(), stackEntity.getStackVersion()));
+        resource.setProperty(STACK_NAME_PROPERTY_ID,
+                (String)stackEntity.getStackName());
+
+        resource.setProperty(STACK_VERSION_PROPERTY_ID,
+                (String)stackEntity.getStackVersion());
+
+        resource.setProperty(MPACK_ID, mpackId);
+
+        resources.add(resource);
+
+      } else {
+        for (Map<String, Object> propertyMap1:
+             getPropertyMaps(predicate)) {
+          requests.add(getRequest(propertyMap1));
+        }
 
     Set<String> requestedIds = getRequestPropertyIds(request, predicate);
 
@@ -109,7 +148,6 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
       }
     });
 
-    Set<Resource> resources = new HashSet<>();
 
     for (StackVersionResponse response : responses) {
       Resource resource = new ResourceImpl(Resource.Type.StackVersion);
@@ -128,16 +166,16 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
 
       setResourceProperty(resource, STACK_VALID_PROPERTY_ID,
           response.isValid(), requestedIds);
-      
+
       setResourceProperty(resource, STACK_ERROR_SET,
           response.getErrors(), requestedIds);
-      
+
       setResourceProperty(resource, STACK_PARENT_PROPERTY_ID,
         response.getParentVersion(), requestedIds);
 
       setResourceProperty(resource, STACK_CONFIG_TYPES,
           response.getConfigTypes(), requestedIds);
-      
+
       setResourceProperty(resource, UPGRADE_PACKS_PROPERTY_ID,
           response.getUpgradePacks(), requestedIds);
 
@@ -147,11 +185,13 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
       setResourceProperty(resource, STACK_MAX_JDK,
               response.getMaxJdk(), requestedIds);
 
-      resources.add(resource);
+        resources.add(resource);
+      }
+      }
     }
 
-    return resources;
-  }
+      return resources;
+    }
 
   private StackVersionRequest getRequest(Map<String, Object> properties) {
     return new StackVersionRequest(
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
index 5ae7e1d..6b19b3c 100644
--- 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
@@ -273,7 +273,7 @@ public class MpackManager {
           serviceTargetDir.toPath(), StandardCopyOption.REPLACE_EXISTING);
       }
     }
-  
+
 
   /**
    * Reads the mpack.json file within the {mpack-name}.tar.gz file and populates Mpack object.


[ambari] 05/20: AMBARI-21523: DELETE Api for Mpacks (mradhakrishnan)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit ab5721cc761c2992c8c238d20b3b48b60ae8437e
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Tue Jul 25 10:10:50 2017 -0700

    AMBARI-21523: DELETE Api for Mpacks  (mradhakrishnan)
---
 .../ambari/server/api/services/AmbariMetaInfo.java | 18 +++++++
 .../ambari/server/api/services/MpacksService.java  | 23 ++++++++
 .../controller/AmbariManagementController.java     | 10 ++++
 .../controller/AmbariManagementControllerImpl.java | 18 ++++++-
 .../AbstractControllerResourceProvider.java        |  2 +
 .../internal/AbstractResourceProvider.java         |  2 +-
 .../controller/internal/MpackResourceProvider.java | 61 ++++++++++++++++++++--
 .../apache/ambari/server/mpack/MpackManager.java   | 45 +++++++++++++++-
 .../org/apache/ambari/server/orm/dao/MpackDAO.java |  4 ++
 .../org/apache/ambari/server/orm/dao/StackDAO.java | 25 +++++++++
 .../ambari/server/orm/entities/StackEntity.java    |  1 +
 .../apache/ambari/server/stack/StackManager.java   |  5 ++
 12 files changed, 207 insertions(+), 7 deletions(-)

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 ea0c68b..1ea5369 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
@@ -61,6 +61,9 @@ import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
 import org.apache.ambari.server.orm.dao.MetainfoDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
+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.stack.upgrade.ConfigUpgradePack;
@@ -1541,4 +1544,19 @@ public class AmbariMetaInfo {
     return commonWidgetsDescriptorFile;
   }
 
+  /***
+   * Remove Mpack from the mpackMap and stackMap which is used to power the Mpack and Stack APIs.
+   * Stack should be removed from stackMap only if it points to the mpack that is being removed.
+   * @param mpackEntity
+   * @param stackEntity
+   * @throws IOException
+   */
+  public void removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException {
+
+    boolean stackDelete = mpackManager.removeMpack(mpackEntity, stackEntity);
+
+    if(stackDelete) {
+      stackManager.removeStack(stackEntity);
+    }
+  }
 }
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
index 32dae0f..c69ed01 100644
--- 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
@@ -19,7 +19,10 @@ package org.apache.ambari.server.api.services;
 
 import org.apache.ambari.server.api.resources.ResourceInstance;
 
+
 import org.apache.ambari.server.controller.spi.Resource;
+
+import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
@@ -154,6 +157,26 @@ public class MpacksService extends BaseService {
             createMpackResource(mpackId));
   }
 
+  @DELETE
+  @Path("{mpack_id}")
+  @Produces(MediaType.TEXT_PLAIN)
+  @ApiOperation(value = "Deletes a selected management pack")
+  @ApiImplicitParams({
+    @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, dataType = DATA_TYPE_STRING,
+                  paramType = PARAM_TYPE_QUERY, defaultValue = MpackResourceProvider.ALL_PROPERTIES),
+  })
+  @ApiResponses({
+          @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+          @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_CLUSTER_OR_HOST_NOT_FOUND),
+          @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+          @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+          @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+  })
+  public Response deleteMpack(String body, @Context HttpHeaders headers, @Context UriInfo ui, @PathParam("mpack_id") String mpackId) {
+    return handleRequest(headers, body, ui, Request.Type.DELETE,
+            createMpackResource(mpackId));
+  }
+
   /**
    * Create an mpack resource instance
    * @param mpackId
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 74a75b5..78f5f94 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
@@ -45,6 +45,8 @@ import org.apache.ambari.server.events.TopologyUpdateEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.metadata.RoleCommandOrder;
 import org.apache.ambari.server.orm.entities.ExtensionLinkEntity;
+import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.scheduler.ExecutionScheduleManager;
 import org.apache.ambari.server.security.authorization.AuthorizationException;
 import org.apache.ambari.server.security.encryption.CredentialStoreService;
@@ -974,5 +976,13 @@ public interface AmbariManagementController {
    */
   ArrayList<Packlet> getPacklets(Long mpackId);
 
+  /***
+   * Remove Mpack from the mpackMap and stackMap which is used to power the Mpack and Stack APIs.
+   * @param mpackEntity
+   * @param stackEntity
+   * @throws IOException
+   */
+  void removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException;
+
 }
 
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 9632d47..6d4d090 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
@@ -159,9 +159,11 @@ import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.HostEntity;
 import org.apache.ambari.server.orm.entities.RepoDefinitionEntity;
 import org.apache.ambari.server.orm.entities.RepoOsEntity;
+import org.apache.ambari.server.orm.entities.MpackEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.SettingEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.orm.entities.WidgetEntity;
 import org.apache.ambari.server.orm.entities.WidgetLayoutEntity;
 import org.apache.ambari.server.orm.entities.WidgetLayoutUserWidgetEntity;
@@ -591,7 +593,12 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     createHostComponents(requests, false);
   }
 
-  public MpackResponse registerMpack(MpackRequest request) throws IOException, AuthorizationException, ResourceAlreadyExistsException{
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public MpackResponse registerMpack(MpackRequest request)
+    throws IOException, AuthorizationException, ResourceAlreadyExistsException{
     MpackResponse mpackResponse = ambariMetaInfo.registerMpack(request);
     updateStacks();
     return mpackResponse;
@@ -3806,6 +3813,15 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
   }
 
   /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException{
+
+    ambariMetaInfo.removeMpack(mpackEntity, stackEntity);
+  }
+
+  /**
    * Get a request response for the given request ids.  Note that this method
    * fully populates a request resource including the set of task sub-resources
    * in the request response.
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index 06dbc7b..2ec5b77 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -64,6 +64,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractAuthori
     this.managementController = managementController;
   }
 
+
+
   public static void init(ResourceProviderFactory factory) {
     resourceProviderFactory = factory;
   }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
index 40e1b2d..21a70ca 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
@@ -68,7 +68,7 @@ public abstract class AbstractResourceProvider extends BaseProvider implements R
    */
   private final Set<ResourceProviderObserver> observers = new HashSet<>();
 
-  private static final Logger LOG = LoggerFactory.getLogger(AbstractResourceProvider.class);
+  protected static final Logger LOG = LoggerFactory.getLogger(AbstractResourceProvider.class);
   protected final static String PROPERTIES_ATTRIBUTES_REGEX = "properties_attributes/[a-zA-Z][a-zA-Z._-]*$";
   public static Pattern propertiesAttributesPattern = Pattern.compile(".*/" + PROPERTIES_ATTRIBUTES_REGEX);
 
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
index f939da7..7366390 100644
--- 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
@@ -29,6 +29,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import com.google.inject.Inject;
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.StaticallyInject;
 import org.apache.ambari.server.api.services.parsers.BodyParseException;
 import org.apache.ambari.server.controller.spi.RequestStatus;
@@ -106,7 +107,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
   }
 
   MpackResourceProvider(AmbariManagementController controller) {
-    super(PROPERTY_IDS, KEY_PROPERTY_IDS, controller);
+    super(Resource.Type.Mpack, PROPERTY_IDS, KEY_PROPERTY_IDS, controller);
   }
 
   @Override
@@ -187,8 +188,8 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         resource.setProperty(REGISTRY_ID, entity.getRegistryId());
         results.add(resource);
       }
-    } //Fetch a particular mpack based on id
-    else {
+    } else {
+      // Fetch a particular mpack based on id
       Map<String, Object> propertyMap = new HashMap<>(PredicateHelper.getProperties(predicate));
       if (propertyMap.containsKey(STACK_NAME_PROPERTY_ID) && propertyMap.containsKey(STACK_VERSION_PROPERTY_ID)) {
         String stackName = (String) propertyMap.get(STACK_NAME_PROPERTY_ID);
@@ -237,5 +238,59 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     return results;
   }
 
+  @Override
+  protected RequestStatus deleteResourcesAuthorized(final Request request, Predicate predicate)
+          throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+    final Long mpackId;
+    Map<String, Object> propertyMap = new HashMap<>(PredicateHelper.getProperties(predicate));
+    DeleteStatusMetaData deleteStatusMetaData = null;
+
+    //Allow deleting mpack only if there are no cluster services deploying using this mpack. Support deleting mpacks only if no cluster has been deployed
+    // (i.e. you should be able to delete an mpack during install wizard only).
+    //Todo : Relax the rule
+    if (getManagementController().getClusters().getClusters().size() > 0) {
+      throw new SystemException("Delete request cannot be completed since there is a cluster deployed");
+    } else {
+      if (propertyMap.containsKey(MPACK_ID)) {
+        Object objMpackId = propertyMap.get(MPACK_ID);
+        if (objMpackId != null) {
+          mpackId = Long.valueOf((String) objMpackId);
+          LOG.info("Deleting Mpack, id = " + mpackId.toString());
+
+          MpackEntity mpackEntity = mpackDAO.findById(mpackId);
+          StackEntity stackEntity = stackDAO.findByMpack(mpackId);
+          try {
+            getManagementController().removeMpack(mpackEntity, stackEntity);
+            if (mpackEntity != null) {
+              deleteStatusMetaData = modifyResources(new Command<DeleteStatusMetaData>() {
+                @Override
+                public DeleteStatusMetaData invoke() throws AmbariException {
+                  if (stackEntity != null) {
+                    stackDAO.removeByMpack(mpackId);
+                    notifyDelete(Resource.Type.Stack, predicate);
+                  }
+                  mpackDAO.removeById(mpackId);
+
+                  return new DeleteStatusMetaData();
+                }
+              });
+              notifyDelete(Resource.Type.Mpack, predicate);
+              deleteStatusMetaData.addDeletedKey(mpackId.toString());
+            } else {
+              throw new NoSuchResourceException("The requested resource doesn't exist: " + predicate);
+            }
+          } catch (IOException e) {
+            throw new SystemException("There is an issue with the Files");
+          }
+        }
+      } else {
+        throw new UnsupportedPropertyException(Resource.Type.Mpack, null);
+      }
+
+      return getRequestStatus(null, null, deleteStatusMetaData);
+    }
+  }
+
 }
 
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
index f19320e..619823c 100644
--- 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
@@ -32,6 +32,7 @@ import org.apache.ambari.server.state.Packlet;
 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -328,8 +329,8 @@ public class MpackManager {
       MpackEntity mpackEntity = new MpackEntity();
       mpackEntity.setMpackName(mpackName);
       mpackEntity.setMpackVersion(mpackVersion);
-      mpackEntity.setMpackUri(mpacks.getMpacksUri());
-
+      mpackEntity.setMpackUri(mpack.getMpacksUri());
+      mpackEntity.setRegistryId(mpack.getRegistryId());
       Long mpackId = mpackDAO.create(mpackEntity);
       return mpackId;
     }
@@ -375,4 +376,44 @@ public class MpackManager {
       return mpack.getPacklets();
     return null;
   }
+
+  /***
+   * Remove the mpack and stack directories when a request comes in to delete a particular mpack.
+   * @param mpackEntity
+   * @throws IOException
+   */
+  public boolean removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException {
+
+    boolean stackDelete = false;
+    File mpackDirToDelete = new File(mpackStaging + File.separator + mpackEntity.getMpackName() + File.separator + mpackEntity.getMpackVersion());
+    File mpackDirectory = new File(mpackStaging + "/" + mpackEntity.getMpackName());
+    String mpackName = mpackEntity.getMpackName() + "-" + mpackEntity.getMpackVersion() + ".tar.gz";
+    Path mpackTarFile = Paths.get(mpackStaging + File.separator + MPACK_TAR_LOCATION +File.separator + mpackName);
+
+    mpackMap.remove(mpackEntity.getMpackId());
+    FileUtils.deleteDirectory(mpackDirToDelete);
+
+    if (mpackDirectory.isDirectory()) {
+      if (mpackDirectory.list().length == 0) {
+        Files.delete(mpackDirectory.toPath());
+      }
+    }
+    if (stackEntity != null) {
+      Path stackPath = Paths.get(stackRoot + "/" + stackEntity.getStackName() + "/" + stackEntity.getStackVersion());
+      File stackDirectory = new File(stackRoot + "/" + stackEntity.getStackName());
+      if (!Files.exists(stackPath))
+        Files.delete(stackPath);
+      if (stackDirectory.isDirectory()) {
+        if (stackDirectory.list().length == 0) {
+          Files.delete(stackDirectory.toPath());
+        }
+      }
+      stackDelete = true;
+    }
+
+    if (Files.exists(mpackTarFile)){
+      Files.delete(mpackTarFile);
+    }
+    return stackDelete;
+  }
 }
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
index a19ceaf..fb4e101 100644
--- 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
@@ -95,5 +95,9 @@ public class MpackDAO {
     return m_daoUtils.selectList(query);
   }
 
+  @Transactional
+  public void removeById(Long mpackId) {
+    m_entityManagerProvider.get().remove(findById(mpackId));
+  }
 
 }
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
index f7c5dbe..57327c6 100644
--- 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
@@ -175,4 +175,29 @@ public class StackDAO {
       entityManager.remove(stack);
     }
   }
+
+  /**
+   * Removes the specified stack based on mpackid.
+   *
+   * @param mpackId
+   *
+   */
+  @Transactional
+  public void removeByMpack(Long mpackId) {
+    entityManagerProvider.get().remove(findByMpack(mpackId));
+  }
+
+  /**
+   * Gets the stack that matches the specified mpackid.
+   *
+   * @return the stack matching the specified mpackid or {@code null}
+   *         if none.
+   */
+  public StackEntity findByMpack(Long mpackId) {
+    TypedQuery<StackEntity> query = entityManagerProvider.get().createNamedQuery(
+            "StackEntity.findByMpack", StackEntity.class);
+    query.setParameter("currentMpackId", mpackId);
+
+    return daoUtils.selectOne(query);
+  }
 }
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
index 0cb8628..bee53b6 100644
--- 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
@@ -40,6 +40,7 @@ import javax.persistence.UniqueConstraint;
 @TableGenerator(name = "stack_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "stack_id_seq", initialValue = 0)
 @NamedQueries({
     @NamedQuery(name = "StackEntity.findAll", query = "SELECT stack FROM StackEntity stack"),
+    @NamedQuery(name = "StackEntity.findByMpack", query = "SELECT stack FROM StackEntity stack where stack.currentMpackId = :currentMpackId"),
     @NamedQuery(name = "StackEntity.findByNameAndVersion", query = "SELECT stack FROM StackEntity stack WHERE stack.stackName = :stackName AND stack.stackVersion = :stackVersion",
                 hints = {
                   @QueryHint(name = "eclipselink.query-results-cache", value = "true"),
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 fbd0d8c..ca3ff30 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
@@ -677,4 +677,9 @@ public class StackManager {
     }
     return extensionModules;
   }
+
+  public void removeStack(StackEntity stackEntity) {
+    String stackKey = stackEntity.getStackName() + StackManager.PATH_DELIMITER +  stackEntity.getStackVersion();
+    stackMap.remove(stackKey);
+  }
 }


[ambari] 12/20: AMBARI-22283 : Add stack name and version to mpack API (mradhakrishnan)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 562e52bde1d7a85acec5be10eb4419997fa42e76
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Tue Oct 24 14:44:07 2017 -0700

    AMBARI-22283 : Add stack name and version to mpack API (mradhakrishnan)
---
 .../server/api/resources/StackVersionResourceDefinition.java   |  1 +
 .../server/controller/internal/MpackResourceProvider.java      | 10 ----------
 .../controller/internal/StackVersionResourceProvider.java      |  5 +----
 3 files changed, 2 insertions(+), 14 deletions(-)

diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
index b0786e1..d621210 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
@@ -23,6 +23,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+
 import org.apache.ambari.server.api.services.Request;
 import org.apache.ambari.server.api.util.TreeNode;
 import org.apache.ambari.server.controller.internal.ResourceImpl;
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
index 8e1dbf5..11fe3a8 100644
--- 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
@@ -142,16 +142,12 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
       MpackResponse response = getManagementController().registerMpack(mpackRequest);
       if (response != null) {
         notifyCreate(Resource.Type.Mpack, request);
-        String[] stackNameVersion = response.getStackId().split("-");
         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_URI, response.getMpackUri());
-        resource.setProperty(STACK_NAME_PROPERTY_ID, stackNameVersion[0]);
-        resource.setProperty(STACK_VERSION_PROPERTY_ID, stackNameVersion[1]);
-
         associatedResources.add(resource);
         return getRequestStatus(null, associatedResources);
       }
@@ -236,9 +232,6 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         resource.setProperty(MPACK_VERSION, entity.getMpackVersion());
         resource.setProperty(MPACK_URI, entity.getMpackUri());
         resource.setProperty(REGISTRY_ID, entity.getRegistryId());
-        StackEntity stackEntity = stackDAO.findByMpack(entity.getMpackId());
-        resource.setProperty(STACK_NAME_PROPERTY_ID, stackEntity.getStackName());
-        resource.setProperty(STACK_VERSION_PROPERTY_ID, stackEntity.getStackVersion());
         results.add(resource);
       }
     } else {
@@ -277,9 +270,6 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
           resource.setProperty(MPACK_VERSION, entity.getMpackVersion());
           resource.setProperty(MPACK_URI, entity.getMpackUri());
           resource.setProperty(REGISTRY_ID, entity.getRegistryId());
-          StackEntity stackEntity = stackDAO.findByMpack(entity.getMpackId());
-          resource.setProperty(STACK_NAME_PROPERTY_ID, stackEntity.getStackName());
-          resource.setProperty(STACK_VERSION_PROPERTY_ID, stackEntity.getStackVersion());
           List<Packlet> packlets = getManagementController().getPacklets(entity.getMpackId());
           resource.setProperty(PACKLETS, packlets);
           results.add(resource);
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
index 86a994a..d1e8a42 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
@@ -45,9 +45,6 @@ import org.apache.ambari.server.orm.entities.StackEntity;
 
 import com.google.inject.Inject;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Sets;
-
 @StaticallyInject
 public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
   public static final String RESPONSE_KEY = "Versions";
@@ -70,7 +67,6 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
   @Inject
   protected static StackDAO stackDAO;
 
-
   private static Set<String> pkPropertyIds = new HashSet<>(
     Arrays.asList(new String[]{STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID, MPACK_ID}));
 
@@ -103,6 +99,7 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
 
   StackVersionResourceProvider(AmbariManagementController controller) {
     super(Resource.Type.StackVersion, PROPERTY_IDS, KEY_PROPERTY_IDS, controller);
+
   }
 
 


[ambari] 19/20: [AMBARI-23223] Review comments

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit fab74c2c5410aea5985e34b24155a9e75d5f80b8
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Fri Mar 16 12:34:16 2018 -0700

    [AMBARI-23223] Review comments
---
 .../controller/internal/MpackResourceProvider.java | 45 +++++++++-------------
 1 file changed, 19 insertions(+), 26 deletions(-)

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
index 110e0a2..ba52639 100644
--- 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
@@ -235,17 +235,9 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
       if (null == responses) {
         responses = Collections.emptySet();
       }
-      for (MpackResponse response : responses){
-        Resource resource = new ResourceImpl(Resource.Type.Mpack);
-        resource.setProperty(MPACK_RESOURCE_ID, response.getId());
-        resource.setProperty(MPACK_ID, response.getMpackId());
-        resource.setProperty(MPACK_NAME, response.getMpackName());
-        resource.setProperty(MPACK_VERSION, response.getMpackVersion());
-        resource.setProperty(MPACK_URI, response.getMpackUri());
-        resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
-        resource.setProperty(REGISTRY_ID, response.getRegistryId());
-        resource.setProperty(MPACK_DISPLAY_NAME, response.getDisplayName());
 
+      for (MpackResponse response : responses) {
+        Resource resource = setResources(response);
         results.add(resource);
       }
     } else {
@@ -257,15 +249,9 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
           mpackId = Long.valueOf((String) objMpackId);
         }
         MpackResponse response = getManagementController().getMpack(mpackId);
-        Resource resource = new ResourceImpl(Resource.Type.Mpack);
+
         if (null != response) {
-          resource.setProperty(MPACK_RESOURCE_ID, response.getId());
-          resource.setProperty(MPACK_ID, response.getMpackId());
-          resource.setProperty(MPACK_NAME, response.getMpackName());
-          resource.setProperty(MPACK_VERSION, response.getMpackVersion());
-          resource.setProperty(MPACK_URI, response.getMpackUri());
-          resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
-          resource.setProperty(REGISTRY_ID, response.getRegistryId());
+          Resource resource = setResources(response);
           List<Module> modules = getManagementController().getModules(response.getId());
           resource.setProperty(MODULES, modules);
           results.add(resource);
@@ -278,15 +264,9 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
         mpackId = stackEntity.getMpackId();
         MpackResponse response = getManagementController().getMpack(mpackId);
-        Resource resource = new ResourceImpl(Resource.Type.Mpack);
+
         if (null != response) {
-          resource.setProperty(MPACK_RESOURCE_ID, response.getId());
-          resource.setProperty(MPACK_ID, response.getMpackId());
-          resource.setProperty(MPACK_NAME, response.getMpackName());
-          resource.setProperty(MPACK_VERSION, response.getMpackVersion());
-          resource.setProperty(MPACK_URI, response.getMpackUri());
-          resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
-          resource.setProperty(REGISTRY_ID, response.getRegistryId());
+          Resource resource = setResources(response);
           resource.setProperty(STACK_NAME_PROPERTY_ID, stackName);
           resource.setProperty(STACK_VERSION_PROPERTY_ID, stackVersion);
           results.add(resource);
@@ -324,6 +304,19 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     return results;
   }
 
+  private Resource setResources(MpackResponse response) {
+    Resource resource = new ResourceImpl(Resource.Type.Mpack);
+    resource.setProperty(MPACK_RESOURCE_ID, response.getId());
+    resource.setProperty(MPACK_ID, response.getMpackId());
+    resource.setProperty(MPACK_NAME, response.getMpackName());
+    resource.setProperty(MPACK_VERSION, response.getMpackVersion());
+    resource.setProperty(MPACK_URI, response.getMpackUri());
+    resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
+    resource.setProperty(REGISTRY_ID, response.getRegistryId());
+    resource.setProperty(MPACK_DISPLAY_NAME, response.getDisplayName());
+    return resource;
+  }
+
   @Override
   protected RequestStatus deleteResourcesAuthorized(final Request request, Predicate predicate)
     throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {


[ambari] 14/20: AMBARI-22971: Remove current_mpack_id to mpack_id in stacks table (jluniya)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 29aa64d6ea9015a395a4410cf90f445c79dd7d45
Author: Jayush Luniya <jl...@hortonworks.com>
AuthorDate: Mon Feb 12 18:04:08 2018 -0800

    AMBARI-22971: Remove current_mpack_id to mpack_id in stacks table (jluniya)
---
 .../api/resources/MpackResourceDefinition.java     |  4 +-
 .../resources/StackVersionResourceDefinition.java  |  3 +-
 .../controller/internal/MpackResourceProvider.java |  2 +-
 .../apache/ambari/server/mpack/MpackManager.java   |  9 ++-
 .../org/apache/ambari/server/orm/dao/StackDAO.java |  2 +-
 .../ambari/server/orm/entities/StackEntity.java    | 18 +++---
 .../src/main/resources/Ambari-DDL-Derby-CREATE.sql |  4 +-
 .../src/main/resources/Ambari-DDL-MySQL-CREATE.sql |  4 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql    |  4 +-
 .../main/resources/Ambari-DDL-Postgres-CREATE.sql  |  4 +-
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql    |  4 +-
 .../main/resources/Ambari-DDL-SQLServer-CREATE.sql | 69 +++++++++++++++++++++-
 12 files changed, 96 insertions(+), 31 deletions(-)

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
index 167e773..c9560ab 100644
--- 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
@@ -96,13 +96,13 @@ public class MpackResourceDefinition extends BaseResourceDefinition {
   }
 
   /***
-   * Post processing to change the name of the result node to current_mpack
+   * Post processing to change the name of the result node to mpack
    */
   private class MpackPostProcessor implements PostProcessor {
     @Override
     public void process(Request request, TreeNode<Resource> resultNode, String href) {
       if (href.contains("/stacks/")) {
-        resultNode.setName("current_mpack");
+        resultNode.setName("mpack");
 
       }
     }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
index d621210..0e2026a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
@@ -92,14 +92,13 @@ public class StackVersionResourceDefinition extends BaseResourceDefinition {
   }
 
   /***
-   * Post processing to change the name of the result node to current_mpack
+   * Post processing to change the name of the result node to stack
    */
   private class StackVersionPostProcessor implements PostProcessor {
     @Override
     public void process(Request request, TreeNode<Resource> resultNode, String href) {
       if (href.contains("/mpacks/")) {
         resultNode.setName("stack");
-
       }
     }
   }
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
index adae593..3771258 100644
--- 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
@@ -246,7 +246,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         String stackName = (String) propertyMap.get(STACK_NAME_PROPERTY_ID);
         String stackVersion = (String) propertyMap.get(STACK_VERSION_PROPERTY_ID);
         StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
-        mpackId = stackEntity.getCurrentMpackId();
+        mpackId = stackEntity.getMpackId();
         if (mpackId != null) {
           MpackResponse response = getManagementController().getMpack(mpackId);
           Resource resource = new ResourceImpl(Resource.Type.Mpack);
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
index 8a1604c..69495d2 100644
--- 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
@@ -547,11 +547,14 @@ public class MpackManager {
       stackEntity = new StackEntity();
       stackEntity.setStackName(stackName);
       stackEntity.setStackVersion(stackVersion);
-      stackEntity.setCurrentMpackId(mpacks.getMpackId());
+
+      stackEntity.setMpackId(mpack.getMpackId());
       stackDAO.create(stackEntity);
     } else {
-      LOG.info("Updating stack {}-{} to the database", stackName, stackVersion);
-      stackEntity.setCurrentMpackId(mpacks.getMpackId());
+      LOG.error("Updating stack {}-{} to the database", stackName, stackVersion);
+
+      stackEntity.setMpackId(mpack.getMpackId());
+
       stackDAO.merge(stackEntity);
     }
   }
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
index 57327c6..559f47c 100644
--- 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
@@ -196,7 +196,7 @@ public class StackDAO {
   public StackEntity findByMpack(Long mpackId) {
     TypedQuery<StackEntity> query = entityManagerProvider.get().createNamedQuery(
             "StackEntity.findByMpack", StackEntity.class);
-    query.setParameter("currentMpackId", mpackId);
+    query.setParameter("mpackId", mpackId);
 
     return daoUtils.selectOne(query);
   }
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
index bee53b6..a2a5698 100644
--- 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
@@ -40,7 +40,7 @@ import javax.persistence.UniqueConstraint;
 @TableGenerator(name = "stack_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "stack_id_seq", initialValue = 0)
 @NamedQueries({
     @NamedQuery(name = "StackEntity.findAll", query = "SELECT stack FROM StackEntity stack"),
-    @NamedQuery(name = "StackEntity.findByMpack", query = "SELECT stack FROM StackEntity stack where stack.currentMpackId = :currentMpackId"),
+    @NamedQuery(name = "StackEntity.findByMpack", query = "SELECT stack FROM StackEntity stack where stack.mpackId = :mpackId"),
     @NamedQuery(name = "StackEntity.findByNameAndVersion", query = "SELECT stack FROM StackEntity stack WHERE stack.stackName = :stackName AND stack.stackVersion = :stackVersion",
                 hints = {
                   @QueryHint(name = "eclipselink.query-results-cache", value = "true"),
@@ -60,17 +60,15 @@ public class StackEntity {
   @Column(name = "stack_version", length = 255, nullable = false)
   private String stackVersion;
 
+  @Column(name = "mpack_id")
+  private Long mpackId;
 
-  @Column(name = "current_mpack_id")
-  private Long currentMpackId;
-
-
-  public Long getCurrentMpackId() {
-    return currentMpackId;
+  public Long getMpackId() {
+    return mpackId;
   }
 
-  public void setCurrentMpackId(Long currentMpackId) {
-    this.currentMpackId = currentMpackId;
+  public void setMpackId(Long mpackId) {
+    this.mpackId = mpackId;
   }
 
 
@@ -169,7 +167,7 @@ public class StackEntity {
     buffer.append("id=").append(stackId);
     buffer.append(", name=").append(stackName);
     buffer.append(", version=").append(stackVersion);
-    buffer.append(", current_mpack_id=").append(currentMpackId);
+    buffer.append(", mpack_id=").append(mpackId);
     buffer.append("}");
     return buffer.toString();
   }
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 bef2c1c..c8c69de 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -38,9 +38,9 @@ CREATE TABLE stack(
   stack_id BIGINT NOT NULL,
   stack_name VARCHAR(255) NOT NULL,
   stack_version VARCHAR(255) NOT NULL,
-  current_mpack_id BIGINT,
+  mpack_id BIGINT,
   CONSTRAINT PK_stack PRIMARY KEY (stack_id),
-  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
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 f24844e..7cd756b 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -57,9 +57,9 @@ CREATE TABLE stack(
   stack_id BIGINT NOT NULL,
   stack_name VARCHAR(100) NOT NULL,
   stack_version VARCHAR(100) NOT NULL,
-  current_mpack_id BIGINT,
+  mpack_id BIGINT,
   CONSTRAINT PK_stack PRIMARY KEY (stack_id),
-  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
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 7c8ca77..e752744 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -38,9 +38,9 @@ CREATE TABLE stack(
   stack_id NUMBER(19) NOT NULL,
   stack_name VARCHAR2(255) NOT NULL,
   stack_version VARCHAR2(255) NOT NULL,
-  current_mpack_id BIGINT,
+  mpack_id NUMBER(19),
   CONSTRAINT PK_stack PRIMARY KEY (stack_id),
-  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
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 a6efcbc..190b307 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -38,9 +38,9 @@ CREATE TABLE stack(
   stack_id BIGINT NOT NULL,
   stack_name VARCHAR(255) NOT NULL,
   stack_version VARCHAR(255) NOT NULL,
-  current_mpack_id BIGINT,
+  mpack_id BIGINT,
   CONSTRAINT PK_stack PRIMARY KEY (stack_id),
-  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
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 76fa36c..8ba40b4 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -37,9 +37,9 @@ CREATE TABLE stack(
   stack_id NUMERIC(19) NOT NULL,
   stack_name VARCHAR(255) NOT NULL,
   stack_version VARCHAR(255) NOT NULL,
-  current_mpack_id BIGINT,
+  mpack_id BIGINT,
   CONSTRAINT PK_stack PRIMARY KEY (stack_id),
-  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
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 0ce1cde..975e762 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -50,9 +50,9 @@ CREATE TABLE stack(
   stack_id BIGINT NOT NULL,
   stack_name VARCHAR(255) NOT NULL,
   stack_version VARCHAR(255) NOT NULL,
-  current_mpack_id BIGINT,
+  mpack_id BIGINT,
   CONSTRAINT PK_stack PRIMARY KEY CLUSTERED (stack_id),
-  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
@@ -97,6 +97,71 @@ CREATE TABLE clusters (
   CONSTRAINT FK_clusters_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES stack(stack_id),
   CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES adminresource(resource_id));
 
+CREATE TABLE ambari_configuration (
+  category_name VARCHAR(100) NOT NULL,
+  property_name VARCHAR(100) NOT NULL,
+  property_value VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (category_name, property_name)
+);
+
+CREATE TABLE hosts (
+  host_id BIGINT NOT NULL,
+  host_name VARCHAR(255) NOT NULL,
+  cpu_count INTEGER NOT NULL,
+  ph_cpu_count INTEGER,
+  cpu_info VARCHAR(255) NOT NULL,
+  discovery_status VARCHAR(2000) NOT NULL,
+  host_attributes VARCHAR(MAX) NOT NULL,
+  ipv4 VARCHAR(255),
+  ipv6 VARCHAR(255),
+  public_host_name VARCHAR(255),
+  last_registration_time BIGINT NOT NULL,
+  os_arch VARCHAR(255) NOT NULL,
+  os_info VARCHAR(1000) NOT NULL,
+  os_type VARCHAR(255) NOT NULL,
+  rack_info VARCHAR(255) NOT NULL,
+  total_mem BIGINT NOT NULL,
+  CONSTRAINT PK_hosts PRIMARY KEY CLUSTERED (host_id),
+  CONSTRAINT UQ_hosts_host_name UNIQUE (host_name));
+
+CREATE TABLE clustersettings (
+  id BIGINT NOT NULL,
+  setting_name VARCHAR(255) NOT NULL,
+  setting_value VARCHAR(255) NOT NULL,
+  cluster_id BIGINT NOT NULL,
+  CONSTRAINT PK_clustersettings PRIMARY KEY (id),
+  CONSTRAINT FK_clustersettings_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
+
+CREATE TABLE servicegroups (
+  id BIGINT NOT NULL,
+  service_group_name VARCHAR(255) NOT NULL,
+  cluster_id BIGINT NOT NULL,
+  stack_id BIGINT NOT NULL,
+  CONSTRAINT PK_servicegroups PRIMARY KEY (id, cluster_id),
+  CONSTRAINT FK_servicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
+
+CREATE TABLE servicegroupdependencies (
+  id BIGINT NOT NULL,
+  service_group_id BIGINT NOT NULL,
+  service_group_cluster_id BIGINT NOT NULL,
+  dependent_service_group_id BIGINT NOT NULL,
+  dependent_service_group_cluster_id BIGINT NOT NULL,
+  CONSTRAINT PK_servicegroupdependencies PRIMARY KEY (id),
+  CONSTRAINT UQ_servicegroupdependencies UNIQUE (service_group_id, service_group_cluster_id, dependent_service_group_id, dependent_service_group_cluster_id),
+  CONSTRAINT FK_svcgrpdep_svcgrp_cl_id FOREIGN KEY (service_group_id, service_group_cluster_id) REFERENCES servicegroups (id, cluster_id),
+  CONSTRAINT FK_svcgrpdep_dep_svcgrp_cl_id FOREIGN KEY (dependent_service_group_id, dependent_service_group_cluster_id) REFERENCES servicegroups (id, cluster_id));
+
+CREATE TABLE clusterservices (
+  id BIGINT NOT NULL,
+  service_name VARCHAR(255) NOT NULL,
+  service_type VARCHAR(255) NOT NULL,
+  cluster_id BIGINT NOT NULL,
+  service_group_id BIGINT NOT NULL,
+  service_enabled INT NOT NULL,
+  CONSTRAINT PK_clusterservices PRIMARY KEY (id, service_group_id, cluster_id),
+  CONSTRAINT UQ_service_id UNIQUE (id),
+  CONSTRAINT FK_clusterservices_cluster_id FOREIGN KEY (service_group_id, cluster_id) REFERENCES servicegroups (id, cluster_id));
+
 CREATE TABLE clusterconfig (
   config_id BIGINT NOT NULL,
   version_tag VARCHAR(255) NOT NULL,


[ambari] 02/20: AMBARI-21231: Download and extract mpacks. Add unit tests (mradhakrishnan)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit cf2b52a10f0988602cfc331ee5bc2a3f4fab1593
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Wed Jun 21 10:57:53 2017 -0700

    AMBARI-21231: Download and extract mpacks. Add unit tests (mradhakrishnan)
---
 .../ambari/server/controller/MpackRequest.java     |  84 +++++-
 .../ambari/server/controller/MpackResponse.java    |  18 +-
 .../AbstractControllerResourceProvider.java        |   2 +
 .../controller/internal/MpackResourceProvider.java |  22 +-
 .../apache/ambari/server/mpack/MpackManager.java   | 201 ++++++++++-----
 .../org/apache/ambari/server/orm/dao/MpackDAO.java |   2 +-
 .../ambari/server/orm/entities/MpackEntity.java    |  16 +-
 .../org/apache/ambari/server/state/Mpacks.java     | 139 +++++++++-
 .../org/apache/ambari/server/state/Packlet.java    |  75 ++++++
 .../api/resources/MpackResourceDefinitionTest.java |  35 +++
 .../server/api/services/AmbariMetaInfoTest.java    |  71 ++++--
 .../server/api/services/MpackServiceTest.java      |  94 +++++++
 .../server/configuration/ConfigurationTest.java    |  10 +
 .../AmbariManagementControllerImplTest.java        |  70 ++++-
 .../ambari/server/controller/MpackRequestTest.java |  44 ++++
 .../server/controller/MpackResponseTest.java       |  54 ++++
 .../internal/MpackResourceProviderTest.java        | 281 +++++++++++++++++++++
 .../apache/ambari/server/orm/dao/MpackDAOTest.java |  76 ++++++
 .../server/orm/entities/MpackEntityTest.java       |  68 +++++
 .../org/apache/ambari/server/state/MpacksTest.java |  95 +++++++
 20 files changed, 1335 insertions(+), 122 deletions(-)

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
index fa6dd1d..a705d18 100644
--- 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
@@ -26,24 +26,24 @@ import org.apache.ambari.server.orm.entities.MpackEntity;
  */
 public class MpackRequest {
 
-  private String mpackId;
+  private Long mpackId;
   private String mpackName;
   private String mpackVersion;
-  private String mpackUrl;
-  private String registryId;
+  private String mpackUri;
+  private Long registryId;
 
-  public MpackRequest(String mpackId) {
+  public MpackRequest(Long mpackId) {
     this.setMpackId(mpackId);
   }
 
   public MpackRequest() {
   }
 
-  public String getMpackId() {
+  public Long getMpackId() {
     return mpackId;
   }
 
-  public void setMpackId(String mpackId) {
+  public void setMpackId(Long mpackId) {
     this.mpackId = mpackId;
   }
 
@@ -63,20 +63,80 @@ public class MpackRequest {
     this.mpackVersion = mpackVersion;
   }
 
-  public String getMpackUrl() {
-    return mpackUrl;
+  public String getMpackUri() {
+    return mpackUri;
   }
 
-  public void setMpackUrl(String mpackUrl) {
-    this.mpackUrl = mpackUrl;
+  public void setMpackUri(String mpackUri) {
+    this.mpackUri = mpackUri;
   }
 
-  public String getRegistryId() {
+  public Long getRegistryId() {
     return registryId;
   }
 
-  public void setRegistryId(String registryId) {
+  public void setRegistryId(Long registryId) {
     this.registryId = registryId;
   }
 
+  @Override
+  public int hashCode() {
+    int result = 1;
+    result = 31 + getMpackId().hashCode();
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (!(obj instanceof MpackRequest)) {
+      return false;
+    }
+    if (this == obj) {
+      return true;
+    }
+    MpackRequest mpackRequest = (MpackRequest) obj;
+
+    if (mpackId == null) {
+      if (mpackRequest.mpackId != null) {
+        return false;
+      }
+    } else if (!mpackId.equals(mpackRequest.mpackId)) {
+      return false;
+    }
+
+    if (mpackName == null) {
+      if (mpackRequest.mpackName != null) {
+        return false;
+      }
+    } else if (!mpackName.equals(mpackRequest.mpackName)) {
+      return false;
+    }
+
+    if (mpackUri == null) {
+      if (mpackRequest.mpackUri != null) {
+        return false;
+      }
+    } else if (!mpackUri.equals(mpackRequest.mpackUri)) {
+      return false;
+    }
+
+    if (registryId == null) {
+      if (mpackRequest.registryId != null) {
+        return false;
+      }
+    } else if (!registryId.equals(mpackRequest.registryId)) {
+      return false;
+    }
+
+    if (mpackVersion == null) {
+      if (mpackRequest.mpackVersion != null) {
+        return false;
+      }
+    } else if (!mpackVersion.equals(mpackRequest.mpackVersion)) {
+      return false;
+    }
+
+    return true;
+  }
+
 }
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
index d7cca79..05687c2 100644
--- 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
@@ -27,13 +27,13 @@ public class MpackResponse {
   private Long mpackId;
   private String mpackVersion;
   private String mpackName;
-  private String mpackUrl;
-  private String registryId;
+  private String mpackUri;
+  private Long registryId;
 
   public MpackResponse(Mpacks mpacks) {
     this.mpackId = mpacks.getMpackId();
     this.mpackVersion = mpacks.getVersion();
-    this.mpackUrl = mpacks.getMpacksUrl();
+    this.mpackUri = mpacks.getMpacksUri();
     this.mpackName = mpacks.getName();
     this.registryId = mpacks.getRegistryId();
   }
@@ -42,8 +42,8 @@ public class MpackResponse {
     return mpackVersion;
   }
 
-  public String getMpackUrl() {
-    return mpackUrl;
+  public String getMpackUri() {
+    return mpackUri;
   }
 
   public Long getMpackId() {
@@ -54,7 +54,7 @@ public class MpackResponse {
     return mpackName;
   }
 
-  public String getRegistryId() {
+  public Long getRegistryId() {
     return registryId;
   }
 
@@ -66,11 +66,11 @@ public class MpackResponse {
     this.mpackName = mpackName;
   }
 
-  public void setMpackUrl(String mpackUrl) {
-    this.mpackUrl = mpackUrl;
+  public void setMpackUri(String mpackUri) {
+    this.mpackUri = mpackUri;
   }
 
-  public void setRegistryId(String registryId) {
+  public void setRegistryId(Long registryId) {
     this.registryId = registryId;
   }
 
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index 15006b0..06dbc7b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -163,6 +163,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractAuthori
         return resourceProviderFactory.getUpgradeResourceProvider(managementController);
       case Stack:
         return new StackResourceProvider(managementController);
+      case Mpack:
+        return new MpackResourceProvider(managementController);
       case StackVersion:
         return new StackVersionResourceProvider(managementController);
       case ClusterStackVersion:
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
index 7b4682a..65eaeb6 100644
--- 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
@@ -61,7 +61,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
   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 MPACK_URI = "MpackInfo/mpack_uri";
   public static final String PACKLETS = "MpackInfo/packlets";
 
 
@@ -87,7 +87,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     PROPERTY_IDS.add(REGISTRY_ID);
     PROPERTY_IDS.add(MPACK_NAME);
     PROPERTY_IDS.add(MPACK_VERSION);
-    PROPERTY_IDS.add(MPACK_URL);
+    PROPERTY_IDS.add(MPACK_URI);
     PROPERTY_IDS.add(PACKLETS);
 
     // keys
@@ -112,7 +112,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     try {
       MpackRequest mpackRequest = getRequest(request);
       if (mpackRequest == null)
-        throw new BodyParseException("Please provide " + MPACK_NAME + " ," + MPACK_VERSION + " ," + MPACK_URL);
+        throw new BodyParseException("Please provide " + MPACK_NAME + " ," + MPACK_VERSION + " ," + MPACK_URI);
       MpackResponse response = getManagementController().registerMpack(mpackRequest);
       if (response != null) {
         notifyCreate(Resource.Type.Mpack, request);
@@ -121,7 +121,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         resource.setProperty(REGISTRY_ID, response.getRegistryId());
         resource.setProperty(MPACK_NAME, response.getMpackName());
         resource.setProperty(MPACK_VERSION, response.getMpackVersion());
-        resource.setProperty(MPACK_URL, response.getMpackUrl());
+        resource.setProperty(MPACK_URI, response.getMpackUri());
 
         associatedResources.add(resource);
         return getRequestStatus(null, associatedResources);
@@ -139,17 +139,17 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     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))
+      if (!propertyMap.containsKey(MPACK_URI) && !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));
+      else if (!propertyMap.containsKey(MPACK_URI)) {
+        mpackRequest.setRegistryId((Long) 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
+      //Directly download the mpack using the given url
       else
-        mpackRequest.setMpackUrl((String) propertyMap.get(MPACK_URL));
+        mpackRequest.setMpackUri((String) propertyMap.get(MPACK_URI));
     }
     return mpackRequest;
 
@@ -173,7 +173,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         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(MPACK_URI, entity.getMpackUri());
         resource.setProperty(REGISTRY_ID, entity.getRegistryId());
         results.add(resource);
       }
@@ -188,7 +188,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
           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(MPACK_URI, entity.getMpackUri());
           resource.setProperty(REGISTRY_ID, entity.getRegistryId());
 
           ArrayList<Packlet> packletArrayList = getManagementController().getPacklets(entity.getMpackId());
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
index dd4a4b3..a031af3 100644
--- 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
@@ -18,8 +18,6 @@
 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;
@@ -29,19 +27,28 @@ 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.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
+import org.apache.commons.io.IOUtils;
 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.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.Paths;
+import java.util.Map;
 import java.util.HashMap;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
+import java.io.File;
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
 
 
 /**
@@ -52,6 +59,7 @@ public class MpackManager {
   protected Map<Long, Mpacks> mpackMap = new HashMap<>();
   private File mpackStaging;
   private MpackDAO mpackDAO;
+  private Mpacks mpack;
 
   private final static Logger LOG = LoggerFactory.getLogger(MpackManager.class);
 
@@ -73,56 +81,151 @@ public class MpackManager {
    * @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();
+    mpack = new Mpacks();
     String mpackName = "";
     String mpackVersion = "";
     boolean isValidMetadata = true;
+
+    //Mpack registration using a software registry
     if (mpackRequest.getRegistryId() != null) {
       mpackName = mpackRequest.getMpackName();
       mpackVersion = mpackRequest.getMpackVersion();
-      mpacks = parseMpacksJson(mpackName, mpackVersion);
-      mpacks.setRegistryId(mpackRequest.getRegistryId());
+      mpack.setRegistryId(mpackRequest.getRegistryId());
       //Validate the Post request
-      isValidMetadata = validateMpackInfo(mpackName, mpackVersion, mpacks.getName(), mpacks.getVersion());
+      isValidMetadata = validateMpackInfo(mpackName, mpackVersion, mpack.getName(), mpack.getVersion());
+      //Todo : Madhu implement GET /registries/{registryId}/mpacks
     } 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());
+      //Mpack registration using direct download
+      mpack.setMpacksUri(mpackRequest.getMpackUri());
+    }
+
+    //Download the mpack and return the path.
+    Path mpackTarPath = downloadMpack(mpackRequest.getMpackUri(), mpackStaging + File.separator);
+    //create a directory as mpack-staging-path/mpack-name/mpack-version
+    if (createMpackDirectory(mpackTarPath)) {
+      //expand the mpack.tar.gz file inside the directory created above
+      String mpackDirectory = mpackStaging + File.separator + mpack.getName() + File.separator + mpack.getVersion();
+      extractMpackTar(mpackTarPath, mpackDirectory);
     }
     if (isValidMetadata) {
-      mpackId = populateDB(mpacks);
+      mpackId = populateDB(mpack);
       if (mpackId != null) {
-        mpackMap.put(mpackId, mpacks);
-        mpacks.setMpackId(mpackId);
-        return new MpackResponse(mpacks);
+        mpackMap.put(mpackId, mpack);
+        mpack.setMpackId(mpackId);
+        return new MpackResponse(mpack);
       } 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() + ")";
+      String message = "Incorrect information : Mismatch in - (" + mpackName + "," + mpack.getName() + ") or (" + mpackVersion + "," + mpack.getVersion() + ")";
       throw new IllegalArgumentException(message); //Mismatch in information
     }
   }
 
   /**
+   * Mpack is downloaded as a tar.gz file. It is extracted into mpack-v2-staging/{mpack-name}/{mpack-version}/ directory
+   *
+   * @param mpackTarPath
+   * @param mpackDirectory
+   * @throws IOException
+   */
+  private void extractMpackTar(Path mpackTarPath, String mpackDirectory) throws IOException {
+    TarArchiveInputStream mpackTarFile = new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(new File(String.valueOf(mpackTarPath))))));
+    // To read individual TAR file
+    TarArchiveEntry entry = null;
+    File outputFile = null;
+    //Create a loop to read every single entry in TAR file
+    while ((entry = mpackTarFile.getNextTarEntry()) != null) {
+      outputFile = new File(mpackStaging, entry.getName());
+      if (entry.isDirectory()) {
+        LOG.debug("Attempting to write output directory" + outputFile.getAbsolutePath());
+        if (!outputFile.exists()) {
+          LOG.debug("Attempting to create output directory " + outputFile.getAbsolutePath());
+          if (!outputFile.mkdirs()) {
+            throw new IllegalStateException(String.format("Couldn't create directory %s.", outputFile.getAbsolutePath()));
+          }
+        }
+      } else {
+        LOG.debug("Creating output file %s." + outputFile.getAbsolutePath());
+        final OutputStream outputFileStream = new FileOutputStream(outputFile);
+        IOUtils.copy(mpackTarFile, outputFileStream);
+        outputFileStream.close();
+      }
+    }
+    mpackTarFile.close();
+    String mpackTarDirectory = mpackTarPath.toString();
+    Path extractedMpackDirectory = Files.move
+            (Paths.get(mpackStaging + File.separator + mpackTarDirectory.substring(mpackTarDirectory.lastIndexOf('/') + 1, mpackTarDirectory.indexOf(".tar")) + File.separator),
+                    Paths.get(mpackDirectory), StandardCopyOption.REPLACE_EXISTING);
+  }
+
+  /**
+   * Reads the mpack.json file within the {mpack-name}.tar.gz file and populates Mpack object.
+   * Extract the mpack-name and mpack-version from mpack.json to create the new mpack directory to hold the mpack files.
+   *
+   * @param mpackTarPath
+   * @return boolean
+   * @throws IOException
+   */
+  private Boolean createMpackDirectory(Path mpackTarPath) throws IOException {
+    TarArchiveInputStream mpackTarFile = new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(new File(mpackTarPath.toString())))));
+    // To read individual TAR file
+    TarArchiveEntry entry = null;
+    String individualFiles;
+    int offset;
+    // Create a loop to read every single entry in TAR file
+    while ((entry = mpackTarFile.getNextTarEntry()) != null) {
+      // Get the name of the file
+      individualFiles = entry.getName();
+      String[] dirFile = individualFiles.split(File.separator);
+      //Search for mpack.json
+      String fileName = dirFile[dirFile.length - 1];
+      if (fileName.contains("mpack") && fileName.contains(".json")) {
+        // Get Size of the file and create a byte array for the size
+        byte[] content = new byte[(int) entry.getSize()];
+        offset = 0;
+        LOG.info("File Name in TAR File is: " + fileName);
+        LOG.debug("Size of the File is: " + entry.getSize());
+        // Read file from the archive into byte array
+        mpackTarFile.read(content, offset, content.length - offset);
+
+        //Read the mpack.json file into Mpack Object for further use.
+        String mpackJsonContents = new String(content, "UTF-8");
+        Gson gson = new Gson();
+        mpack = gson.fromJson(mpackJsonContents, Mpacks.class);
+
+        mpackTarFile.close();
+
+        return new File(mpackStaging + File.separator + mpack.getName()).mkdir();
+
+      }
+    }
+
+    return false;
+  }
+
+
+  /***
+   * Download the mpack from the given uri
+   * @param sourceURI
+   * @param targetDirectory
+   * @return
+   */
+  public static Path downloadMpack(String sourceURI, String targetDirectory) throws IOException {
+    URL url = new URL(sourceURI);
+    String fileName = sourceURI.substring(sourceURI.lastIndexOf('/') + 1, sourceURI.length());
+    Path targetPath = new File(targetDirectory + File.separator + fileName).toPath();
+    Files.copy(url.openStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
+
+    return targetPath;
+  }
+
+
+  /**
    * Compares if the user's mpack information matches the downloaded mpack information.
    *
    * @param expectedMpackName
@@ -140,24 +243,6 @@ public class MpackManager {
   }
 
   /**
-   * 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
@@ -173,7 +258,7 @@ public class MpackManager {
       MpackEntity mpackEntity = new MpackEntity();
       mpackEntity.setMpackName(mpackName);
       mpackEntity.setMpackVersion(mpackVersion);
-      mpackEntity.setMpackUrl(mpacks.getMpacksUrl());
+      mpackEntity.setMpackUri(mpacks.getMpacksUri());
 
       Long mpackId = mpackDAO.create(mpackEntity);
       return mpackId;
@@ -184,10 +269,12 @@ public class MpackManager {
 
   /**
    * Fetches the packlet info stored in the memory for mpacks/{mpack_id} call.
+   * @param mpackId
+   * @return ArrayList
    */
   public ArrayList<Packlet> getPacklets(Long mpackId) {
     Mpacks mpack = mpackMap.get(mpackId);
-    if(mpack.getPacklets()!=null)
+    if (mpack.getPacklets() != null)
       return mpack.getPacklets();
     return null;
   }
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
index e41edd2..a19ceaf 100644
--- 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
@@ -39,7 +39,7 @@ public class MpackDAO {
    * JPA entity manager
    */
   @Inject
-  private Provider<EntityManager> m_entityManagerProvider;
+  Provider<EntityManager> m_entityManagerProvider;
 
   /**
    * DAO utilities for dealing mostly with {@link TypedQuery} results.
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
index addba17..ed5aa6e 100644
--- 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
@@ -61,7 +61,7 @@ public class MpackEntity {
   private String mpackVersion;
 
   @Column(name = "mpack_uri", nullable = false)
-  private String mpackUrl;
+  private String mpackUri;
 
   public Long getMpackId() {
     return mpackId;
@@ -79,8 +79,8 @@ public class MpackEntity {
     return mpackVersion;
   }
 
-  public String getMpackUrl() {
-    return mpackUrl;
+  public String getMpackUri() {
+    return mpackUri;
   }
 
   public void setMpackId(Long mpackId) {
@@ -99,8 +99,8 @@ public class MpackEntity {
     this.mpackVersion = mpackVersion;
   }
 
-  public void setMpackUrl(String mpackUrl) {
-    this.mpackUrl = mpackUrl;
+  public void setMpackUri(String mpackUri) {
+    this.mpackUri = mpackUri;
   }
 
   public MpackEntity() {
@@ -121,6 +121,8 @@ public class MpackEntity {
     EqualsBuilder equalsBuilder = new EqualsBuilder();
 
     equalsBuilder.append(mpackId, that.mpackId);
+    equalsBuilder.append(mpackName, that.mpackName);
+    equalsBuilder.append(mpackVersion, that.mpackVersion);
     return equalsBuilder.isEquals();
   }
 
@@ -135,7 +137,7 @@ public class MpackEntity {
    */
   @Override
   public int hashCode() {
-    return Objects.hash(mpackId);
+    return Objects.hash(mpackId, mpackName, mpackVersion);
   }
 
   /**
@@ -150,7 +152,7 @@ public class MpackEntity {
     }
     buffer.append(", mpackName=").append(mpackName);
     buffer.append(", mpackVersion=").append(mpackVersion);
-    buffer.append(", mpackUrl=").append(mpackUrl);
+    buffer.append(", mpackUri=").append(mpackUri);
     buffer.append("}");
     return buffer.toString();
   }
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
index 7abac7e..9a457b0 100644
--- 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
@@ -29,7 +29,7 @@ public class Mpacks {
 
     private Long mpackId;
 
-    private String registryId;
+    private Long registryId;
 
     @SerializedName("name")
     private String name;
@@ -46,7 +46,7 @@ public class Mpacks {
     @SerializedName("packlets")
     private ArrayList<Packlet> packlets;
 
-    private String mpacksUrl;
+    private String mpacksUri;
 
     public Long getMpackId() {
         return mpackId;
@@ -56,20 +56,20 @@ public class Mpacks {
         this.mpackId = mpackId;
     }
 
-    public String getRegistryId() {
+    public Long getRegistryId() {
         return registryId;
     }
 
-    public void setRegistryId(String registryId) {
+    public void setRegistryId(Long registryId) {
         this.registryId = registryId;
     }
 
-    public String getMpacksUrl() {
-        return mpacksUrl;
+    public String getMpacksUri() {
+        return mpacksUri;
     }
 
-    public void setMpacksUrl(String mpacksUrl) {
-        this.mpacksUrl = mpacksUrl;
+    public void setMpacksUri(String mpacksUri) {
+        this.mpacksUri = mpacksUri;
     }
 
     public String getName() {
@@ -111,4 +111,127 @@ public class Mpacks {
     public void setPacklets(ArrayList<Packlet> packlets) {
         this.packlets = packlets;
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((mpackId == null) ? 0 : mpackId.hashCode());
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((version == null) ? 0 : version.hashCode());
+        result = prime * result + ((registryId == null) ? 0 : registryId.hashCode());
+        result = prime * result + ((description == null) ? 0 : description.hashCode());
+        result = prime * result + ((prerequisites == null) ? 0 : prerequisites.hashCode());
+        result = prime * result + ((packlets == null) ? 0 : packlets.hashCode());
+        result = prime * result + ((mpacksUri == null) ? 0 : mpacksUri.hashCode());
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj == null) {
+            return false;
+        }
+
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        Mpacks other = (Mpacks) obj;
+
+        if (name != other.name) {
+            return false;
+        }
+
+        if (version == null) {
+            if (other.version != null) {
+                return false;
+            }
+        } else if (!version.equals(other.version)) {
+            return false;
+        }
+
+        if (description == null) {
+            if (other.description != null) {
+                return false;
+            }
+        } else if (!description.equals(other.description)) {
+            return false;
+        }
+
+        if (mpackId == null) {
+            if (other.mpackId != null) {
+                return false;
+            }
+        } else if (!mpackId.equals(other.mpackId)) {
+            return false;
+        }
+
+        if (registryId == null) {
+            if (other.registryId != null) {
+                return false;
+            }
+        } else if (!registryId.equals(other.registryId)) {
+            return false;
+        }
+
+        if (registryId == null) {
+            if (other.registryId != null) {
+                return false;
+            }
+        } else if (!registryId.equals(other.registryId)) {
+            return false;
+        }
+
+        if (registryId == null) {
+            if (other.registryId != null) {
+                return false;
+            }
+        } else if (!registryId.equals(other.registryId)) {
+            return false;
+        }
+
+        if (prerequisites == null) {
+            if (other.prerequisites != null) {
+                return false;
+            }
+        } else if (!prerequisites.equals(other.prerequisites)) {
+            return false;
+        }
+
+        if (packlets == null) {
+            if (other.packlets != null) {
+                return false;
+            }
+        } else if (!packlets.equals(other.packlets)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append('{');
+        sb.append("name=").append(name).append(", ");
+        sb.append("mpackId=").append(mpackId).append(", ");
+        sb.append("version=").append(version).append(", ");
+        sb.append("registryId=").append(registryId).append(", ");
+        sb.append("description=").append(description).append(", ");
+        sb.append("prereq=").append(prerequisites.toString()).append(", ");
+        sb.append("packlets=").append(packlets.toString()).append(", ");
+        sb.append('}');
+        return sb.toString();
+    }
 }
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
index 5c91232..0bd2479 100644
--- 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
@@ -62,4 +62,79 @@ public class Packlet {
     this.sourceDir = sourceDir;
   }
 
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((type == null) ? 0 : type.hashCode());
+    result = prime * result + ((name == null) ? 0 : name.hashCode());
+    result = prime * result + ((version == null) ? 0 : version.hashCode());
+    result = prime * result + ((sourceDir == null) ? 0 : sourceDir.hashCode());
+    return result;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    }
+
+    if (obj == null) {
+      return false;
+    }
+
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+
+    Packlet other = (Packlet) obj;
+
+    if (type != other.type) {
+      return false;
+    }
+
+    if (name == null) {
+      if (other.name != null) {
+        return false;
+      }
+    } else if (!name.equals(other.name)) {
+      return false;
+    }
+
+    if (version == null) {
+      if (other.version != null) {
+        return false;
+      }
+    } else if (!version.equals(other.version)) {
+      return false;
+    }
+
+    if (sourceDir == null) {
+      if (other.sourceDir != null) {
+        return false;
+      }
+    } else if (!sourceDir.equals(other.sourceDir)) {
+      return false;
+    }
+    return true;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    sb.append('{');
+    sb.append("type=").append(type).append(", ");
+    sb.append("name=").append(name).append(", ");
+    sb.append("version=").append(version).append(", ");
+    sb.append("source directory=").append(sourceDir).append(", ");
+    sb.append('}');
+    return sb.toString();
+  }
+
 }
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/MpackResourceDefinitionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/MpackResourceDefinitionTest.java
new file mode 100644
index 0000000..08166b8
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/MpackResourceDefinitionTest.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.api.resources;
+
+import static junit.framework.Assert.assertEquals;
+import org.junit.Test;
+
+/**
+ * MpackServiceResourceDefinition unit tests
+ */
+public class MpackResourceDefinitionTest {
+    @Test
+    public void testDefinitionNames() {
+      ResourceDefinition def = new MpackResourceDefinition();
+      assertEquals("mpack", def.getSingularName());
+      assertEquals("mpacks", def.getPluralName());
+    }
+}
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 6e8852c..64287d7 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
@@ -18,6 +18,27 @@
 
 package org.apache.ambari.server.api.services;
 
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.dao.MetainfoDAO;
+import org.apache.ambari.server.state.AutoDeployInfo;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.CustomCommandDefinition;
+import org.apache.ambari.server.state.DependencyInfo;
+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.RepositoryInfo;
+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.Mpacks;
+import org.apache.ambari.server.controller.MpackRequest;
+import org.apache.ambari.server.controller.MpackResponse;
+import org.apache.ambari.server.mpack.MpackManager;
+import org.apache.ambari.server.mpack.MpackManagerFactory;
 import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
@@ -39,6 +60,8 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 import java.util.UUID;
+import java.util.HashMap;
+import java.util.ArrayList;
 
 import javax.persistence.EntityManager;
 
@@ -54,25 +77,10 @@ import org.apache.ambari.server.metadata.AmbariServiceAlertDefinitions;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.OrmTestHelper;
-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.RepositoryVersionEntity;
 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;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.CustomCommandDefinition;
-import org.apache.ambari.server.state.DependencyInfo;
-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.RepositoryInfo;
-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.alert.AlertDefinition;
 import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
 import org.apache.ambari.server.state.alert.MetricSource;
@@ -343,6 +351,30 @@ public class AmbariMetaInfoTest {
   }
 
   @Test
+  public void testRegisterMpacks() throws Exception{
+    MpackManager mm = metaInfo.getMpackManager();
+    MpackRequest mpackRequest = createNiceMock(MpackRequest.class);
+    Mpacks mpacks = new Mpacks();
+    mpacks.setMpackId((long)100);
+    mpacks.setPacklets(new ArrayList<Packlet>());
+    mpacks.setPrerequisites(new HashMap<String, String>());
+    mpacks.setRegistryId(new Long(100));
+    mpacks.setVersion("3.0");
+    mpacks.setMpacksUri("abc.tar.gz");
+    mpacks.setDescription("Test mpacks");
+    mpacks.setName("testMpack");
+    MpackResponse mpackResponse = new MpackResponse(mpacks);
+    expect(mm.registerMpack(mpackRequest)).andReturn(mpackResponse);
+    replay(mm);
+    assertEquals(mpackResponse,metaInfo.registerMpack(mpackRequest));
+  }
+
+  @Test
+  public void testGetPacklets() throws Exception{
+
+  }
+
+  @Test
   public void testConfigDependencies() throws Exception {
     ServiceInfo serviceInfo = metaInfo.getService(STACK_NAME_HDP, EXT_STACK_NAME,
         SERVICE_NAME_MAPRED2);
@@ -1935,7 +1967,10 @@ public class AmbariMetaInfoTest {
     Properties properties = new Properties();
     properties.setProperty(Configuration.METADATA_DIR_PATH.getKey(), stackRoot.getPath());
     properties.setProperty(Configuration.SERVER_VERSION_FILE.getKey(), versionFile.getPath());
+
     properties.setProperty(Configuration.RESOURCES_DIR.getKey(), resourcesRoot.getPath());
+    properties.setProperty(Configuration.MPACKS_V2_STAGING_DIR_PATH.getKey(),"/var/lib/ambari-server/resources/mpacks-v2");
+
     Configuration configuration = new Configuration(properties);
 
     TestAmbariMetaInfo metaInfo = new TestAmbariMetaInfo(configuration);
@@ -2010,6 +2045,12 @@ public class AmbariMetaInfoTest {
       f.setAccessible(true);
       f.set(this, stackManagerFactory);
 
+      // MpackManagerFactory
+      MpackManagerFactory mpackManagerFactory = injector.getInstance(MpackManagerFactory.class);
+      f = c.getDeclaredField("mpackManagerFactory");
+      f.setAccessible(true);
+      f.set(this, mpackManagerFactory);
+
       //AlertDefinitionDAO
       alertDefinitionDAO = createNiceMock(AlertDefinitionDAO.class);
       f = c.getDeclaredField("alertDefinitionDao");
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/MpackServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/MpackServiceTest.java
new file mode 100644
index 0000000..06eb15d
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/MpackServiceTest.java
@@ -0,0 +1,94 @@
+/**
+ * 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.api.services;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.api.services.parsers.RequestBodyParser;
+import org.apache.ambari.server.api.services.serializers.ResultSerializer;
+
+import org.apache.ambari.server.api.util.ApiVersion;
+import org.apache.ambari.server.controller.spi.Resource;
+
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Unit tests for MpackService
+ */
+public class MpackServiceTest extends BaseServiceTest{
+  @Override
+  public List<BaseServiceTest.ServiceTestInvocation> getTestInvocations() throws Exception {
+    List<BaseServiceTest.ServiceTestInvocation> listInvocations = new ArrayList<>();
+
+    // getMpacks
+    MpacksService service = new TestMpackService("null");
+    Method m = service.getClass().getMethod("getMpacks", String.class, HttpHeaders.class, UriInfo.class);
+    Object[] args = new Object[]{null, getHttpHeaders(), getUriInfo()};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
+
+    // getMpack
+    service = new TestMpackService("1");
+    m = service.getClass().getMethod("getMpack", String.class, HttpHeaders.class, UriInfo.class, String.class);
+    args = new Object[]{null, getHttpHeaders(), getUriInfo(), ""};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
+
+    //createMpacks
+    service = new TestMpackService(null);
+    m = service.getClass().getMethod("createMpacks", String.class, HttpHeaders.class, UriInfo.class);
+    args = new Object[]{"body", getHttpHeaders(), getUriInfo()};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.POST, service, m, args, "body"));
+
+    return listInvocations;
+  }
+  private class TestMpackService extends MpacksService {
+
+    private String m_mpackId;
+
+    private TestMpackService(String mpackId) {
+      super(ApiVersion.Default);
+      m_mpackId = mpackId;
+    }
+
+    @Override
+    protected ResourceInstance createResource(Resource.Type type, Map<Resource.Type, String> mapIds) {
+      return getTestResource();
+    }
+
+    @Override
+    RequestFactory getRequestFactory() {
+      return getTestRequestFactory();
+    }
+
+    @Override
+    protected RequestBodyParser getBodyParser() {
+      return getTestBodyParser();
+    }
+
+    @Override
+    protected ResultSerializer getResultSerializer() {
+      return getTestResultSerializer();
+    }
+  }
+
+
+}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java b/ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java
index 6b79e75..b8d95c7 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/configuration/ConfigurationTest.java
@@ -157,6 +157,16 @@ public class ConfigurationTest {
   }
 
   @Test
+  public void testGetMpacksV2StagingPath() {
+    Properties ambariProperties = new Properties();
+    ambariProperties.setProperty(Configuration.MPACKS_V2_STAGING_DIR_PATH.getKey(), "/var/lib/ambari-server/resources/mpacks-v2/");
+    Configuration conf = new Configuration(ambariProperties);
+    Assert.assertEquals("/var/lib/ambari-server/resources/mpacks-v2/", conf.getMpacksV2StagingPath());
+    conf = new Configuration();
+    Assert.assertEquals(null, conf.getMpacksV2StagingPath());
+  }
+
+  @Test
   public void testGetClientHTTPSSettings() throws IOException {
 
     File passFile = File.createTempFile("https.pass.", "txt");
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
index af85d9b..ac4ceb9 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
@@ -24,6 +24,30 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JAVA_VERS
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.NOT_MANAGED_HDFS_PATH_LIST;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_NAME;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_VERSION;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.security.authorization.Users;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.DesiredConfig;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.PropertyInfo;
+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.ServiceComponentHost;
+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.Mpacks;
+import org.apache.ambari.server.state.Packlet;
 import static org.easymock.EasyMock.anyBoolean;
 import static org.easymock.EasyMock.anyLong;
 import static org.easymock.EasyMock.anyObject;
@@ -75,12 +99,10 @@ import org.apache.ambari.server.agent.stomp.MetadataHolder;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.internal.RequestStageContainer;
-import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.entities.LdapSyncSpecEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
-import org.apache.ambari.server.security.authorization.Users;
 import org.apache.ambari.server.security.authorization.internal.InternalAuthenticationToken;
 import org.apache.ambari.server.security.encryption.CredentialStoreService;
 import org.apache.ambari.server.security.encryption.CredentialStoreType;
@@ -2425,6 +2447,49 @@ public class AmbariManagementControllerImplTest {
     verify(injector, clusters, ambariMetaInfo, stackInfo, cluster, repoVersionDAO, repoVersion);
   }
 
+  @Test
+  public void testRegisterMpacks() throws Exception{
+    MpackRequest mpackRequest = createNiceMock(MpackRequest.class);
+    Mpacks mpacks = new Mpacks();
+    mpacks.setMpackId((long)100);
+    mpacks.setPacklets(new ArrayList<Packlet>());
+    mpacks.setPrerequisites(new HashMap<String, String>());
+    mpacks.setRegistryId(new Long(100));
+    mpacks.setVersion("3.0");
+    mpacks.setMpacksUri("abc.tar.gz");
+    mpacks.setDescription("Test mpacks");
+    mpacks.setName("testMpack");
+    MpackResponse mpackResponse = new MpackResponse(mpacks);
+    Injector injector = createNiceMock(Injector.class);
+    expect(injector.getInstance(MaintenanceStateHelper.class)).andReturn(null).atLeastOnce();
+    expect(ambariMetaInfo.registerMpack(mpackRequest)).andReturn(mpackResponse);
+    replay(ambariMetaInfo,injector);
+    AmbariManagementController controller = new AmbariManagementControllerImpl(null, clusters, injector);
+    setAmbariMetaInfo(ambariMetaInfo, controller);
+    Assert.assertEquals(mpackResponse,controller.registerMpack(mpackRequest));
+  }
+
+  @Test
+  public void testGetPacklets() throws Exception {
+    Long mpackId = new Long(100);
+    ArrayList<Packlet> packletArrayList = new ArrayList<>();
+    Packlet samplePacklet = new Packlet();
+    Injector injector = createNiceMock(Injector.class);
+    samplePacklet.setType("service");
+    samplePacklet.setVersion("3.0.0");
+    samplePacklet.setName("NIFI");
+    samplePacklet.setSourceDir("/abc/nifi.tar.gz");
+    packletArrayList.add(samplePacklet);
+    expect(injector.getInstance(MaintenanceStateHelper.class)).andReturn(null).atLeastOnce();
+    expect(ambariMetaInfo.getPacklets(mpackId)).andReturn(packletArrayList).atLeastOnce();
+    replay(ambariMetaInfo,injector);
+    AmbariManagementController controller = new AmbariManagementControllerImpl(null, clusters, injector);
+    setAmbariMetaInfo(ambariMetaInfo, controller);
+
+    Assert.assertEquals(packletArrayList,controller.getPacklets(mpackId));
+
+  }
+
   public static void constructorInit(Injector injector, Capture<AmbariManagementController> controllerCapture, Gson gson,
                                MaintenanceStateHelper maintenanceStateHelper, KerberosHelper kerberosHelper,
                                Provider<MetadataHolder> m_metadataHolder, Provider<AgentConfigsHolder> m_agentConfigsHolder) {
@@ -2434,6 +2499,7 @@ public class AmbariManagementControllerImplTest {
     expect(injector.getInstance(KerberosHelper.class)).andReturn(kerberosHelper);
   }
 
+
   public static void constructorInit(Injector injector, Capture<AmbariManagementController> controllerCapture,
                                KerberosHelper kerberosHelper) {
     injector.injectMembers(capture(controllerCapture));
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackRequestTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackRequestTest.java
new file mode 100644
index 0000000..e858e54
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackRequestTest.java
@@ -0,0 +1,44 @@
+/**
+ * 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.controller;
+
+
+import org.junit.Test;
+import org.junit.Assert;
+
+/**
+ * Unit tests for MpackRequest
+ */
+public class MpackRequestTest {
+  @Test
+  public void testBasicGetAndSet() {
+    MpackRequest mpackRequest =
+            new MpackRequest(new Long(1));
+    Assert.assertEquals("1", mpackRequest.getMpackId());
+    mpackRequest.setMpackUri("abc.tar.gz");
+    mpackRequest.setRegistryId(new Long(1));
+    mpackRequest.setMpackVersion("3.0");
+    mpackRequest.setMpackName("testmpack");
+
+    Assert.assertEquals("abc.tar.gz", mpackRequest.getMpackUri());
+    Assert.assertEquals("1", mpackRequest.getRegistryId());
+    Assert.assertEquals("3.0", mpackRequest.getMpackVersion());
+    Assert.assertEquals("testmpack", mpackRequest.getMpackName());
+
+  }
+}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java
new file mode 100644
index 0000000..c61d515
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java
@@ -0,0 +1,54 @@
+/**
+ * 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.controller;
+
+import org.apache.ambari.server.state.Mpacks;
+import org.apache.ambari.server.state.Packlet;
+import org.junit.Test;
+import org.junit.Assert;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Unit tests for MpackResponse
+ */
+public class MpackResponseTest {
+  @Test
+  public void testBasicGetAndSet() {
+    MpackResponse mpackResponse = new MpackResponse(setupMpacks());
+    Assert.assertEquals(new Long(100), mpackResponse.getMpackId());
+    Assert.assertEquals("100",mpackResponse.getRegistryId());
+    Assert.assertEquals("3.0",mpackResponse.getMpackVersion());
+    Assert.assertEquals("abc.tar.gz",mpackResponse.getMpackUri());
+    Assert.assertEquals("testMpack", mpackResponse.getMpackName());
+
+  }
+  public Mpacks setupMpacks(){
+    Mpacks mpacks = new Mpacks();
+    mpacks.setMpackId((long)100);
+    mpacks.setPacklets(new ArrayList<Packlet>());
+    mpacks.setPrerequisites(new HashMap<String, String>());
+    mpacks.setRegistryId(new Long(100));
+    mpacks.setVersion("3.0");
+    mpacks.setMpacksUri("abc.tar.gz");
+    mpacks.setDescription("Test mpacks");
+    mpacks.setName("testMpack");
+
+    return mpacks;
+  }
+}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
new file mode 100644
index 0000000..d6638c6
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
@@ -0,0 +1,281 @@
+/**
+ * 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 com.google.inject.Injector;
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.util.Modules;
+import com.google.inject.Module;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.MpackResponse;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.MpackRequest;
+import org.apache.ambari.server.controller.utilities.*;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+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.easymock.EasyMock;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.verify;
+import org.junit.Test;
+import org.junit.Assert;
+import org.junit.Before;
+
+
+import javax.persistence.EntityManager;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+
+public class MpackResourceProviderTest {
+
+  private MpackDAO m_dao;
+  private Injector m_injector;
+  private AmbariManagementController m_amc;
+
+  @Before
+  public void before() throws Exception {
+    m_dao = EasyMock.createNiceMock(MpackDAO.class);
+    m_amc = EasyMock.createNiceMock(AmbariManagementController.class);
+
+    m_injector = Guice.createInjector(Modules.override(new InMemoryDefaultTestModule()).with(
+            new MockModule()));
+  }
+
+  @Test
+  public void testGetResourcesMpacks() throws Exception {
+    Resource.Type type = Resource.Type.Mpack;
+
+    Resource resourceExpected1 = new ResourceImpl(Resource.Type.Mpack);
+    resourceExpected1.setProperty(MpackResourceProvider.MPACK_ID, (long)1);
+    resourceExpected1.setProperty(MpackResourceProvider.MPACK_NAME, "TestMpack1");
+    resourceExpected1.setProperty(MpackResourceProvider.MPACK_VERSION, "3.0");
+    resourceExpected1.setProperty(MpackResourceProvider.MPACK_URI, "abcd.tar.gz");
+    resourceExpected1.setProperty(MpackResourceProvider.REGISTRY_ID, null);
+
+    Resource resourceExpected2 = new ResourceImpl(Resource.Type.Mpack);
+    resourceExpected2.setProperty(MpackResourceProvider.MPACK_ID, (long)2);
+    resourceExpected2.setProperty(MpackResourceProvider.MPACK_NAME, "TestMpack2");
+    resourceExpected2.setProperty(MpackResourceProvider.MPACK_VERSION, "3.0");
+    resourceExpected2.setProperty(MpackResourceProvider.MPACK_URI, "abc.tar.gz");
+    resourceExpected2.setProperty(MpackResourceProvider.REGISTRY_ID, (long)1);
+
+    List<MpackEntity> entities = new ArrayList<>();
+    MpackEntity entity = new MpackEntity();
+    entity.setMpackId((long) 1);
+    entity.setMpackUri("abcd.tar.gz");
+    entity.setMpackName("TestMpack1");
+    entity.setMpackVersion("3.0");
+    entities.add(entity);
+
+    entity = new MpackEntity();
+    entity.setMpackId((long) 2);
+    entity.setMpackUri("abc.tar.gz");
+    entity.setMpackName("TestMpack2");
+    entity.setMpackVersion("3.0");
+    entity.setRegistryId(new Long(1));
+    entities.add(entity);
+
+    // set expectations
+    EasyMock.expect(m_dao.findAll()).andReturn(entities).anyTimes();
+
+    // replay
+    replay(m_dao);
+
+    ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
+            type,
+            PropertyHelper.getPropertyIds(type),
+            PropertyHelper.getKeyPropertyIds(type),
+            m_amc);
+
+    // create the request
+    Request request = PropertyHelper.getReadRequest();
+
+    // get all ... no predicate
+    Set<Resource> resources = provider.getResources(request, null);
+
+    Assert.assertEquals(2, resources.size());
+
+    for (Resource resource : resources) {
+      Long mpackId = (Long) resource.getPropertyValue(MpackResourceProvider.MPACK_ID);
+      if (mpackId == (long) 1) {
+        Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.MPACK_NAME), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_NAME));
+        Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.MPACK_VERSION), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_VERSION));
+        Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.MPACK_URI), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_URI));
+        Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.REGISTRY_ID), (Long) resource.getPropertyValue(MpackResourceProvider.REGISTRY_ID));
+      } else if (mpackId == (long) 2) {
+        Assert.assertEquals(resourceExpected2.getPropertyValue(MpackResourceProvider.MPACK_NAME), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_NAME));
+        Assert.assertEquals(resourceExpected2.getPropertyValue(MpackResourceProvider.MPACK_VERSION), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_VERSION));
+        Assert.assertEquals(resourceExpected2.getPropertyValue(MpackResourceProvider.MPACK_URI), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_URI));
+        Assert.assertEquals(resourceExpected2.getPropertyValue(MpackResourceProvider.REGISTRY_ID), (Long) resource.getPropertyValue(MpackResourceProvider.REGISTRY_ID));
+      } else {
+        Assert.assertTrue(false);
+      }
+    }
+
+    // verify
+    verify(m_dao);
+  }
+
+  @Test
+  public void testGetResourcesMpackId() throws Exception {
+    Resource.Type type = Resource.Type.Mpack;
+
+    Predicate predicate = new PredicateBuilder().property(
+            MpackResourceProvider.MPACK_ID).equals(
+            Long.valueOf(1).toString()).toPredicate();
+
+    MpackEntity entity = new MpackEntity();
+    entity.setMpackId((long) 1);
+    entity.setMpackUri("abcd.tar.gz");
+    entity.setMpackName("TestMpack1");
+    entity.setMpackVersion("3.0");
+
+
+    ArrayList<Packlet> packletArrayList = new ArrayList<>();
+    Packlet packlet = new Packlet();
+    packlet.setName("testService");
+    packlet.setType("service");
+    packlet.setSourceDir("testDir/testDir");
+    packlet.setVersion("3.0");
+    packletArrayList.add(packlet);
+
+    Resource resourceExpected1 = new ResourceImpl(Resource.Type.Mpack);
+    resourceExpected1.setProperty(MpackResourceProvider.MPACK_ID, (long)1);
+    resourceExpected1.setProperty(MpackResourceProvider.MPACK_NAME, "TestMpack1");
+    resourceExpected1.setProperty(MpackResourceProvider.MPACK_VERSION, "3.0");
+    resourceExpected1.setProperty(MpackResourceProvider.MPACK_URI, "abcd.tar.gz");
+    resourceExpected1.setProperty(MpackResourceProvider.REGISTRY_ID, null);
+    resourceExpected1.setProperty(MpackResourceProvider.PACKLETS,packletArrayList);
+
+    // set expectations
+    EasyMock.expect(m_dao.findById((long)1)).andReturn(entity).anyTimes();
+    EasyMock.expect(m_amc.getPacklets((long)1)).andReturn(packletArrayList).anyTimes();
+
+    // replay
+    replay(m_dao,m_amc);
+
+    ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
+            type,
+            PropertyHelper.getPropertyIds(type),
+            PropertyHelper.getKeyPropertyIds(type),
+            m_amc);
+
+    // create the request
+    Request request = PropertyHelper.getReadRequest();
+
+    // get all ... no predicate
+    Set<Resource> resources = provider.getResources(request,predicate);
+
+    Assert.assertEquals(1, resources.size());
+    for(Resource resource: resources){
+      Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.MPACK_NAME), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_NAME));
+      Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.MPACK_VERSION), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_VERSION));
+      Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.MPACK_URI), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_URI));
+      Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.REGISTRY_ID), (Long) resource.getPropertyValue(MpackResourceProvider.REGISTRY_ID));
+      Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.PACKLETS),(ArrayList)resource.getPropertyValue(MpackResourceProvider.PACKLETS));
+  }
+    // verify
+    verify(m_dao,m_amc);
+
+  }
+
+  @Test
+  public void testCreateResources() throws Exception {
+    MpackRequest mpackRequest = new MpackRequest();
+    mpackRequest.setMpackUri("abc.tar.gz");
+    Request request = createMock(Request.class);
+    MpackResponse response = new MpackResponse(setupMpacks());
+    Set<Map<String, Object>> properties = new HashSet<>();
+    Map propertyMap = new HashMap();
+    propertyMap.put(MpackResourceProvider.MPACK_URI,"abc.tar.gz");
+    properties.add(propertyMap);
+
+    // set expectations
+    EasyMock.expect(m_amc.registerMpack(mpackRequest)).andReturn(response).anyTimes();
+    EasyMock.expect(request.getProperties()).andReturn(properties).anyTimes();
+    replay(m_amc,request);
+    // end expectations
+
+    ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
+            Resource.Type.Mpack,
+            PropertyHelper.getPropertyIds(Resource.Type.Mpack),
+            PropertyHelper.getKeyPropertyIds(Resource.Type.Mpack),
+            m_amc);
+
+    AbstractResourceProviderTest.TestObserver observer = new AbstractResourceProviderTest.TestObserver();
+    ((ObservableResourceProvider)provider).addObserver(observer);
+
+    RequestStatusImpl requestStatus = (RequestStatusImpl) provider.createResources(request);
+    Set<Resource> associatedResources = requestStatus.getAssociatedResources();
+
+    Assert.assertEquals(1,associatedResources.size());
+    for(Resource r : associatedResources){
+      Assert.assertEquals((long)100,r.getPropertyValue(MpackResourceProvider.MPACK_ID));
+      Assert.assertEquals("testMpack",r.getPropertyValue(MpackResourceProvider.MPACK_NAME));
+      Assert.assertEquals("3.0",r.getPropertyValue(MpackResourceProvider.MPACK_VERSION));
+      Assert.assertEquals("abc.tar.gz",r.getPropertyValue(MpackResourceProvider.MPACK_URI));
+    }
+    ResourceProviderEvent lastEvent = observer.getLastEvent();
+    Assert.assertNotNull(lastEvent);
+    Assert.assertEquals(Resource.Type.Mpack, lastEvent.getResourceType());
+    Assert.assertEquals(ResourceProviderEvent.Type.Create, lastEvent.getType());
+    Assert.assertEquals(request, lastEvent.getRequest());
+    Assert.assertNull(lastEvent.getPredicate());
+
+    verify(m_amc,request);
+  }
+
+  public Mpacks setupMpacks(){
+    Mpacks mpacks = new Mpacks();
+    mpacks.setMpackId((long)100);
+    mpacks.setPacklets(new ArrayList<Packlet>());
+    mpacks.setPrerequisites(new HashMap<String, String>());
+    mpacks.setRegistryId(new Long(100));
+    mpacks.setVersion("3.0");
+    mpacks.setMpacksUri("abc.tar.gz");
+    mpacks.setDescription("Test mpacks");
+    mpacks.setName("testMpack");
+
+    return mpacks;
+  }
+
+  /**
+   *
+   */
+  private class MockModule implements Module {
+    @Override
+    public void configure(Binder binder) {
+      binder.bind(EntityManager.class).toInstance(EasyMock.createMock(EntityManager.class));
+      binder.bind(MpackDAO.class).toInstance(m_dao);
+      binder.bind(AmbariManagementController.class).toInstance(m_amc);
+    }
+  }
+}
\ No newline at end of file
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/MpackDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/MpackDAOTest.java
new file mode 100644
index 0000000..7b45815
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/MpackDAOTest.java
@@ -0,0 +1,76 @@
+/**
+ * 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.Injector;
+import com.google.inject.Guice;
+import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import com.google.inject.persist.UnitOfWork;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Tests {@link MpackDAO}.
+ */
+public class MpackDAOTest {
+  private Injector m_injector;
+  private MpackDAO m_dao;
+
+  @Before
+  public void init() {
+    m_injector = Guice.createInjector(new InMemoryDefaultTestModule());
+    m_injector.getInstance(GuiceJpaInitializer.class);
+    m_injector.getInstance(UnitOfWork.class).begin();
+    m_dao = m_injector.getInstance(MpackDAO.class);
+  }
+
+  @Test
+  public void testCreateFind() {
+    List<MpackEntity> eDefinitions = new ArrayList<>();
+
+    // create 2 definitions
+    for (int i = 1; i < 3; i++) {
+      MpackEntity definition = new MpackEntity();
+      definition.setMpackId(new Long(100)+i);
+      definition.setMpackName("testMpack" + i);
+      definition.setRegistryId(Long.valueOf(i));
+      definition.setMpackVersion("3.0.0.0-12"+i);
+      definition.setMpackUri("http://c6401.ambari.apache.org:8080/resources/mpacks-repo/testMpack" + i + "-3.0.0.0-123.tar.gz");
+      eDefinitions.add(definition);
+      m_dao.create(definition);
+    }
+
+    List<MpackEntity> definitions = m_dao.findAll();
+    assertNotNull(definitions);
+    assertEquals(2, definitions.size());
+    definitions = m_dao.findByNameVersion("testMpack1","3.0.0.0-121");
+    assertEquals(1, definitions.size());
+    assertEquals(new Long(101),(Long)definitions.get(0).getMpackId());
+    MpackEntity entity = m_dao.findById(new Long(102));
+    assertEquals(entity.getMpackName(),"testMpack2");
+    assertEquals(entity.getMpackVersion(),"3.0.0.0-122");
+
+  }
+}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/MpackEntityTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/MpackEntityTest.java
new file mode 100644
index 0000000..7948111
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/MpackEntityTest.java
@@ -0,0 +1,68 @@
+/**
+ * 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 org.junit.Test;
+import org.junit.Assert;
+
+import java.util.Objects;
+
+/**
+ * Tests methods on {@link MpackEntity}.
+ */
+public class MpackEntityTest {
+  /**
+   * Tests {@link MpackEntity#hashCode()} and {@link MpackEntity#equals(Object)}
+   */
+  @Test
+  public void testHashCodeAndEquals(){
+    MpackEntity entity1 = new MpackEntity();
+    MpackEntity entity2 = new MpackEntity();
+
+    Assert.assertEquals(entity1.hashCode(), entity2.hashCode());
+    Assert.assertTrue(Objects.equals(entity1, entity2));
+
+    entity1.setMpackId(new Long(1));
+    entity2.setMpackId(new Long(2));
+    Assert.assertNotSame(entity1.hashCode(), entity2.hashCode());
+    Assert.assertFalse(Objects.equals(entity1, entity2));
+
+    entity2.setMpackId(new Long(1));
+    Assert.assertEquals(entity1.hashCode(), entity2.hashCode());
+    Assert.assertTrue(Objects.equals(entity1, entity2));
+
+    entity1.setMpackName("testMpack1");
+    entity2.setMpackName("testMpack2");
+    Assert.assertNotSame(entity1.hashCode(), entity2.hashCode());
+    Assert.assertFalse(Objects.equals(entity1, entity2));
+
+    entity2.setMpackName("testMpack1");
+    Assert.assertEquals(entity1.hashCode(), entity2.hashCode());
+    Assert.assertTrue(Objects.equals(entity1, entity2));
+
+    entity1.setMpackVersion("3.0");
+    entity2.setMpackVersion("3.1");
+    Assert.assertNotSame(entity1.hashCode(), entity2.hashCode());
+    Assert.assertFalse(Objects.equals(entity1, entity2));
+
+    entity2.setMpackVersion("3.0");
+    Assert.assertEquals(entity1.hashCode(), entity2.hashCode());
+    Assert.assertTrue(Objects.equals(entity1, entity2));
+  }
+}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/MpacksTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/MpacksTest.java
new file mode 100644
index 0000000..6d87a60
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/MpacksTest.java
@@ -0,0 +1,95 @@
+/**
+ * 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.Gson;
+import org.junit.Test;
+import org.junit.Assert;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class MpacksTest {
+  @Test
+  public void testMpacks() {
+    Mpacks mpacks = new Mpacks();
+    mpacks.setName("name");
+    mpacks.setMpackId((long)100);
+    mpacks.setDescription("desc");
+    mpacks.setVersion("3.0");
+    mpacks.setMpacksUri("abc.tar.gz");
+    mpacks.setRegistryId(new Long(100));
+
+    Assert.assertEquals("name", mpacks.getName());
+    Assert.assertEquals(new Long(100), mpacks.getMpackId());
+    Assert.assertEquals("desc", mpacks.getDescription());
+    Assert.assertEquals("abc.tar.gz", mpacks.getMpacksUri());
+    Assert.assertEquals(new Long(100), mpacks.getRegistryId());
+
+  }
+
+  @Test
+  public void testMpacksUsingGson() {
+    String mpackJsonContents = "{\n" +
+            "  \"name\" : \"hdf-ambari-mpack\",\n" +
+            "  \"version\": \"3.0.0.0-111\",\n" +
+            "  \"description\" : \"HDF 3.0.0 Ambari Management Pack\",\n" +
+            "  \"prerequisites\": {\n" +
+            "    \"min-ambari-version\" : \"3.0.0.0\"\n" +
+            "  },\n" +
+            "  \"packlets\": [\n" +
+            "    {\n" +
+            "      \"type\" : \"service-packlet\",\n" +
+            "      \"name\" : \"NIFI\",\n" +
+            "      \"version\" : \"1.2.0.0-123\",\n" +
+            "      \"source_dir\": \"packlets/NIFI-1.2.0.0-123.tar.gz\"\n" +
+            "    },\n" +
+            "    {\n" +
+            "      \"type\" : \"service-packlet\",\n" +
+            "      \"name\" : \"STREAMLINE\",\n" +
+            "      \"version\" : \"1.0.0.0-100\",\n" +
+            "      \"source_dir\": \"packlets/STREAMLINE-1.0.0.0-100.tar.gz\"\n" +
+            "    }\n" +
+            "  ]\n" +
+            "}\n";
+    HashMap<String, String> expectedPrereq = new HashMap<>();
+    expectedPrereq.put("min-ambari-version","3.0.0.0");
+    ArrayList<Packlet> expectedPacklets = new ArrayList<>();
+    Packlet nifi = new Packlet();
+    nifi.setType("service-packlet");
+    nifi.setVersion("1.2.0.0-123");
+    nifi.setSourceDir("packlets/NIFI-1.2.0.0-123.tar.gz");
+    nifi.setName("NIFI");
+    Packlet streamline = new Packlet();
+    streamline.setName("STREAMLINE");
+    streamline.setType("service-packlet");
+    streamline.setSourceDir("packlets/STREAMLINE-1.0.0.0-100.tar.gz");
+    streamline.setVersion("1.0.0.0-100");
+    expectedPacklets.add(nifi);
+    expectedPacklets.add(streamline);
+
+    Gson gson = new Gson();
+    Mpacks mpacks = gson.fromJson(mpackJsonContents, Mpacks.class);
+    Assert.assertEquals("hdf-ambari-mpack",mpacks.getName());
+    Assert.assertEquals("3.0.0.0-111", mpacks.getVersion());
+    Assert.assertEquals("HDF 3.0.0 Ambari Management Pack",mpacks.getDescription());
+    Assert.assertEquals(expectedPrereq, mpacks.getPrerequisites());
+    Assert.assertEquals(expectedPacklets.toString(), mpacks.getPacklets().toString());
+  }
+
+}


[ambari] 01/20: AMBARI-21150: Mpack API and DB Schema changes (mradhakrishnan)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit d3e45e90dc1954c214b44e7539928a2ade69a35e
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Mon Jun 5 12:25:48 2017 -0700

    AMBARI-21150: Mpack API and DB Schema changes (mradhakrishnan)
---
 ambari-server/conf/unix/ambari.properties          |   1 +
 ambari-server/conf/windows/ambari.properties       |   1 +
 .../api/resources/MpackResourceDefinition.java     |  50 +++
 .../api/resources/ResourceInstanceFactoryImpl.java |   4 +
 .../api/services/AbstractVersionService.java       | 362 +++++++++++++++++++++
 .../ambari/server/api/services/AmbariMetaInfo.java |  57 ++++
 .../ambari/server/api/services/MpacksService.java  | 102 ++++++
 .../ambari/server/configuration/Configuration.java |  17 +
 .../controller/AmbariManagementController.java     |  22 ++
 .../controller/AmbariManagementControllerImpl.java |  14 +-
 .../ambari/server/controller/ControllerModule.java |   2 +
 .../ambari/server/controller/MpackRequest.java     |  82 +++++
 .../ambari/server/controller/MpackResponse.java    |  99 ++++++
 .../controller/internal/DefaultProviderModule.java |   8 +-
 .../controller/internal/MpackResourceProvider.java | 209 ++++++++++++
 .../ambari/server/controller/spi/Resource.java     |   2 +
 .../metrics/system/impl/AmbariMetricSinkImpl.java  |   2 -
 .../apache/ambari/server/mpack/MpackManager.java   | 194 +++++++++++
 .../ambari/server/mpack/MpackManagerFactory.java   |  37 +++
 .../org/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 ++++
 .../src/main/resources/Ambari-DDL-Derby-CREATE.sql |  19 ++
 .../src/main/resources/Ambari-DDL-MySQL-CREATE.sql |  18 +
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql    |  18 +
 .../main/resources/Ambari-DDL-Postgres-CREATE.sql  |  18 +
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql    |  18 +
 .../main/resources/Ambari-DDL-SQLServer-CREATE.sql |  18 +
 .../src/main/resources/META-INF/persistence.xml    |   1 +
 .../system/impl/TestAmbariMetricsSinkImpl.java     |   2 -
 31 files changed, 1805 insertions(+), 8 deletions(-)

diff --git a/ambari-server/conf/unix/ambari.properties b/ambari-server/conf/unix/ambari.properties
index 4e189a4..6254f7d 100644
--- a/ambari-server/conf/unix/ambari.properties
+++ b/ambari-server/conf/unix/ambari.properties
@@ -129,6 +129,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_S [...]
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
 
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";
+  }
+}
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 4133383..61c7c89 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
@@ -154,6 +154,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
         resourceDefinition = new MemberResourceDefinition();
         break;
 
+      case Mpack:
+        resourceDefinition = new MpackResourceDefinition();
+        break;
+
       case Request:
         resourceDefinition = new RequestResourceDefinition();
         break;
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
new file mode 100644
index 0000000..2d81602
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AbstractVersionService.java
@@ -0,0 +1,362 @@
+/**
+ * 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.api.services;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+
+import org.apache.ambari.server.api.rest.BootStrapResource;
+import org.apache.ambari.server.api.rest.HealthCheck;
+import org.apache.ambari.server.api.rest.KdcServerReachabilityCheck;
+import org.apache.ambari.server.api.util.ApiVersion;
+
+/**
+ * Abstract class for single entry point for an API version
+ */
+public abstract class AbstractVersionService {
+
+  /**
+   * Handles /actions request.
+   *
+   * @return action service
+   */
+  @Path("/actions")
+  public ActionService getActionService(@PathParam("apiVersion") String apiVersion) {
+    return new ActionService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /alert_targets request.
+   *
+   * @return alert targets service
+   */
+  @Path("/alert_targets")
+  public AlertTargetService getAlertTargetService(@PathParam("apiVersion") String apiVersion) {
+    return new AlertTargetService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /privileges request.
+   *
+   * @return privileges service
+   */
+  @Path("/privileges")
+  public AmbariPrivilegeService getAmbariPrivilegeService(@PathParam("apiVersion") String apiVersion) {
+    return new AmbariPrivilegeService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /blueprints request.
+   *
+   * @return blueprints service
+   */
+  @Path("/blueprints")
+  public BlueprintService getBlueprintService(@PathParam("apiVersion") String apiVersion) {
+    return new BlueprintService(ApiVersion.valueOf(apiVersion));
+  }
+
+
+  /**
+   * Handles /links request.
+   *
+   * @return extension links service
+   */
+  @Path("/links")
+  public ExtensionLinksService getExtensionLinksService(@PathParam("apiVersion") String apiVersion) {
+    return new ExtensionLinksService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /extensions request.
+   *
+   * @return extensions service
+   */
+  @Path("/extensions")
+  public ExtensionsService getExtensionsService(@PathParam("apiVersion") String apiVersion) {
+    return new ExtensionsService(ApiVersion.valueOf(apiVersion));
+  }
+
+
+  /**
+   * Handles /clusters request.
+   *
+   * @return cluster service
+   */
+  @Path("/clusters")
+  public ClusterService getClusterService(@PathParam("apiVersion") String apiVersion) {
+    return new ClusterService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /feeds request.
+   * TODO: Cleanup?
+   *
+   * @return feed service
+   */
+  @Path("/feeds")
+  public FeedService getFeedService(@PathParam("apiVersion") String apiVersion) {
+    return new FeedService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /groups request.
+   *
+   * @return group service
+   */
+  @Path("/groups")
+  public GroupService getGroupService(@PathParam("apiVersion") String apiVersion) {
+    return new GroupService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /hosts request.
+   *
+   * @return host service
+   */
+  @Path("/hosts")
+  public HostService getHostService(@PathParam("apiVersion") String apiVersion) {
+    return new HostService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /instances request.
+   * TODO: Cleanup?
+   *
+   * @return instance service
+   */
+  @Path("/instances")
+  public InstanceService getInstanceService(@PathParam("apiVersion") String apiVersion) {
+    return new InstanceService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /kerberos_descriptors request.
+   *
+   * @return kerberos descriptor service
+   */
+  @Path("/kerberos_descriptors")
+  public KerberosDescriptorService getKerberosDescriptorService(@PathParam("apiVersion") String apiVersion) {
+    return new KerberosDescriptorService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /keys request.
+   *
+   * @return key service
+   */
+  @Path("/keys")
+  public KeyService getKeyService(@PathParam("apiVersion") String apiVersion) {
+    return new KeyService();
+  }
+
+  /**
+   * Handles /ldap_sync_events request.
+   *
+   * @return Ldap sync event service
+   */
+  @Path("/ldap_sync_events")
+  public LdapSyncEventService getLdapSyncEventService(@PathParam("apiVersion") String apiVersion) {
+    return new LdapSyncEventService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /logout request.
+   *
+   * @return logout service
+   */
+  @Path("/logout")
+  public LogoutService getLogoutService(@PathParam("apiVersion") String apiVersion) {
+    return new LogoutService();
+  }
+
+  /**
+   * Handles /permissions request.
+   *
+   * @return permission service
+   */
+  @Path("/permissions")
+  public PermissionService getPermissionService(@PathParam("apiVersion") String apiVersion) {
+    return new PermissionService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /persist request.
+   *
+   * @return persist service
+   */
+  @Path("/persist")
+  public PersistKeyValueService getPersistKeyValueService(@PathParam("apiVersion") String apiVersion) {
+    return new PersistKeyValueService();
+  }
+
+  /**
+   * Handles /remoteclusters request
+   *
+   * @return remote clusters service
+   */
+  @Path("/remoteclusters")
+  public RemoteClustersService getRemoteClustersService(@PathParam("apiVersion") String apiVersion) {
+    return new RemoteClustersService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /requests request.
+   *
+   * @return request service
+   */
+  @Path("/requests")
+  public RequestService getRequestService(@PathParam("apiVersion") String apiVersion) {
+    return new RequestService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /settings request.
+   *
+   * @return request service
+   */
+  @Path("/settings")
+  public SettingService getSettingService(@PathParam("apiVersion") String apiVersion) {
+    return new SettingService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /authorizations request.
+   *
+   * @return role authorization service
+   */
+  @Path("/authorizations")
+  public RoleAuthorizationService getRoleAuthorizationService(@PathParam("apiVersion") String apiVersion) {
+    return new RoleAuthorizationService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /services request.
+   *
+   * @return root service service
+   */
+  @Path("/services")
+  public RootServiceService getRootServiceService(@PathParam("apiVersion") String apiVersion) {
+    return new RootServiceService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /targets request.
+   * TODO: Cleanup?
+   *
+   * @return target cluster service
+   */
+  @Path("/targets")
+  public TargetClusterService getTargetClusterService(@PathParam("apiVersion") String apiVersion) {
+    return new TargetClusterService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /users request.
+   *
+   * @return user service
+   */
+  @Path("/users")
+  public UserService getUserService(@PathParam("apiVersion") String apiVersion) {
+    return new UserService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /version_definitions request.
+   *
+   * @return version definition service
+   */
+  @Path("/version_definitions")
+  public VersionDefinitionService getVersionDefinitionService(@PathParam("apiVersion") String apiVersion) {
+    return new VersionDefinitionService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /views request.
+   *
+   * @return view service
+   */
+  @Path("/views")
+  public ViewService getViewService(@PathParam("apiVersion") String apiVersion) {
+    return new ViewService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /view/urls request.
+   *
+   * @return view urls service
+   */
+  @Path("/view/urls")
+  public ViewUrlsService getViewUrlsService(@PathParam("apiVersion") String apiVersion) {
+    return new ViewUrlsService(ApiVersion.valueOf(apiVersion));
+  }
+
+  /**
+   * Handles /stacks request.
+   *
+   * @return stacks service
+   */
+  @Path("/stacks")
+  public StacksService getStacksService(@PathParam("apiVersion") String apiVersion) {
+    return new StacksService(ApiVersion.valueOf(apiVersion));
+  }
+
+
+  /**
+   * Handles /bootstrap request.
+   *
+   * @return bootstrap service
+   */
+  @Path("/bootstrap")
+  public BootStrapResource getBootStrapResource(@PathParam("apiVersion") String apiVersion) {
+    return new BootStrapResource();
+  }
+
+
+  /**
+   * Handles /check request.
+   *
+   * @return health check service
+   */
+  @Path("/check")
+  public HealthCheck getHealthCheck(@PathParam("apiVersion") String apiVersion) {
+    return new HealthCheck();
+  }
+
+  /**
+   * Handles /kdc_check request.
+   *
+   * @return kdc server reachability service
+   */
+  @Path("/kdc_check")
+  public KdcServerReachabilityCheck getKdcServerReachabilityCheck(@PathParam("apiVersion") String apiVersion) {
+    return new KdcServerReachabilityCheck();
+  }
+
+  /**
+   * Handles /mpacks request.
+   *
+   * @return mpacks service
+   */
+  @Path("/mpacks")
+  public MpacksService getMpacksService(@PathParam("apiVersion") String apiVersion) {
+    return new MpacksService(ApiVersion.valueOf(apiVersion));
+  }
+
+
+}
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 54dfd1a..8ad5357 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
@@ -45,6 +45,9 @@ 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.RootService;
+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.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.alert.ScriptSource;
@@ -145,9 +151,12 @@ public class AmbariMetaInfo {
   private File serverVersionFile;
   private File commonWidgetsDescriptorFile;
   private File customActionRoot;
+
   private String commonKerberosDescriptorFileLocation;
   Map<String, VersionDefinitionXml> versionDefinitions = null;
 
+  private File mpacksV2Staging;
+
 
   @Inject
   private MetainfoDAO metaInfoDAO;
@@ -206,6 +215,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;
 
   /**
@@ -235,8 +256,13 @@ public class AmbariMetaInfo {
 
     customActionRoot = new File(conf.getCustomActionDefinitionPath());
 
+
     commonKerberosDescriptorFileLocation = new File(conf.getResourceDirPath(), KERBEROS_DESCRIPTOR_FILE_NAME).getAbsolutePath();
     commonWidgetsDescriptorFile = new File(conf.getResourceDirPath(), WIDGETS_DESCRIPTOR_FILE_NAME);
+
+    String mpackV2StagingPath = conf.getMpacksV2StagingPath();
+    mpacksV2Staging = new File(mpackV2StagingPath);
+
   }
 
   /**
@@ -254,6 +280,8 @@ public class AmbariMetaInfo {
     stackManager = stackManagerFactory.create(stackRoot, commonServicesRoot, extensionsRoot,
         osFamily, false);
 
+    mpackManager = mpackManagerFactory.create(mpacksV2Staging);
+
     getCustomActionDefinitions(customActionRoot);
   }
 
@@ -266,6 +294,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
@@ -617,6 +653,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);
 
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));
+
+  }
+
+}
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 09d90e8..aa75c1b 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
@@ -716,6 +716,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(
@@ -3517,6 +3526,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);
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 57e80f5..74a75b5 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.MetadataUpdateEvent;
 import org.apache.ambari.server.events.TopologyUpdateEvent;
@@ -64,6 +67,7 @@ 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.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;
@@ -153,6 +157,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 -------------------------------------------------------------
 
@@ -952,5 +965,14 @@ public interface AmbariManagementController {
       throws AmbariException;
 
   Map<String, BlueprintProvisioningState> getBlueprintProvisioningStates(Long clusterId, Long hostId) throws AmbariException;
+
+  /**
+   * Fetch the packlet info for a given mpack.
+   *
+   * @param mpackId
+   * @return List of packlets
+   */
+  ArrayList<Packlet> getPacklets(Long mpackId);
+
 }
 
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 f7e2ba4..9ac40c0 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
@@ -134,6 +134,7 @@ 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.SystemException;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 import org.apache.ambari.server.customactions.ActionDefinition;
 import org.apache.ambari.server.events.MetadataUpdateEvent;
 import org.apache.ambari.server.events.TopologyUpdateEvent;
@@ -216,6 +217,7 @@ 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.*;
 import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityController;
@@ -559,7 +561,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
   @Override
   public synchronized void createHostComponents(Set<ServiceComponentHostRequest> requests, boolean isBlueprintProvisioned)
-      throws AmbariException, AuthorizationException {
+     throws AmbariException, AuthorizationException {
 
     if (requests.isEmpty()) {
       LOG.warn("Received an empty requests set");
@@ -717,6 +719,16 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     m_topologyHolder.get().updateData(getAddedComponentsTopologyEvent(requests));
   }
 
+  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);
+  }
+
   void persistServiceComponentHosts(Set<ServiceComponentHostRequest> requests, boolean isBlueprintProvisioned)
     throws AmbariException {
     Multimap<Cluster, ServiceComponentHost> schMap = ArrayListMultimap.create();
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 aae1eb3..470777c 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
@@ -97,6 +97,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;
@@ -500,6 +501,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());
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;
+  }
+
+}
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());
+  }
+}
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 9f92cdd..eaac98d 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.
@@ -80,6 +80,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:
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;
+  }
+
+}
+
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 c669d20..23cd528 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,
@@ -213,6 +214,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();
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 2a5b69e..0a1119e 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;
   }
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;
+  }
+}
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);
+}
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);
+  }
+
+
+}
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();
+  }
+}
+
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;
+    }
+}
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;
+  }
+
+}
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 064807b..6b559a3 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -939,6 +939,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);
@@ -1197,6 +1214,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
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 ccc0851..3f77778 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -1128,6 +1128,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);
@@ -1174,6 +1191,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),
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 5f315f1..ca192cf 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -1107,6 +1107,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);
@@ -1153,6 +1170,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);
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 f40f940..c888dac 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -1156,6 +1156,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),
@@ -1641,6 +1642,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);
 
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 f957031..eb01504 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -1107,6 +1107,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);
@@ -1152,6 +1169,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);
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 ba59961..7b3298b 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -1131,6 +1131,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);
@@ -1181,6 +1198,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),
diff --git a/ambari-server/src/main/resources/META-INF/persistence.xml b/ambari-server/src/main/resources/META-INF/persistence.xml
index be7cf16..35b48be 100644
--- a/ambari-server/src/main/resources/META-INF/persistence.xml
+++ b/ambari-server/src/main/resources/META-INF/persistence.xml
@@ -102,6 +102,7 @@
     <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.AmbariConfigurationEntity</class>
+    <class>org.apache.ambari.server.orm.entities.MpackEntity</class>
 
     <properties>
       <property name="eclipselink.cache.size.default" value="10000" />
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 10e5ef8..149960b 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;
   }


[ambari] 15/20: [AMBARI-22992] Update error handling during mpack installation (#363)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 27f19ade679570881b6fa13e4dcaa82bcf764531
Author: mradha25 <mr...@hortonworks.com>
AuthorDate: Thu Feb 15 12:09:52 2018 -0800

    [AMBARI-22992] Update error handling during mpack installation (#363)
    
    * [AMBARI-22992] Update error handling during mpack installation
    
    * [AMBARI-22997] cluster-settings.xml is not present in /var/lib/ambari-server/resources post ambari installation
    
    * [AMBARI-22992] Update error handling during mpack installation - review comments
---
 ambari-server/src/main/assemblies/server.xml       |  5 ++
 .../apache/ambari/server/mpack/MpackManager.java   | 59 ++++++++--------------
 2 files changed, 25 insertions(+), 39 deletions(-)

diff --git a/ambari-server/src/main/assemblies/server.xml b/ambari-server/src/main/assemblies/server.xml
index 21524ee..464972f 100644
--- a/ambari-server/src/main/assemblies/server.xml
+++ b/ambari-server/src/main/assemblies/server.xml
@@ -316,6 +316,11 @@
     </file>
     <file>
       <fileMode>755</fileMode>
+      <source>target/classes/cluster-settings.xml</source>
+      <outputDirectory>/var/lib/ambari-server/resources</outputDirectory>
+    </file>
+    <file>
+      <fileMode>755</fileMode>
       <source>target/classes/Ambari-DDL-Postgres-CREATE.sql</source>
       <outputDirectory>/var/lib/ambari-server/resources</outputDirectory>
     </file>
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
index 69495d2..29b59b3 100644
--- 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
@@ -213,13 +213,13 @@ public class MpackManager {
     if (mpackId != null) {
       mpackMap.put(mpackId, mpack);
       mpack.setMpackId(mpackId);
-      populateStackDB(mpack);
-      return new MpackResponse(mpack);
-    } else {
-      String message = "Mpack :" + mpackRequest.getMpackName() + " version: " + mpackRequest.getMpackVersion()
-        + " already exists in server";
-      throw new ResourceAlreadyExistsException(message);
+      if (populateStackDB(mpack))
+        return new MpackResponse(mpack);
     }
+    String message = "Mpack :" + mpackRequest.getMpackName() + " version: " + mpackRequest.getMpackVersion()
+      + " already exists in server";
+    throw new ResourceAlreadyExistsException(message);
+
   }
 
   /***
@@ -318,7 +318,7 @@ public class MpackManager {
       generateMetainfo(metainfoFile, mpack);
     }
 
-    createSymLinks();
+    createSymLinks(mpack);
   }
 
   /**
@@ -426,18 +426,10 @@ public class MpackManager {
    * This will enable StackManager to parse the newly registered mpack as part of the stacks.
    * @throws IOException
    */
-  private void createSymLinks() throws IOException {
-    String stackId = mpack.getStackId();
-    String stackName = "";
-    String stackVersion = "";
-    if (stackId == null) {
-      stackName = mpack.getName();
-      stackVersion = mpack.getVersion();
-    } else {
-      StackId id = new StackId(stackId);
-      stackName = id.getStackName();
-      stackVersion = id.getStackVersion();
-    }
+  private void createSymLinks(Mpack mpack) throws IOException {
+
+    String stackName = mpack.getName();
+    String stackVersion = mpack.getVersion();
     File stack = new File(stackRoot + "/" + stackName);
     Path stackPath = Paths.get(stackRoot + "/" + stackName + "/" + stackVersion);
     Path mpackPath = Paths.get(mpackStaging + "/" + mpack.getName() + "/" + mpack.getVersion());
@@ -506,7 +498,8 @@ public class MpackManager {
     String mpackName = mpacks.getName();
     String mpackVersion = mpacks.getVersion();
     List resultSet = mpackDAO.findByNameVersion(mpackName, mpackVersion);
-    if (resultSet.size() == 0) {
+    StackEntity stackEntity = stackDAO.find(mpackName, mpackVersion);
+    if (resultSet.size() == 0 && stackEntity == null) {
       LOG.info("Adding mpack {}-{} to the database", mpackName, mpackVersion);
       MpackEntity mpackEntity = new MpackEntity();
       mpackEntity.setMpackName(mpackName);
@@ -524,23 +517,12 @@ public class MpackManager {
    * Makes an entry or updates the entry in the stack table to establish a link between the mpack and the
    * associated stack
    *
-   * @param mpacks
+   * @param mpack
    * @throws IOException
    */
-  protected void populateStackDB(Mpack mpacks) throws IOException {
-
-    String stackId = mpack.getStackId();
-    String stackName = "";
-    String stackVersion = "";
-    if (stackId == null) {
-      stackName = mpack.getName();
-      stackVersion = mpack.getVersion();
-    } else {
-      StackId id = new StackId(stackId);
-      stackName = id.getStackName();
-      stackVersion = id.getStackVersion();
-    }
-
+  protected boolean populateStackDB(Mpack mpack) throws IOException {
+    String stackName = mpack.getName();
+    String stackVersion = mpack.getVersion();
     StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
     if (stackEntity == null) {
       LOG.info("Adding stack {}-{} to the database", stackName, stackVersion);
@@ -550,12 +532,11 @@ public class MpackManager {
 
       stackEntity.setMpackId(mpack.getMpackId());
       stackDAO.create(stackEntity);
+      return true;
     } else {
-      LOG.error("Updating stack {}-{} to the database", stackName, stackVersion);
-
-      stackEntity.setMpackId(mpack.getMpackId());
+      LOG.error("Stack {}-{} already exists in the database", stackName, stackVersion);
+      return false;
 
-      stackDAO.merge(stackEntity);
     }
   }
 


[ambari] 16/20: AMBARI-22979: Update software registry API to support new mpack schema (jluniya) (#433)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit a77b2f93bc260e1513cd247079c6bcec70ed0382
Author: jayush <ja...@gmail.com>
AuthorDate: Thu Feb 22 10:49:13 2018 -0800

    AMBARI-22979: Update software registry API to support new mpack schema (jluniya) (#433)
---
 .../api/resources/MpackResourceDefinition.java     |   2 +-
 .../ambari/server/api/services/MpacksService.java  |  24 ++---
 .../ambari/server/controller/MpackRequest.java     |  24 ++---
 .../ambari/server/controller/MpackResponse.java    |  75 +++++++------
 .../controller/internal/MpackResourceProvider.java |  51 +++++----
 .../apache/ambari/server/mpack/MpackManager.java   |  61 +++++------
 .../org/apache/ambari/server/orm/dao/MpackDAO.java |  14 +--
 .../ambari/server/orm/entities/MpackEntity.java    |  20 ++--
 .../java/org/apache/ambari/server/state/Mpack.java | 117 +++++++--------------
 .../apache/ambari/server/utils/MpackVersion.java   |  83 ++++++++++++---
 .../apache/ambari/server/utils/VersionUtils.java   |  13 ++-
 .../AmbariManagementControllerImplTest.java        |   2 +-
 .../ambari/server/controller/MpackRequestTest.java |   4 +-
 .../server/controller/MpackResponseTest.java       |   8 +-
 .../internal/MpackResourceProviderTest.java        |  20 ++--
 .../apache/ambari/server/orm/dao/MpackDAOTest.java |   4 +-
 .../server/orm/entities/MpackEntityTest.java       |   6 +-
 .../org/apache/ambari/server/state/MpackTest.java  |   4 +-
 .../ambari/server/utils/TestVersionUtils.java      |  32 +++++-
 19 files changed, 309 insertions(+), 255 deletions(-)

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
index c9560ab..3875135 100644
--- 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
@@ -86,7 +86,7 @@ public class MpackResourceDefinition extends BaseResourceDefinition {
         Map<String, Object> mpackInfo = mapInfo.get("MpackInfo");
 
         int idx = href.indexOf("stacks/");
-        Long mpackId = (Long)mpackInfo.get("mpack_id");
+        Long mpackId = (Long)mpackInfo.get("id");
         href = href.substring(0, idx) + "mpacks/" + mpackId;
         resultNode.setProperty("href", href);
       } else {
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
index c69ed01..4694841 100644
--- 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
@@ -79,7 +79,7 @@ public class MpacksService extends BaseService {
     response = MpackResponseWrapper.class, responseContainer = RESPONSE_CONTAINER_LIST)
   @ApiImplicitParams({
     @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, dataType = DATA_TYPE_STRING,
-      paramType = PARAM_TYPE_QUERY, defaultValue = MpackResourceProvider.MPACK_ID),
+      paramType = PARAM_TYPE_QUERY, defaultValue = MpackResourceProvider.MPACK_RESOURCE_ID),
     @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION, dataType = DATA_TYPE_STRING,
       paramType = PARAM_TYPE_QUERY),
     @ApiImplicitParam(name = QUERY_PAGE_SIZE, value = QUERY_PAGE_SIZE_DESCRIPTION, defaultValue = DEFAULT_PAGE_SIZE,
@@ -129,13 +129,13 @@ public class MpacksService extends BaseService {
   }
 
   /***
-   * Handles: GET /mpacks/{mpack_id}
-   * Return a specific mpack given an mpack_id
+   * Handles: GET /mpacks/{id}
+   * Return a specific mpack given an id
    *
    * @param
    */
   @GET
-  @Path("{mpack_id}")
+  @Path("{id}")
   @Produces(MediaType.TEXT_PLAIN)
   @ApiOperation(value = "Returns information about a specific mpack that is registered with this Ambari instance",
     response = MpackResponseWrapper.class)
@@ -151,14 +151,14 @@ public class MpacksService extends BaseService {
     @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
   })
   public Response getMpack(String body, @Context HttpHeaders headers, @Context UriInfo ui,
-    @PathParam("mpack_id") String mpackId) {
+    @PathParam("id") String id) {
 
     return handleRequest(headers, body, ui, Request.Type.GET,
-            createMpackResource(mpackId));
+            createMpackResource(id));
   }
 
   @DELETE
-  @Path("{mpack_id}")
+  @Path("{id}")
   @Produces(MediaType.TEXT_PLAIN)
   @ApiOperation(value = "Deletes a selected management pack")
   @ApiImplicitParams({
@@ -172,19 +172,19 @@ public class MpacksService extends BaseService {
           @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
           @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
   })
-  public Response deleteMpack(String body, @Context HttpHeaders headers, @Context UriInfo ui, @PathParam("mpack_id") String mpackId) {
+  public Response deleteMpack(String body, @Context HttpHeaders headers, @Context UriInfo ui, @PathParam("id") String id) {
     return handleRequest(headers, body, ui, Request.Type.DELETE,
-            createMpackResource(mpackId));
+            createMpackResource(id));
   }
 
   /**
    * Create an mpack resource instance
-   * @param mpackId
+   * @param id
    * @return ResourceInstance
    */
-  private ResourceInstance createMpackResource(String mpackId) {
+  private ResourceInstance createMpackResource(String id) {
     return createResource(Resource.Type.Mpack,
-            Collections.singletonMap(Resource.Type.Mpack, mpackId));
+            Collections.singletonMap(Resource.Type.Mpack, id));
 
   }
 
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
index a705d18..49d0caa 100644
--- 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
@@ -26,25 +26,25 @@ import org.apache.ambari.server.orm.entities.MpackEntity;
  */
 public class MpackRequest {
 
-  private Long mpackId;
+  private Long id;
+  private Long registryId;
   private String mpackName;
   private String mpackVersion;
   private String mpackUri;
-  private Long registryId;
 
-  public MpackRequest(Long mpackId) {
-    this.setMpackId(mpackId);
+  public MpackRequest(Long id) {
+    this.setId(id);
   }
 
   public MpackRequest() {
   }
 
-  public Long getMpackId() {
-    return mpackId;
+  public Long getId() {
+    return id;
   }
 
-  public void setMpackId(Long mpackId) {
-    this.mpackId = mpackId;
+  public void setId(Long id) {
+    this.id = id;
   }
 
   public String getMpackName() {
@@ -82,7 +82,7 @@ public class MpackRequest {
   @Override
   public int hashCode() {
     int result = 1;
-    result = 31 + getMpackId().hashCode();
+    result = 31 + getId().hashCode();
     return result;
   }
 
@@ -96,11 +96,11 @@ public class MpackRequest {
     }
     MpackRequest mpackRequest = (MpackRequest) obj;
 
-    if (mpackId == null) {
-      if (mpackRequest.mpackId != null) {
+    if (id == null) {
+      if (mpackRequest.id != null) {
         return false;
       }
-    } else if (!mpackId.equals(mpackRequest.mpackId)) {
+    } else if (!id.equals(mpackRequest.id)) {
       return false;
     }
 
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
index 7d44c76..bc1e47d 100644
--- 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
@@ -28,86 +28,93 @@ import io.swagger.annotations.ApiModelProperty;
  */
 public class MpackResponse {
 
-  private Long mpackId;
-  private String mpackVersion;
+  private Long id;
+  private String mpackId;
   private String mpackName;
+  private String mpackVersion;
   private String mpackUri;
   private Long registryId;
   private String stackId;
   private String description;
 
   public MpackResponse(Mpack mpack) {
+    this.id = mpack.getResourceId();
     this.mpackId = mpack.getMpackId();
-    this.mpackVersion = mpack.getVersion();
-    this.mpackUri = mpack.getMpacksUri();
     this.mpackName = mpack.getName();
+    this.mpackVersion = mpack.getVersion();
+    this.mpackUri = mpack.getMpackUri();
     this.registryId = mpack.getRegistryId();
-    this.stackId = mpack.getStackId();
     this.description = mpack.getDescription();
   }
 
-  public String getMpackVersion() {
-    return mpackVersion;
+  public Long getId() {
+    return id;
   }
 
-  public String getMpackUri() {
-    return mpackUri;
+  public void setId(Long id) {
+    this.id = id;
   }
 
-  public Long getMpackId() {
-    return mpackId;
+  public Long getRegistryId() {
+    return registryId;
   }
 
-  public String getStackId() {
-    return stackId;
+  public void setRegistryId(Long registryId) {
+    this.registryId = registryId;
   }
 
-  public void setStackId(String stackId) {
-    this.stackId = stackId;
+  public String getMpackId() {
+    return mpackId;
+  }
+
+  public void setMpackId(String mpackId) {
+    this.mpackId = mpackId;
   }
 
   public String getMpackName() {
     return mpackName;
   }
 
-  public Long getRegistryId() {
-    return registryId;
+  public void setMpackName(String mpackName) {
+    this.mpackName = mpackName;
   }
 
-  public void setMpackVersion(String mpackVersion) {
-    this.mpackVersion = mpackVersion;
+  public String getDescription() {
+    return description;
   }
 
-  public void setMpackName(String mpackName) {
-    this.mpackName = mpackName;
+  public void setDescription(String description) {
+    this.description = description;
   }
 
-  public void setMpackUri(String mpackUri) {
-    this.mpackUri = mpackUri;
+  public String getMpackVersion() {
+    return mpackVersion;
   }
 
-  public void setRegistryId(Long registryId) {
-    this.registryId = registryId;
+  public void setMpackVersion(String mpackVersion) {
+    this.mpackVersion = mpackVersion;
   }
 
-  public void setMpackId(Long mpackId) {
-    this.mpackId = mpackId;
+  public String getMpackUri() {
+    return mpackUri;
   }
 
-
-  public String getDescription() {
-    return description;
+  public void setMpackUri(String mpackUri) {
+    this.mpackUri = mpackUri;
   }
 
-  public void setDescription(String description) {
-    this.description = description;
+  public String getStackId() {
+    return stackId;
   }
 
+  public void setStackId(String stackId) {
+    this.stackId = stackId;
+  }
 
   @Override
   public int hashCode() {
     int result = 1;
-    result = 31 + getMpackId().hashCode();
+    result = 31 + getId().hashCode();
     return result;
   }
 
@@ -120,7 +127,7 @@ public class MpackResponse {
       return true;
     }
     MpackResponse MpackResponse = (MpackResponse) obj;
-    return getMpackId().equals(MpackResponse.getMpackId());
+    return getId().equals(MpackResponse.getId());
   }
 
   public interface MpackResponseWrapper extends ApiModel {
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
index 3771258..3169eda 100644
--- 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
@@ -69,19 +69,20 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
 
   public static final String RESPONSE_KEY = "MpackInfo";
   public static final String ALL_PROPERTIES = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "*";
-  public static final String MPACK_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_id";
+  public static final String MPACK_RESOURCE_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "id";
   public static final String REGISTRY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "registry_id";
+  public static final String MPACK_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_id";
   public static final String MPACK_NAME = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_name";
   public static final String MPACK_VERSION = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_version";
+  public static final String MPACK_DESCRIPTION = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_description";
   public static final String MPACK_URI = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_uri";
   public static final String MODULES = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "modules";
-  public static final String MPACK_DESC = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "description";
   public static final String STACK_NAME_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_name";
   public static final String STACK_VERSION_PROPERTY_ID =
     RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_version";
 
   private static Set<String> pkPropertyIds = new HashSet<>(
-    Arrays.asList(MPACK_ID, STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID));
+    Arrays.asList(MPACK_RESOURCE_ID, STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID));
 
   /**
    * The property ids for an mpack resource.
@@ -104,18 +105,19 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
 
   static {
     // properties
-    PROPERTY_IDS.add(MPACK_ID);
+    PROPERTY_IDS.add(MPACK_RESOURCE_ID);
     PROPERTY_IDS.add(REGISTRY_ID);
+    PROPERTY_IDS.add(MPACK_ID);
     PROPERTY_IDS.add(MPACK_NAME);
     PROPERTY_IDS.add(MPACK_VERSION);
     PROPERTY_IDS.add(MPACK_URI);
-    PROPERTY_IDS.add(MPACK_DESC);
+    PROPERTY_IDS.add(MPACK_DESCRIPTION);
     PROPERTY_IDS.add(MODULES);
     PROPERTY_IDS.add(STACK_NAME_PROPERTY_ID);
     PROPERTY_IDS.add(STACK_VERSION_PROPERTY_ID);
 
     // keys
-    KEY_PROPERTY_IDS.put(Resource.Type.Mpack, MPACK_ID);
+    KEY_PROPERTY_IDS.put(Resource.Type.Mpack, MPACK_RESOURCE_ID);
     KEY_PROPERTY_IDS.put(Resource.Type.Stack, STACK_NAME_PROPERTY_ID);
     KEY_PROPERTY_IDS.put(Resource.Type.StackVersion, STACK_VERSION_PROPERTY_ID);
 
@@ -145,11 +147,12 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
       if (response != null) {
         notifyCreate(Resource.Type.Mpack, request);
         Resource resource = new ResourceImpl(Resource.Type.Mpack);
+        resource.setProperty(MPACK_RESOURCE_ID, response.getId());
         resource.setProperty(MPACK_ID, response.getMpackId());
         resource.setProperty(MPACK_NAME, response.getMpackName());
         resource.setProperty(MPACK_VERSION, response.getMpackVersion());
         resource.setProperty(MPACK_URI, response.getMpackUri());
-        resource.setProperty(MPACK_DESC, response.getDescription());
+        resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
         resource.setProperty(REGISTRY_ID, response.getRegistryId());
         associatedResources.add(resource);
         return getRequestStatus(null, associatedResources);
@@ -199,22 +202,23 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     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_URI) && !propertyMap.containsKey(REGISTRY_ID))
+      if (!propertyMap.containsKey(MPACK_URI) && !propertyMap.containsKey(REGISTRY_ID)) {
         return null;
-      //Fetch Mpack Download Url using the given registry id
-      else if (!propertyMap.containsKey(MPACK_URI)) {
+      } else if (!propertyMap.containsKey(MPACK_URI)) {
+        // Retrieve mpack download url using the given registry id
         mpackRequest.setRegistryId(Long.valueOf((String) propertyMap.get(REGISTRY_ID)));
         mpackRequest.setMpackName((String) propertyMap.get(MPACK_NAME));
         mpackRequest.setMpackVersion((String) propertyMap.get(MPACK_VERSION));
       }
-      //Directly download the mpack using the given url
-      else
+      else {
+        //Directly download the mpack using the given url
         mpackRequest.setMpackUri((String) propertyMap.get(MPACK_URI));
+      }
     }
     return mpackRequest;
-
   }
 
+
   @Override
   public Set<Resource> getResources(Request request, Predicate predicate)
     throws SystemException, UnsupportedPropertyException,
@@ -231,11 +235,12 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
       }
       for (MpackResponse response : responses){
         Resource resource = new ResourceImpl(Resource.Type.Mpack);
+        resource.setProperty(MPACK_RESOURCE_ID, response.getId());
         resource.setProperty(MPACK_ID, response.getMpackId());
         resource.setProperty(MPACK_NAME, response.getMpackName());
         resource.setProperty(MPACK_VERSION, response.getMpackVersion());
         resource.setProperty(MPACK_URI, response.getMpackUri());
-        resource.setProperty(MPACK_DESC, response.getDescription());
+        resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
         resource.setProperty(REGISTRY_ID, response.getRegistryId());
         results.add(resource);
       }
@@ -251,11 +256,12 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
           MpackResponse response = getManagementController().getMpack(mpackId);
           Resource resource = new ResourceImpl(Resource.Type.Mpack);
           if (null != response) {
+            resource.setProperty(MPACK_RESOURCE_ID, response.getId());
             resource.setProperty(MPACK_ID, response.getMpackId());
             resource.setProperty(MPACK_NAME, response.getMpackName());
             resource.setProperty(MPACK_VERSION, response.getMpackVersion());
             resource.setProperty(MPACK_URI, response.getMpackUri());
-            resource.setProperty(MPACK_DESC, response.getDescription());
+            resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
             resource.setProperty(REGISTRY_ID, response.getRegistryId());
             resource.setProperty(STACK_NAME_PROPERTY_ID, stackName);
             resource.setProperty(STACK_VERSION_PROPERTY_ID, stackVersion);
@@ -265,21 +271,22 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         return results;
       }
 
-      if (propertyMap.containsKey(MPACK_ID)) {
-        Object objMpackId = propertyMap.get(MPACK_ID);
-        if(objMpackId != null)
+      if (propertyMap.containsKey(MPACK_RESOURCE_ID)) {
+        Object objMpackId = propertyMap.get(MPACK_RESOURCE_ID);
+        if (objMpackId != null)
           mpackId = Long.valueOf((String) objMpackId);
 
           MpackResponse response = getManagementController().getMpack(mpackId);
           Resource resource = new ResourceImpl(Resource.Type.Mpack);
           if (null != response) {
+            resource.setProperty(MPACK_RESOURCE_ID, response.getId());
             resource.setProperty(MPACK_ID, response.getMpackId());
             resource.setProperty(MPACK_NAME, response.getMpackName());
             resource.setProperty(MPACK_VERSION, response.getMpackVersion());
             resource.setProperty(MPACK_URI, response.getMpackUri());
-            resource.setProperty(MPACK_DESC, response.getDescription());
+            resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
             resource.setProperty(REGISTRY_ID, response.getRegistryId());
-            List<Module> modules = getManagementController().getModules(response.getMpackId());
+            List<Module> modules = getManagementController().getModules(response.getId());
             resource.setProperty(MODULES, modules);
             results.add(resource);
           }
@@ -307,8 +314,8 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     if (getManagementController().getClusters().getClusters().size() > 0) {
       throw new SystemException("Delete request cannot be completed since there is a cluster deployed");
     } else {
-      if (propertyMap.containsKey(MPACK_ID)) {
-        Object objMpackId = propertyMap.get(MPACK_ID);
+      if (propertyMap.containsKey(MPACK_RESOURCE_ID)) {
+        Object objMpackId = propertyMap.get(MPACK_RESOURCE_ID);
         if (objMpackId != null) {
           mpackId = Long.valueOf((String) objMpackId);
           LOG.info("Deleting Mpack, id = " + mpackId.toString());
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
index 29b59b3..123b587 100644
--- 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
@@ -126,9 +126,10 @@ public class MpackManager {
                     "UTF-8");
                   Gson gson = new Gson();
                   Mpack existingMpack = gson.fromJson(mpackJsonContents, Mpack.class);
-                  existingMpack.setMpackId(mpackEntity.getMpackId());
-                  existingMpack.setMpacksUri(mpackEntity.getMpackUri());
-                  mpackMap.put(mpackEntity.getMpackId(), existingMpack);
+                  existingMpack.setResourceId(mpackEntity.getId());
+                  existingMpack.setMpackUri(mpackEntity.getMpackUri());
+                  existingMpack.setRegistryId(mpackEntity.getRegistryId());
+                  mpackMap.put(mpackEntity.getId(), existingMpack);
                 }
               }
             }
@@ -163,7 +164,7 @@ public class MpackManager {
   public MpackResponse registerMpack(MpackRequest mpackRequest)
     throws IOException, IllegalArgumentException, ResourceAlreadyExistsException {
 
-    Long mpackId;
+    Long mpackResourceId;
     String mpackName = "";
     String mpackVersion = "";
     mpack = new Mpack();
@@ -175,27 +176,25 @@ public class MpackManager {
     if (mpackRequest.getRegistryId() != null) {
       mpackName = mpackRequest.getMpackName();
       mpackVersion = mpackRequest.getMpackVersion();
-      mpack.setRegistryId(mpackRequest.getRegistryId());
 
       LOG.info("Mpack Registration via Registry :" + mpackName);
 
       mpack = downloadMpackMetadata(mpackRequest.getMpackUri());
+      mpack.setRegistryId(mpackRequest.getRegistryId());
       isValidMetadata = validateMpackInfo(mpackName, mpackVersion, mpack.getName(), mpack.getVersion());
 
       if (isValidMetadata) {
         mpackTarPath = downloadMpack(mpackRequest.getMpackUri(), mpack.getDefinition());
         createMpackDirectory(mpack);
         mpackDirectory = mpackStaging + File.separator + mpack.getName() + File.separator + mpack.getVersion();
+      } else {
+        String message =
+          "Incorrect information : Mismatch in - (" + mpackName + "," + mpack.getName() + ") or (" + mpackVersion
+            + "," + mpack.getVersion() + ")";
+        throw new IllegalArgumentException(message); //Mismatch in information
       }
-      else {
-          String message =
-            "Incorrect information : Mismatch in - (" + mpackName + "," + mpack.getName() + ") or (" + mpackVersion
-              + "," + mpack.getVersion() + ")";
-          throw new IllegalArgumentException(message); //Mismatch in information
-        }
-      }
-    //Mpack registration using direct download
-    else {
+    } else {
+      // Mpack registration using direct download
       mpack = downloadMpackMetadata(mpackRequest.getMpackUri());
       mpackTarPath = downloadMpack(mpackRequest.getMpackUri(), mpack.getDefinition());
 
@@ -208,13 +207,14 @@ public class MpackManager {
       }
     }
     extractMpackTar(mpack, mpackTarPath, mpackDirectory);
-    mpackId = populateDB(mpack);
-
-    if (mpackId != null) {
-      mpackMap.put(mpackId, mpack);
-      mpack.setMpackId(mpackId);
-      if (populateStackDB(mpack))
-        return new MpackResponse(mpack);
+    mpack.setMpackUri(mpackRequest.getMpackUri());
+    mpackResourceId = populateDB(mpack);
+
+    if (mpackResourceId != null) {
+      mpackMap.put(mpackResourceId, mpack);
+      mpack.setResourceId(mpackResourceId);
+      populateStackDB(mpack);
+      return new MpackResponse(mpack);
     }
     String message = "Mpack :" + mpackRequest.getMpackName() + " version: " + mpackRequest.getMpackVersion()
       + " already exists in server";
@@ -476,9 +476,8 @@ public class MpackManager {
     String actualMpackName,
     String actualMpackVersion) {
 
-    String strippedActualMpackVersion = actualMpackVersion.substring(0, actualMpackVersion.lastIndexOf('.'));
     if (expectedMpackName.equalsIgnoreCase(actualMpackName) && expectedMpackVersion
-      .equalsIgnoreCase(strippedActualMpackVersion)) {
+      .equalsIgnoreCase(actualMpackVersion)) {
       return true;
     } else {
       LOG.info("Incorrect information : Mismatch in - (" + expectedMpackName + "," + actualMpackName + ") or ("
@@ -504,7 +503,7 @@ public class MpackManager {
       MpackEntity mpackEntity = new MpackEntity();
       mpackEntity.setMpackName(mpackName);
       mpackEntity.setMpackVersion(mpackVersion);
-      mpackEntity.setMpackUri(mpack.getMpacksUri());
+      mpackEntity.setMpackUri(mpack.getMpackUri());
       mpackEntity.setRegistryId(mpack.getRegistryId());
       Long mpackId = mpackDAO.create(mpackEntity);
       return mpackId;
@@ -520,7 +519,7 @@ public class MpackManager {
    * @param mpack
    * @throws IOException
    */
-  protected boolean populateStackDB(Mpack mpack) throws IOException {
+  protected void populateStackDB(Mpack mpack) throws IOException, ResourceAlreadyExistsException {
     String stackName = mpack.getName();
     String stackVersion = mpack.getVersion();
     StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
@@ -529,14 +528,12 @@ public class MpackManager {
       stackEntity = new StackEntity();
       stackEntity.setStackName(stackName);
       stackEntity.setStackVersion(stackVersion);
-
-      stackEntity.setMpackId(mpack.getMpackId());
+      stackEntity.setMpackId(mpack.getResourceId());
       stackDAO.create(stackEntity);
-      return true;
     } else {
-      LOG.error("Stack {}-{} already exists in the database", stackName, stackVersion);
-      return false;
-
+      String message = "Stack " + stackName + "-" + stackVersion + " already exists";
+      LOG.error(message);
+      throw new ResourceAlreadyExistsException(message);
     }
   }
 
@@ -568,7 +565,7 @@ public class MpackManager {
 
     LOG.info("Removing mpack :" + mpackName);
 
-    mpackMap.remove(mpackEntity.getMpackId());
+    mpackMap.remove(mpackEntity.getId());
     FileUtils.deleteDirectory(mpackDirToDelete);
 
     if (mpackDirectory.isDirectory()) {
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
index fb4e101..d0068c2 100644
--- 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
@@ -53,19 +53,19 @@ public class MpackDAO {
   @Transactional
   public Long create(MpackEntity mpackEntity) {
     m_entityManagerProvider.get().persist(mpackEntity);
-    return mpackEntity.getMpackId();
+    return mpackEntity.getId();
   }
 
   /**
    * Gets an mpack with the specified ID.
    *
-   * @param mpackId
-   *          the ID of the alert to retrieve.
+   * @param id
+   *          the ID of the mpack 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);
+  public MpackEntity findById(long id) {
+    return m_entityManagerProvider.get().find(MpackEntity.class, id);
   }
 
   /**
@@ -96,8 +96,8 @@ public class MpackDAO {
   }
 
   @Transactional
-  public void removeById(Long mpackId) {
-    m_entityManagerProvider.get().remove(findById(mpackId));
+  public void removeById(Long id) {
+    m_entityManagerProvider.get().remove(findById(id));
   }
 
 }
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
index ed5aa6e..d555f91 100644
--- 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
@@ -40,7 +40,7 @@ import java.util.Objects;
 @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.findById", query = "SELECT mpack FROM MpackEntity mpack where mpack.id = :id"),
         @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")})
 
@@ -49,7 +49,7 @@ public class MpackEntity {
   @Id
   @GeneratedValue(strategy = GenerationType.TABLE, generator = "mpack_id_generator")
   @Column(name = "id", nullable = false, updatable = false)
-  private Long mpackId;
+  private Long id;
 
   @Column(name = "registry_id", nullable = true, insertable = true, updatable = false, length = 10)
   private Long registryId;
@@ -63,8 +63,8 @@ public class MpackEntity {
   @Column(name = "mpack_uri", nullable = false)
   private String mpackUri;
 
-  public Long getMpackId() {
-    return mpackId;
+  public Long getId() {
+    return id;
   }
 
   public Long getRegistryId() {
@@ -83,8 +83,8 @@ public class MpackEntity {
     return mpackUri;
   }
 
-  public void setMpackId(Long mpackId) {
-    this.mpackId = mpackId;
+  public void setId(Long id) {
+    this.id = id;
   }
 
   public void setRegistryId(Long registryId) {
@@ -120,7 +120,7 @@ public class MpackEntity {
     MpackEntity that = (MpackEntity) object;
     EqualsBuilder equalsBuilder = new EqualsBuilder();
 
-    equalsBuilder.append(mpackId, that.mpackId);
+    equalsBuilder.append(id, that.id);
     equalsBuilder.append(mpackName, that.mpackName);
     equalsBuilder.append(mpackVersion, that.mpackVersion);
     return equalsBuilder.isEquals();
@@ -129,7 +129,7 @@ public class MpackEntity {
   /**
    * Generates a hash for the mpack based on the following criteria:
    * <ul>
-   * <li>{@link #mpackId}
+   * <li>{@link #id}
    * </ul>
    * <p/>
    * <p/>
@@ -137,7 +137,7 @@ public class MpackEntity {
    */
   @Override
   public int hashCode() {
-    return Objects.hash(mpackId, mpackName, mpackVersion);
+    return Objects.hash(id, mpackName, mpackVersion);
   }
 
   /**
@@ -146,7 +146,7 @@ public class MpackEntity {
   @Override
   public String toString() {
     StringBuilder buffer = new StringBuilder("MpackEntity{");
-    buffer.append("mpackId=").append(mpackId);
+    buffer.append("id=").append(id);
     if (null != registryId) {
       buffer.append(", registryId=").append(registryId);
     }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
index 1bdd394..233cd95 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
@@ -27,18 +27,25 @@ import java.util.List;
  */
 public class Mpack {
 
-  private Long mpackId;
+  /**
+   * Mpack DB Id
+   */
+  private Long resourceId;
 
   private Long registryId;
 
+  /**
+   * Mpack id as defined in mpack.json
+   */
+  @SerializedName("id")
+  private String mpackId;
+
   @SerializedName("name")
   private String name;
 
   @SerializedName("version")
   private String version;
 
-  @SerializedName("artifacts-path")
-  private String artifactsPath;
 
   @SerializedName("prerequisites")
   private HashMap<String, String> prerequisites;
@@ -46,15 +53,6 @@ public class Mpack {
   @SerializedName("modules")
   private List<Module> modules;
 
-  @SerializedName("modules-path")
-  private String modulesPath;
-
-  @SerializedName("mpack-path")
-  private String mpackPath;
-
-  @SerializedName("stack-id")
-  private String stackId;
-
   @SerializedName("definition")
   private String definition;
 
@@ -63,12 +61,12 @@ public class Mpack {
 
   private String mpackUri;
 
-  public Long getMpackId() {
-    return mpackId;
+  public Long getResourceId() {
+    return resourceId;
   }
 
-  public void setMpackId(Long mpackId) {
-    this.mpackId = mpackId;
+  public void setResourceId(Long resourceId) {
+    this.resourceId = resourceId;
   }
 
   public Long getRegistryId() {
@@ -79,12 +77,20 @@ public class Mpack {
     this.registryId = registryId;
   }
 
-  public String getMpacksUri() {
+  public String getMpackUri() {
     return mpackUri;
   }
 
-  public void setMpacksUri(String mpacksUri) {
-    this.mpackUri = mpacksUri;
+  public void setMpackUri(String mpackUri) {
+    this.mpackUri = mpackUri;
+  }
+
+  public String getMpackId() {
+    return mpackId;
+  }
+
+  public void setMpackId(String mpackId) {
+    this.mpackId = mpackId;
   }
 
   public String getName() {
@@ -127,39 +133,6 @@ public class Mpack {
     this.modules = modules;
   }
 
-  public String getStackId() {
-    return stackId;
-  }
-
-  public void setStackId(String stackId) {
-    this.stackId = stackId;
-  }
-
-
-  public String getArtifactsPath() {
-    return artifactsPath;
-  }
-
-  public void setArtifactsPath(String artifactsPath) {
-    this.artifactsPath = artifactsPath;
-  }
-
-  public String getModulesPath() {
-    return modulesPath;
-  }
-
-  public void setModulesPath(String modulesPath) {
-    this.modulesPath = modulesPath;
-  }
-
-  public String getMpackPath() {
-    return mpackPath;
-  }
-
-  public void setMpackPath(String mpackPath) {
-    this.mpackPath = mpackPath;
-  }
-
   public String getDefinition() {
     return definition;
   }
@@ -175,16 +148,13 @@ public class Mpack {
 
     Mpack mpack = (Mpack) o;
 
-    if (!mpackId.equals(mpack.mpackId)) return false;
+    if (!resourceId.equals(mpack.resourceId)) return false;
     if (registryId != null ? !registryId.equals(mpack.registryId) : mpack.registryId != null) return false;
+    if (!mpackId.equals(mpack.mpackId)) return false;
     if (!name.equals(mpack.name)) return false;
     if (!version.equals(mpack.version)) return false;
-    if (!artifactsPath.equals(mpack.artifactsPath)) return false;
     if (!prerequisites.equals(mpack.prerequisites)) return false;
     if (!modules.equals(mpack.modules)) return false;
-    if (!modulesPath.equals(mpack.modulesPath)) return false;
-    if (!mpackPath.equals(mpack.mpackPath)) return false;
-    if (!stackId.equals(mpack.stackId)) return false;
     if (!definition.equals(mpack.definition)) return false;
     if (!description.equals(mpack.description)) return false;
     return mpackUri.equals(mpack.mpackUri);
@@ -192,16 +162,13 @@ public class Mpack {
 
   @Override
   public int hashCode() {
-    int result = mpackId.hashCode();
+    int result = resourceId.hashCode();
     result = 31 * result + (registryId != null ? registryId.hashCode() : 0);
+    result = 31 * result + mpackId.hashCode();
     result = 31 * result + name.hashCode();
     result = 31 * result + version.hashCode();
-    result = 31 * result + artifactsPath.hashCode();
     result = 31 * result + prerequisites.hashCode();
     result = 31 * result + modules.hashCode();
-    result = 31 * result + modulesPath.hashCode();
-    result = 31 * result + mpackPath.hashCode();
-    result = 31 * result + stackId.hashCode();
     result = 31 * result + definition.hashCode();
     result = 31 * result + description.hashCode();
     result = 31 * result + mpackUri.hashCode();
@@ -211,16 +178,13 @@ public class Mpack {
   @Override
   public String toString() {
     return "Mpack{" +
-            "mpackId=" + mpackId +
+            "id=" + resourceId +
             ", registryId=" + registryId +
+            ", mpackId='" + mpackId + '\'' +
             ", name='" + name + '\'' +
             ", version='" + version + '\'' +
-            ", artifactsPath='" + artifactsPath + '\'' +
             ", prerequisites=" + prerequisites +
             ", modules=" + modules +
-            ", modulesPath='" + modulesPath + '\'' +
-            ", mpackPath='" + mpackPath + '\'' +
-            ", stackId='" + stackId + '\'' +
             ", definition='" + definition + '\'' +
             ", description='" + description + '\'' +
             ", mpackUri='" + mpackUri + '\'' +
@@ -228,15 +192,17 @@ public class Mpack {
   }
 
   public void copyFrom(Mpack mpack) {
-    if (this.name == null)
+    if (this.resourceId == null) {
+      this.resourceId = mpack.getResourceId();
+    }
+    if (this.name == null) {
       this.name = mpack.getName();
     if (this.mpackId == null)
       this.mpackId = mpack.getMpackId();
     if (this.version == null)
       this.version = mpack.getVersion();
-    if (this.stackId == null) {
-      this.stackId = mpack.getStackId();
-    if (this.registryId == null)
+    }
+    if (this.registryId == null) {
       this.registryId = mpack.getRegistryId();
     if (this.description == null)
       this.description = mpack.getDescription();
@@ -244,18 +210,9 @@ public class Mpack {
     if (this.modules == null) {
       this.modules = mpack.getModules();
     }
-    if (this.artifactsPath == null) {
-      this.artifactsPath = mpack.getArtifactsPath();
-    }
     if (this.prerequisites == null) {
       this.prerequisites = mpack.getPrerequisites();
     }
-    if (this.modulesPath == null) {
-      this.modulesPath = mpack.getModulesPath();
-    }
-    if (this.mpackPath == null) {
-      this.mpackPath = mpack.getMpackPath();
-    }
     if (this.definition == null) {
       this.definition = mpack.getDefinition();
     }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/MpackVersion.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/MpackVersion.java
index ad3fdc8..31bb167 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/utils/MpackVersion.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/MpackVersion.java
@@ -23,6 +23,9 @@ import java.util.regex.Pattern;
 
 import org.apache.commons.lang.StringUtils;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * This class should be used to compare mpack and stack versions.
  * Base method which should be used is parse/parseStackVersion, depends
@@ -38,11 +41,15 @@ public class MpackVersion implements Comparable<MpackVersion> {
   private final static String VERSION_WITH_HOTFIX_AND_BUILD_PATTERN = "^([0-9]+).([0-9]+).([0-9]+)-h([0-9]+)-b([0-9]+)";
   private final static String VERSION_WITH_BUILD_PATTERN = "^([0-9]+).([0-9]+).([0-9]+)-b([0-9]+)";
   private final static String LEGACY_STACK_VERSION_PATTERN = "^([0-9]+).([0-9]+).([0-9]+).([0-9]+)-([0-9]+)";
+  private final static String FORMAT_VERSION_PATTERN = "^([0-9]+)(\\.)?([0-9]+)?(\\.)?([0-9]+)?(-h)?([0-9]+)?(-b)?([0-9]+)?";
 
   // Patterns for previous RE
   private final static Pattern PATTERN_WITH_HOTFIX = Pattern.compile(VERSION_WITH_HOTFIX_AND_BUILD_PATTERN);
   private final static Pattern PATTERN_LEGACY_STACK_VERSION = Pattern.compile(LEGACY_STACK_VERSION_PATTERN);
   private final static Pattern PATTERN_WITHOUT_HOTFIX = Pattern.compile(VERSION_WITH_BUILD_PATTERN);
+  private final static Pattern PATTERN_FORMAT_VERSION = Pattern.compile(FORMAT_VERSION_PATTERN);
+
+  private final static Logger LOG = LoggerFactory.getLogger(MpackVersion.class);
 
   // Parts of version
   private int major;
@@ -68,20 +75,59 @@ public class MpackVersion implements Comparable<MpackVersion> {
    * @return MpackVersion instance which contains parsed version
    * */
   public static MpackVersion parse(String mpackVersion) {
-    Matcher versionMatcher = validateMpackVersion(mpackVersion);
-    MpackVersion result = null;
+    return parse(mpackVersion, true);
+  }
 
+  public static MpackVersion parse(String mpackVersion, boolean strict) {
+
+    if(!strict) {
+      mpackVersion = format(mpackVersion);
+    }
+    Matcher versionMatcher = validateMpackVersion(mpackVersion);
+    if(versionMatcher == null) {
+      throw new IllegalArgumentException("Wrong format for mpack version");
+    }
     if (versionMatcher.pattern().pattern().equals(VERSION_WITH_BUILD_PATTERN)) {
-      result = new MpackVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)),
+      return new MpackVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)),
               Integer.parseInt(versionMatcher.group(3)), 0, Integer.parseInt(versionMatcher.group(4)));
-
-    } else {
-      result = new MpackVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)),
+    } else if (versionMatcher.pattern().pattern().equals(VERSION_WITH_HOTFIX_AND_BUILD_PATTERN)) {
+      return new MpackVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)),
               Integer.parseInt(versionMatcher.group(3)), Integer.parseInt(versionMatcher.group(4)), Integer.parseInt(versionMatcher.group(5)));
-
+    } else {
+      throw new IllegalArgumentException("Wrong format for mpack version");
     }
+  }
 
-    return result;
+  /**
+   * Method to format an mpack version in {major}.{minor}.{maint}-h{hotfix}-b{build} format
+   * @param mpackVersion input mpack version string
+   * @return formatted mpack version string
+   */
+  public static String format(String mpackVersion) {
+    Matcher m = PATTERN_FORMAT_VERSION.matcher(mpackVersion);
+    if(m.matches()) {
+      String majorVersion = m.group(1);
+      String minorVersion = m.group(3);
+      String maintVersion = m.group(5);
+      String hotfixNum = m.group(7);
+      String buildNum = m.group(9);
+      if(hotfixNum != null || buildNum != null) {
+        if(minorVersion == null || maintVersion == null) {
+          // Both minorVersion and maintVersion should be specified
+          throw new IllegalArgumentException("Wrong format for mpack version");
+        }
+      }
+      minorVersion = minorVersion != null? minorVersion: "0";
+      maintVersion = maintVersion != null? maintVersion: "0";
+      hotfixNum = hotfixNum != null? hotfixNum: "0";
+      buildNum = buildNum != null? buildNum: "0";
+      String formattedMpackVersion = String.format("%s.%s.%s-h%s-b%s",
+        majorVersion, minorVersion, maintVersion, hotfixNum, buildNum);
+      return formattedMpackVersion;
+
+    } else {
+      throw new IllegalArgumentException("Wrong format for mpack version");
+    }
   }
 
   /**
@@ -93,10 +139,18 @@ public class MpackVersion implements Comparable<MpackVersion> {
    * */
   public static MpackVersion parseStackVersion(String stackVersion) {
     Matcher versionMatcher = validateStackVersion(stackVersion);
-    MpackVersion result = new MpackVersion(Integer.parseInt(versionMatcher.group(1)), Integer.parseInt(versionMatcher.group(2)),
-          Integer.parseInt(versionMatcher.group(3)), Integer.parseInt(versionMatcher.group(4)), Integer.parseInt(versionMatcher.group(5)));
+    if(versionMatcher == null) {
+      throw new IllegalArgumentException("Wrong format for mpack version");
+    }
 
-    return result;
+    if(versionMatcher.pattern().pattern().equals(LEGACY_STACK_VERSION_PATTERN)) {
+      return new MpackVersion(Integer.parseInt(versionMatcher.group(1)),
+        Integer.parseInt(versionMatcher.group(2)),
+        Integer.parseInt(versionMatcher.group(3)), Integer.parseInt(versionMatcher.group(4)),
+        Integer.parseInt(versionMatcher.group(5)));
+    } else {
+      throw new IllegalArgumentException("Wrong format for mpack version");
+    }
   }
 
   /**
@@ -114,12 +168,9 @@ public class MpackVersion implements Comparable<MpackVersion> {
 
     String stackVersion = StringUtils.trim(version);
 
-    Matcher versionMatcher = PATTERN_WITH_HOTFIX.matcher(stackVersion);
+    Matcher versionMatcher = PATTERN_LEGACY_STACK_VERSION.matcher(stackVersion);
     if (!versionMatcher.find()) {
-      versionMatcher = PATTERN_LEGACY_STACK_VERSION.matcher(stackVersion);
-      if (!versionMatcher.find()) {
-        throw new IllegalArgumentException("Wrong format for stack version, should be N.N.N.N-N or N.N.N-hN-bN");
-      }
+      throw new IllegalArgumentException("Wrong format for stack version, should be N.N.N.N-N or N.N.N-hN-bN");
     }
 
     return versionMatcher;
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
index 6a3d81c..4d1e302 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
@@ -20,7 +20,10 @@ package org.apache.ambari.server.utils;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.annotation.Nullable;
+
 import org.apache.ambari.server.bootstrap.BootStrapImpl;
+
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.math.NumberUtils;
 
@@ -253,7 +256,15 @@ public class VersionUtils {
     compare = v2 - v1;
 
     return Integer.compare(compare, 0);
-
   }
 
+  /**
+   * Helper function to compare two comparable versions with null checks
+   * @param v1 The first version
+   * @param v2 The second version
+   * @return 0 if both are equal, <0 if first one is lower, >0 otherwise
+   */
+  public static int compareTo(@Nullable Comparable v1, @Nullable Comparable v2) {
+    return v1 == null ? (v2 == null ? 0 : -1) : v2 == null ? 1 : v1.compareTo(v2);
+  }
 }
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
index f30e030..1e06d18 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
@@ -2452,7 +2452,7 @@ public class AmbariManagementControllerImplTest {
     MpackRequest mpackRequest = createNiceMock(MpackRequest.class);
     RequestStatusResponse response = new RequestStatusResponse(new Long(201));
     Mpack mpack = new Mpack();
-    mpack.setMpackId((long)100);
+    mpack.setResourceId((long)100);
     mpack.setModules(new ArrayList<Module>());
     mpack.setPrerequisites(new HashMap<String, String>());
     mpack.setRegistryId(new Long(100));
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackRequestTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackRequestTest.java
index e858e54..630fb15 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackRequestTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackRequestTest.java
@@ -28,8 +28,8 @@ public class MpackRequestTest {
   @Test
   public void testBasicGetAndSet() {
     MpackRequest mpackRequest =
-            new MpackRequest(new Long(1));
-    Assert.assertEquals("1", mpackRequest.getMpackId());
+            new MpackRequest(1L);
+    Assert.assertEquals((Long)1L, mpackRequest.getId());
     mpackRequest.setMpackUri("abc.tar.gz");
     mpackRequest.setRegistryId(new Long(1));
     mpackRequest.setMpackVersion("3.0");
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java
index 22bcce7..3ef98c6 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java
@@ -36,8 +36,8 @@ public class MpackResponseTest {
   @Test
   public void testBasicGetAndSet() {
     MpackResponse mpackResponse = new MpackResponse(setupMpack());
-    Assert.assertEquals(new Long(100), mpackResponse.getMpackId());
-    Assert.assertEquals("100",mpackResponse.getRegistryId());
+    Assert.assertEquals((Long)100L, mpackResponse.getId());
+    Assert.assertEquals((Long)100L, mpackResponse.getRegistryId());
     Assert.assertEquals("3.0",mpackResponse.getMpackVersion());
     Assert.assertEquals("abc.tar.gz",mpackResponse.getMpackUri());
     Assert.assertEquals("testMpack", mpackResponse.getMpackName());
@@ -46,12 +46,12 @@ public class MpackResponseTest {
 
   public Mpack setupMpack() {
     Mpack mpack = new Mpack();
-    mpack.setMpackId(100L);
+    mpack.setResourceId(100L);
     mpack.setModules(new ArrayList<Module>());
     mpack.setPrerequisites(new HashMap<String, String>());
     mpack.setRegistryId(100L);
     mpack.setVersion("3.0");
-    mpack.setMpacksUri("abc.tar.gz");
+    mpack.setMpackUri("abc.tar.gz");
     mpack.setDescription("Test mpack");
     mpack.setName("testMpack");
 
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
index f3b5aad..f453684 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
@@ -90,14 +90,14 @@ public class MpackResourceProviderTest {
     Resource.Type type = Resource.Type.Mpack;
 
     Resource resourceExpected1 = new ResourceImpl(Resource.Type.Mpack);
-    resourceExpected1.setProperty(MpackResourceProvider.MPACK_ID, (long)1);
+    resourceExpected1.setProperty(MpackResourceProvider.MPACK_RESOURCE_ID, (long)1);
     resourceExpected1.setProperty(MpackResourceProvider.MPACK_NAME, "TestMpack1");
     resourceExpected1.setProperty(MpackResourceProvider.MPACK_VERSION, "3.0");
     resourceExpected1.setProperty(MpackResourceProvider.MPACK_URI, "abcd.tar.gz");
     resourceExpected1.setProperty(MpackResourceProvider.REGISTRY_ID, null);
 
     Resource resourceExpected2 = new ResourceImpl(Resource.Type.Mpack);
-    resourceExpected2.setProperty(MpackResourceProvider.MPACK_ID, (long)2);
+    resourceExpected2.setProperty(MpackResourceProvider.MPACK_RESOURCE_ID, (long)2);
     resourceExpected2.setProperty(MpackResourceProvider.MPACK_NAME, "TestMpack2");
     resourceExpected2.setProperty(MpackResourceProvider.MPACK_VERSION, "3.0");
     resourceExpected2.setProperty(MpackResourceProvider.MPACK_URI, "abc.tar.gz");
@@ -105,14 +105,14 @@ public class MpackResourceProviderTest {
 
     List<MpackEntity> entities = new ArrayList<>();
     MpackEntity entity = new MpackEntity();
-    entity.setMpackId((long) 1);
+    entity.setId((long) 1);
     entity.setMpackUri("abcd.tar.gz");
     entity.setMpackName("TestMpack1");
     entity.setMpackVersion("3.0");
     entities.add(entity);
 
     entity = new MpackEntity();
-    entity.setMpackId((long) 2);
+    entity.setId((long) 2);
     entity.setMpackUri("abc.tar.gz");
     entity.setMpackName("TestMpack2");
     entity.setMpackVersion("3.0");
@@ -138,7 +138,7 @@ public class MpackResourceProviderTest {
     Assert.assertEquals(2, resources.size());
 
     for (Resource resource : resources) {
-      Long mpackId = (Long) resource.getPropertyValue(MpackResourceProvider.MPACK_ID);
+      Long mpackId = (Long) resource.getPropertyValue(MpackResourceProvider.MPACK_RESOURCE_ID);
       if (mpackId == (long) 1) {
         Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.MPACK_NAME), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_NAME));
         Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.MPACK_VERSION), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_VERSION));
@@ -163,11 +163,11 @@ public class MpackResourceProviderTest {
     Resource.Type type = Resource.Type.Mpack;
 
     Predicate predicate = new PredicateBuilder().property(
-            MpackResourceProvider.MPACK_ID).equals(
+            MpackResourceProvider.MPACK_RESOURCE_ID).equals(
             Long.valueOf(1).toString()).toPredicate();
 
     MpackEntity entity = new MpackEntity();
-    entity.setMpackId((long) 1);
+    entity.setId((long) 1);
     entity.setMpackUri("abcd.tar.gz");
     entity.setMpackName("TestMpack1");
     entity.setMpackVersion("3.0");
@@ -182,7 +182,7 @@ public class MpackResourceProviderTest {
     packletArrayList.add(module);
 
     Resource resourceExpected1 = new ResourceImpl(Resource.Type.Mpack);
-    resourceExpected1.setProperty(MpackResourceProvider.MPACK_ID, (long)1);
+    resourceExpected1.setProperty(MpackResourceProvider.MPACK_RESOURCE_ID, (long)1);
     resourceExpected1.setProperty(MpackResourceProvider.MPACK_NAME, "TestMpack1");
     resourceExpected1.setProperty(MpackResourceProvider.MPACK_VERSION, "3.0");
     resourceExpected1.setProperty(MpackResourceProvider.MPACK_URI, "abcd.tar.gz");
@@ -248,7 +248,7 @@ public class MpackResourceProviderTest {
 
     Assert.assertEquals(1,associatedResources.size());
     for(Resource r : associatedResources){
-      Assert.assertEquals((long)100,r.getPropertyValue(MpackResourceProvider.MPACK_ID));
+      Assert.assertEquals((long)100,r.getPropertyValue(MpackResourceProvider.MPACK_RESOURCE_ID));
       Assert.assertEquals("testMpack",r.getPropertyValue(MpackResourceProvider.MPACK_NAME));
       Assert.assertEquals("3.0",r.getPropertyValue(MpackResourceProvider.MPACK_VERSION));
       Assert.assertEquals("../../../../../../../resources/mpacks-v2/abc.tar.gz",r.getPropertyValue(MpackResourceProvider.MPACK_URI));
@@ -266,7 +266,7 @@ public class MpackResourceProviderTest {
 
   public Mpack setupMpack() {
     Mpack mpack = new Mpack();
-    mpack.setMpackId((long)100);
+    mpack.setResourceId((long)100);
     mpack.setModules(new ArrayList<Module>());
     mpack.setPrerequisites(new HashMap<String, String>());
     mpack.setRegistryId(new Long(100));
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/MpackDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/MpackDAOTest.java
index 7b45815..f589fe8 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/MpackDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/MpackDAOTest.java
@@ -53,7 +53,7 @@ public class MpackDAOTest {
     // create 2 definitions
     for (int i = 1; i < 3; i++) {
       MpackEntity definition = new MpackEntity();
-      definition.setMpackId(new Long(100)+i);
+      definition.setId(new Long(100)+i);
       definition.setMpackName("testMpack" + i);
       definition.setRegistryId(Long.valueOf(i));
       definition.setMpackVersion("3.0.0.0-12"+i);
@@ -67,7 +67,7 @@ public class MpackDAOTest {
     assertEquals(2, definitions.size());
     definitions = m_dao.findByNameVersion("testMpack1","3.0.0.0-121");
     assertEquals(1, definitions.size());
-    assertEquals(new Long(101),(Long)definitions.get(0).getMpackId());
+    assertEquals(new Long(101),(Long)definitions.get(0).getId());
     MpackEntity entity = m_dao.findById(new Long(102));
     assertEquals(entity.getMpackName(),"testMpack2");
     assertEquals(entity.getMpackVersion(),"3.0.0.0-122");
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/MpackEntityTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/MpackEntityTest.java
index 7948111..4677837 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/MpackEntityTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/entities/MpackEntityTest.java
@@ -38,12 +38,12 @@ public class MpackEntityTest {
     Assert.assertEquals(entity1.hashCode(), entity2.hashCode());
     Assert.assertTrue(Objects.equals(entity1, entity2));
 
-    entity1.setMpackId(new Long(1));
-    entity2.setMpackId(new Long(2));
+    entity1.setId(new Long(1));
+    entity2.setId(new Long(2));
     Assert.assertNotSame(entity1.hashCode(), entity2.hashCode());
     Assert.assertFalse(Objects.equals(entity1, entity2));
 
-    entity2.setMpackId(new Long(1));
+    entity2.setId(new Long(1));
     Assert.assertEquals(entity1.hashCode(), entity2.hashCode());
     Assert.assertTrue(Objects.equals(entity1, entity2));
 
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
index c561a7a..e478968 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
@@ -30,14 +30,14 @@ public class MpackTest {
   public void testMpacks() {
     Mpack mpack = new Mpack();
     mpack.setName("name");
-    mpack.setMpackId((long)100);
+    mpack.setResourceId((long)100);
     mpack.setDescription("desc");
     mpack.setVersion("3.0");
     mpack.setMpacksUri("abc.tar.gz");
     mpack.setRegistryId(new Long(100));
 
     Assert.assertEquals("name", mpack.getName());
-    Assert.assertEquals(new Long(100), mpack.getMpackId());
+    Assert.assertEquals(new Long(100), mpack.getResourceId());
     Assert.assertEquals("desc", mpack.getDescription());
     Assert.assertEquals("abc.tar.gz", mpack.getMpacksUri());
     Assert.assertEquals(new Long(100), mpack.getRegistryId());
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
index 08c0a06..ebb7278 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
@@ -277,17 +277,41 @@ public class TestVersionUtils {
     Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("2.2.3-b10")));
     Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-h1-b10")));
     Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h0-b10").compareTo(MpackVersion.parse("1.2.3-h0-b11")));
+
+    Assert.assertEquals(0, MpackVersion.parse("1", false).compareTo(MpackVersion.parse("1.0.0-h0-b0")));
+    Assert.assertEquals(0, MpackVersion.parse("1.0", false).compareTo(MpackVersion.parse("1.0.0-h0-b0")));
+    Assert.assertEquals(0, MpackVersion.parse("1.0.0", false).compareTo(MpackVersion.parse("1.0.0-h0-b0")));
+    Assert.assertEquals(0, MpackVersion.parse("1.0.0-b0", false).compareTo(MpackVersion.parse("1.0.0-h0-b0")));
+    Assert.assertEquals(0, MpackVersion.parse("1.0.0-h0-b0", false).compareTo(MpackVersion.parse("1.0.0-h0-b0")));
+
+    Assert.assertEquals(-1, MpackVersion.parse("1", false).compareTo(MpackVersion.parse("1.0.0-h0-b111")));
+    Assert.assertEquals(-1, MpackVersion.parse("1.0", false).compareTo(MpackVersion.parse("1.0.0-h0-b111")));
+    Assert.assertEquals(-1, MpackVersion.parse("1.0.0", false).compareTo(MpackVersion.parse("1.0.0-h0-b111")));
+    Assert.assertEquals(-1, MpackVersion.parse("1.0.0-b0", false).compareTo(MpackVersion.parse("1.0.0-h0-b111")));
+    Assert.assertEquals(-1, MpackVersion.parse("1.0.0-h0-b0", false).compareTo(MpackVersion.parse("1.0.0-h0-b111")));
+
+    Assert.assertEquals(1, MpackVersion.parse("2", false).compareTo(MpackVersion.parse("1.0.0-h0-b111")));
+    Assert.assertEquals(1, MpackVersion.parse("1.1", false).compareTo(MpackVersion.parse("1.0.0-h0-b111")));
+    Assert.assertEquals(1, MpackVersion.parse("1.0.1", false).compareTo(MpackVersion.parse("1.0.0-h0-b111")));
   }
 
   @Test
   public void testStackVersionWithValidVersions() {
     Assert.assertEquals(1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888")));
-    Assert.assertEquals(1, MpackVersion.parseStackVersion("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888")));
+    Assert.assertEquals(1, MpackVersion.parse("1.2.4-h1-b1").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888")));
+    Assert.assertEquals(1, MpackVersion.parse("1.3.3-h1-b1").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888")));
+    Assert.assertEquals(1, MpackVersion.parse("2.2.3-h1-b1").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888")));
+
+    Assert.assertEquals(0, MpackVersion.parse("1.2.3-h4-b888").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888")));
+
     Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.11-888")));
+    Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.4.1-1")));
+    Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.3.3.1-1")));
+    Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("2.2.3.1-1")));
+
     Assert.assertEquals(1, MpackVersion.parseStackVersion("1.2.3.4-999").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888")));
-    Assert.assertEquals(0, MpackVersion.parseStackVersion("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3-h10-b10")));
-    Assert.assertEquals(0, MpackVersion.parseStackVersion("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("1.2.3.10-10")));
-    Assert.assertEquals(-1, MpackVersion.parse("1.2.3-h10-b10").compareTo(MpackVersion.parseStackVersion("2.2.3.4-888")));
+    Assert.assertEquals(0, MpackVersion.parseStackVersion("1.2.3.4-999").compareTo(MpackVersion.parseStackVersion("1.2.3.4-999")));
+    Assert.assertEquals(-1, MpackVersion.parseStackVersion("1.2.3.1-999").compareTo(MpackVersion.parseStackVersion("1.2.3.4-888")));
   }
 
   @Test


[ambari] 04/20: AMBARI-21077: Fix build issues after reverting patch for AMBARI-21077 and merging latest trunk (jluniya)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit f9d70515bad9e8d5f582e99409969f4cc2839587
Author: Jayush Luniya <jl...@hortonworks.com>
AuthorDate: Mon Jul 10 12:53:08 2017 -0700

    AMBARI-21077: Fix build issues after reverting patch for AMBARI-21077 and merging latest trunk (jluniya)
---
 .../server/api/services/MpackRequestSwagger.java   | 30 +++++++
 .../ambari/server/api/services/MpacksService.java  | 82 +++++++++++++++++--
 .../ambari/server/controller/MpackResponse.java    | 10 +++
 .../controller/internal/MpackResourceProvider.java | 19 +++--
 .../ambari/server/upgrade/UpgradeCatalog251.java   |  1 +
 .../server/api/services/MpacksServiceTest.java     | 93 ++++++++++++++++++++++
 6 files changed, 219 insertions(+), 16 deletions(-)

diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/MpackRequestSwagger.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/MpackRequestSwagger.java
new file mode 100644
index 0000000..5fe5693
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/MpackRequestSwagger.java
@@ -0,0 +1,30 @@
+/*
+ * 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.api.services;
+
+import org.apache.ambari.server.controller.ApiModel;
+import org.apache.ambari.server.controller.MpackRequest;
+import org.apache.ambari.server.controller.internal.MpackResourceProvider;
+
+import io.swagger.annotations.ApiModelProperty;
+
+@SuppressWarnings("unused") // for Swagger
+public interface MpackRequestSwagger extends ApiModel {
+  @ApiModelProperty(name = MpackResourceProvider.RESPONSE_KEY)
+  MpackRequest getMpackRequest();
+}
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
index 9912f88..32dae0f 100644
--- 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
@@ -20,7 +20,6 @@ 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;
@@ -28,19 +27,38 @@ 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.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import java.util.Collections;
 
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.MpackResponse.MpackResponseWrapper;
+import org.apache.ambari.server.controller.internal.MpackResourceProvider;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.http.HttpStatus;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+
 /**
  * Service for Mpacks Management.
  * Endpoint for Mpack Data
  */
-
+@Path("/mpacks/")
+@Api(value = "Mpacks", description = "Endpoint for mpack-specific operations")
 public class MpacksService extends BaseService {
 
-  public MpacksService(ApiVersion apiVersion) {
-    super(apiVersion);
+  private static final String MPACK_REQUEST_TYPE = "org.apache.ambari.server.api.services.MpackRequestSwagger";
+
+  public MpacksService() {
+    super();
   }
 
   /**
@@ -53,7 +71,28 @@ public class MpacksService extends BaseService {
    *
    */
   @GET
-  @Produces("text/plain")
+  @Produces(MediaType.TEXT_PLAIN)
+  @ApiOperation(value = "Returns all mpacks registered with this Ambari instance",
+    response = MpackResponseWrapper.class, responseContainer = RESPONSE_CONTAINER_LIST)
+  @ApiImplicitParams({
+    @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, dataType = DATA_TYPE_STRING,
+      paramType = PARAM_TYPE_QUERY, defaultValue = MpackResourceProvider.MPACK_ID),
+    @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION, dataType = DATA_TYPE_STRING,
+      paramType = PARAM_TYPE_QUERY),
+    @ApiImplicitParam(name = QUERY_PAGE_SIZE, value = QUERY_PAGE_SIZE_DESCRIPTION, defaultValue = DEFAULT_PAGE_SIZE,
+      dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
+    @ApiImplicitParam(name = QUERY_FROM, value = QUERY_FROM_DESCRIPTION, allowableValues = QUERY_FROM_VALUES,
+      defaultValue = DEFAULT_FROM, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
+    @ApiImplicitParam(name = QUERY_TO, value = QUERY_TO_DESCRIPTION, allowableValues = QUERY_TO_VALUES,
+      dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
+  })
+  @ApiResponses({
+    @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+    @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+    @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+    @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+    @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+  })
   public Response getMpacks(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
     return handleRequest(headers, body, ui, Request.Type.GET,
             createMpackResource(null));
@@ -68,7 +107,20 @@ public class MpacksService extends BaseService {
    * @return information regarding the created mpack
    */
   @POST
-  @Produces("text/plain")
+  @Produces(MediaType.TEXT_PLAIN)
+  @ApiOperation(value = "Registers an mpack with this Ambari mpack")
+  @ApiImplicitParams({
+    @ApiImplicitParam(dataType = MPACK_REQUEST_TYPE, paramType = PARAM_TYPE_BODY)
+  })
+  @ApiResponses({
+    @ApiResponse(code = HttpStatus.SC_CREATED, message = MSG_SUCCESSFUL_OPERATION),
+    @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED),
+    @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS),
+    @ApiResponse(code = HttpStatus.SC_CONFLICT, message = MSG_RESOURCE_ALREADY_EXISTS),
+    @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+    @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+    @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+  })
   public Response createMpacks(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
     return handleRequest(headers, body, ui, Request.Type.POST, createMpackResource(null));
   }
@@ -81,8 +133,22 @@ public class MpacksService extends BaseService {
    */
   @GET
   @Path("{mpack_id}")
-  @Produces("text/plain")
-  public Response getMpack(String body, @Context HttpHeaders headers, @Context UriInfo ui, @PathParam("mpack_id") String mpackId) {
+  @Produces(MediaType.TEXT_PLAIN)
+  @ApiOperation(value = "Returns information about a specific mpack that is registered with this Ambari instance",
+    response = MpackResponseWrapper.class)
+  @ApiImplicitParams({
+    @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, dataType = DATA_TYPE_STRING,
+      paramType = PARAM_TYPE_QUERY, defaultValue = MpackResourceProvider.ALL_PROPERTIES),
+  })
+  @ApiResponses({
+    @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+    @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+    @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+    @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+    @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+  })
+  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));
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
index d111913..16eb03c 100644
--- 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
@@ -17,7 +17,11 @@
  */
 package org.apache.ambari.server.controller;
 
+
 import org.apache.ambari.server.state.Mpacks;
+import org.apache.ambari.server.controller.internal.MpackResourceProvider;
+
+import io.swagger.annotations.ApiModelProperty;
 
 /**
  * Represents a mpack response.
@@ -106,4 +110,10 @@ public class MpackResponse {
     MpackResponse MpackResponse = (MpackResponse) obj;
     return getMpackId().equals(MpackResponse.getMpackId());
   }
+
+  public interface MpackResponseWrapper extends ApiModel {
+    @ApiModelProperty(name = MpackResourceProvider.RESPONSE_KEY)
+    @SuppressWarnings("unused")
+    MpackResponse getMpackResponse();
+  }
 }
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
index 6f90e04..f939da7 100644
--- 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
@@ -44,6 +44,7 @@ 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.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.orm.dao.MpackDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.MpackEntity;
@@ -56,14 +57,16 @@ import org.apache.ambari.server.state.Packlet;
 @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_URI = "MpackInfo/mpack_uri";
-  public static final String PACKLETS = "MpackInfo/packlets";
-  public static final String STACK_NAME_PROPERTY_ID = "MpackInfo/stack_name";
-  public static final String STACK_VERSION_PROPERTY_ID = "MpackInfo/stack_version";
+  public static final String RESPONSE_KEY = "MpackInfo";
+  public static final String ALL_PROPERTIES = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "*";
+  public static final String MPACK_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_id";
+  public static final String REGISTRY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "registry_id";
+  public static final String MPACK_NAME = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_name";
+  public static final String MPACK_VERSION = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_version";
+  public static final String MPACK_URI = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_uri";
+  public static final String PACKLETS = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "packlets";
+  public static final String STACK_NAME_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_name";
+  public static final String STACK_VERSION_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_version";
 
   private static Set<String> pkPropertyIds = new HashSet<>(
           Arrays.asList(MPACK_ID, STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID));
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog251.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog251.java
index 07c7d3e..6200915 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog251.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog251.java
@@ -31,6 +31,7 @@ import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
 import org.apache.ambari.server.state.SecurityType;
 import org.apache.commons.lang.StringUtils;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/MpacksServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/MpacksServiceTest.java
new file mode 100644
index 0000000..3c3184c
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/MpacksServiceTest.java
@@ -0,0 +1,93 @@
+/**
+ * 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.api.services;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.api.services.parsers.RequestBodyParser;
+import org.apache.ambari.server.api.services.serializers.ResultSerializer;
+
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * Unit tests for MpacksService
+ */
+public class MpacksServiceTest extends BaseServiceTest{
+  @Override
+  public List<BaseServiceTest.ServiceTestInvocation> getTestInvocations() throws Exception {
+    List<BaseServiceTest.ServiceTestInvocation> listInvocations = new ArrayList<>();
+
+    // getMpacks
+    MpacksService service = new TestMpacksService("null");
+    Method m = service.getClass().getMethod("getMpacks", String.class, HttpHeaders.class, UriInfo.class);
+    Object[] args = new Object[]{null, getHttpHeaders(), getUriInfo()};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
+
+    // getMpack
+    service = new TestMpacksService("1");
+    m = service.getClass().getMethod("getMpack", String.class, HttpHeaders.class, UriInfo.class, String.class);
+    args = new Object[]{null, getHttpHeaders(), getUriInfo(), ""};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
+
+    //createMpacks
+    service = new TestMpacksService(null);
+    m = service.getClass().getMethod("createMpacks", String.class, HttpHeaders.class, UriInfo.class);
+    args = new Object[]{"body", getHttpHeaders(), getUriInfo()};
+    listInvocations.add(new ServiceTestInvocation(Request.Type.POST, service, m, args, "body"));
+
+    return listInvocations;
+  }
+  private class TestMpacksService extends MpacksService {
+
+    private String m_mpackId;
+
+    private TestMpacksService(String mpackId) {
+      super();
+      m_mpackId = mpackId;
+    }
+
+    @Override
+    protected ResourceInstance createResource(Resource.Type type, Map<Resource.Type, String> mapIds) {
+      return getTestResource();
+    }
+
+    @Override
+    RequestFactory getRequestFactory() {
+      return getTestRequestFactory();
+    }
+
+    @Override
+    protected RequestBodyParser getBodyParser() {
+      return getTestBodyParser();
+    }
+
+    @Override
+    protected ResultSerializer getResultSerializer() {
+      return getTestResultSerializer();
+    }
+  }
+
+
+}


[ambari] 10/20: AMBARI-22283 : Add stack name and version to mpack API (mradhakrishnan)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 3959182fddd84e55ee5cb48249c583f77d21fe06
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Sun Oct 22 14:34:34 2017 -0700

    AMBARI-22283 : Add stack name and version to mpack API (mradhakrishnan)
---
 .../server/controller/internal/MpackResourceProvider.java  | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

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
index 694bf3c..8e1dbf5 100644
--- 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
@@ -142,12 +142,15 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
       MpackResponse response = getManagementController().registerMpack(mpackRequest);
       if (response != null) {
         notifyCreate(Resource.Type.Mpack, request);
+        String[] stackNameVersion = response.getStackId().split("-");
         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_URI, response.getMpackUri());
+        resource.setProperty(STACK_NAME_PROPERTY_ID, stackNameVersion[0]);
+        resource.setProperty(STACK_VERSION_PROPERTY_ID, stackNameVersion[1]);
 
         associatedResources.add(resource);
         return getRequestStatus(null, associatedResources);
@@ -233,6 +236,9 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         resource.setProperty(MPACK_VERSION, entity.getMpackVersion());
         resource.setProperty(MPACK_URI, entity.getMpackUri());
         resource.setProperty(REGISTRY_ID, entity.getRegistryId());
+        StackEntity stackEntity = stackDAO.findByMpack(entity.getMpackId());
+        resource.setProperty(STACK_NAME_PROPERTY_ID, stackEntity.getStackName());
+        resource.setProperty(STACK_VERSION_PROPERTY_ID, stackEntity.getStackVersion());
         results.add(resource);
       }
     } else {
@@ -271,9 +277,11 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
           resource.setProperty(MPACK_VERSION, entity.getMpackVersion());
           resource.setProperty(MPACK_URI, entity.getMpackUri());
           resource.setProperty(REGISTRY_ID, entity.getRegistryId());
-
-          ArrayList<Packlet> packletArrayList = getManagementController().getPacklets(entity.getMpackId());
-          resource.setProperty(PACKLETS, packletArrayList);
+          StackEntity stackEntity = stackDAO.findByMpack(entity.getMpackId());
+          resource.setProperty(STACK_NAME_PROPERTY_ID, stackEntity.getStackName());
+          resource.setProperty(STACK_VERSION_PROPERTY_ID, stackEntity.getStackVersion());
+          List<Packlet> packlets = getManagementController().getPacklets(entity.getMpackId());
+          resource.setProperty(PACKLETS, packlets);
           results.add(resource);
         }
       }


[ambari] 13/20: [AMBARI-22904] Revised mpack APIs (#252)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 10bf7bae99e6c76e8cd8902b597e16ce70573114
Author: mradha25 <mr...@hortonworks.com>
AuthorDate: Tue Feb 6 11:20:52 2018 -0800

    [AMBARI-22904] Revised mpack APIs (#252)
    
    * [AMBARI-22904] Revised mpack APIs
    
    * [AMBARI-22904] Revised mpack APIs
    
    * [AMBARI-22904] Revised mpack APIs
    
    * [AMBARI-22904] Revised mpack APIs
    
    * [AMBARI-22904] Revised mpack APIs
    
    * [AMBARI-22904] Revised mpack APIs
    
    *  [AMBARI-22904] Revised mpack APIs
---
 .../ambari/server/api/services/AmbariMetaInfo.java |  37 ++-
 .../controller/AmbariManagementController.java     |  35 ++-
 .../controller/AmbariManagementControllerImpl.java |  37 ++-
 .../ambari/server/controller/MpackResponse.java    |  26 +-
 .../controller/internal/MpackResourceProvider.java |  69 +++--
 .../apache/ambari/server/mpack/MpackManager.java   | 310 ++++++++++++++-------
 .../apache/ambari/server/stack/StackDirectory.java |  12 +-
 .../org/apache/ambari/server/state/Module.java     | 163 +++++++++++
 .../ambari/server/state/ModuleComponent.java       | 109 ++++++++
 .../ambari/server/state/ModuleDependency.java      |  88 ++++++
 .../java/org/apache/ambari/server/state/Mpack.java | 246 ++++++++--------
 .../org/apache/ambari/server/state/Packlet.java    | 162 -----------
 .../server/state/stack/StackMetainfoXml.java       |  23 +-
 .../AmbariManagementControllerImplTest.java        |  41 +--
 .../server/controller/MpackResponseTest.java       |  34 ++-
 .../internal/MpackResourceProviderTest.java        |  47 ++--
 .../org/apache/ambari/server/state/MpackTest.java  | 104 ++++---
 17 files changed, 1004 insertions(+), 539 deletions(-)

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 1fa30ef..6180a13 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
@@ -73,6 +73,8 @@ import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.DependencyInfo;
 import org.apache.ambari.server.state.ExtensionInfo;
+import org.apache.ambari.server.state.Module;
+import org.apache.ambari.server.state.Mpack;
 import org.apache.ambari.server.state.OperatingSystemInfo;
 import org.apache.ambari.server.state.PropertyInfo;
 import org.apache.ambari.server.state.RepositoryInfo;
@@ -80,7 +82,6 @@ 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.alert.ScriptSource;
@@ -672,12 +673,12 @@ public class AmbariMetaInfo {
   }
 
   /**
-   * Gets the packlet information for given mpack.
+   * Gets the module information for given mpack.
    * @param mpackId
-   * @return List of Packlets.
+   * @return List of Modules.
    */
-  public ArrayList<Packlet> getPacklets(Long mpackId) {
-    return mpackManager.getPacklets(mpackId);
+  public List<Module> getModules(Long mpackId) {
+    return mpackManager.getModules(mpackId);
   }
 
 
@@ -1556,13 +1557,35 @@ public class AmbariMetaInfo {
    * @throws IOException
    */
   public void removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException {
-    if(versionDefinitions != null) {
+    if (versionDefinitions != null) {
       versionDefinitions.clear();
     }
     boolean stackDelete = mpackManager.removeMpack(mpackEntity, stackEntity);
 
-    if(stackDelete) {
+    if (stackDelete) {
       stackManager.removeStack(stackEntity);
     }
   }
+
+    /*
+   * Fetch all mpacks from mpackMap
+   * @return all mpacks from mpackMap - in memory data structure
+   */
+  public Collection<Mpack> getMpacks() {
+    if (mpackManager.getMpackMap() != null) {
+      return mpackManager.getMpackMap().values();
+    }
+    return Collections.emptySet();
+  }
+
+  /***
+   * Fetch a particular mpack based on mpackid
+   * @return a single mpack
+   */
+  public Mpack getMpack(Long mpackId) {
+    if (mpackManager.getMpackMap() != null && mpackManager.getMpackMap().containsKey(mpackId)) {
+      return mpackManager.getMpackMap().get(mpackId);
+    }
+    return null;
+  }
 }
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 78f5f94..d94fcbc 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
@@ -61,6 +61,7 @@ import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.HostState;
 import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.Module;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceComponentFactory;
@@ -69,7 +70,6 @@ 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.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;
@@ -969,12 +969,13 @@ public interface AmbariManagementController {
   Map<String, BlueprintProvisioningState> getBlueprintProvisioningStates(Long clusterId, Long hostId) throws AmbariException;
 
   /**
-   * Fetch the packlet info for a given mpack.
+   * Fetch the module info for a given mpack.
    *
    * @param mpackId
-   * @return List of packlets
+   * @return List of modules
    */
-  ArrayList<Packlet> getPacklets(Long mpackId);
+  List<Module> getModules(Long mpackId);
+
 
   /***
    * Remove Mpack from the mpackMap and stackMap which is used to power the Mpack and Stack APIs.
@@ -984,5 +985,31 @@ public interface AmbariManagementController {
    */
   void removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException;
 
+  /**
+   * Creates serviceconfigversions and corresponding new configurations if it is an initial request
+   * OR
+   * Rollbacks to an existing serviceconfigversion if request specifies.
+   * @param requests
+   *
+   * @return
+   *
+   * @throws AmbariException
+   *
+   * @throws AuthorizationException
+   */
+  Set<ServiceConfigVersionResponse> createServiceConfigVersion(Set<ServiceConfigVersionRequest> requests) throws AmbariException, AuthorizationException;
+
+  /***
+   * Fetch all mpacks
+   * @return
+   */
+  Set<MpackResponse> getMpacks();
+
+  /***
+   * Fetch an mpack based on id
+   * @param mpackId
+   * @return
+   */
+  MpackResponse getMpack(Long mpackId);
 }
 
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 6d4d090..29e42d9 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
@@ -201,6 +201,8 @@ import org.apache.ambari.server.state.ExtensionInfo;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.HostState;
 import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.Module;
+import org.apache.ambari.server.state.Mpack;
 import org.apache.ambari.server.state.OperatingSystemInfo;
 import org.apache.ambari.server.state.PropertyDependencyInfo;
 import org.apache.ambari.server.state.PropertyInfo;
@@ -251,7 +253,6 @@ import org.apache.ambari.server.state.UnlimitedKeyJCERequirement;
 import org.apache.ambari.server.state.ExtensionInfo;
 import org.apache.ambari.server.state.RepositoryInfo;
 import org.apache.ambari.server.state.OperatingSystemInfo;
-import org.apache.ambari.server.state.Packlet;
 import org.apache.ambari.server.state.HostComponentAdminState;
 import org.apache.ambari.server.state.PropertyDependencyInfo;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityController;
@@ -604,6 +605,30 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     return mpackResponse;
   }
 
+  @Override
+  public Set<MpackResponse> getMpacks(){
+    Collection<Mpack> mpacks = ambariMetaInfo.getMpacks();
+    Set<MpackResponse> responseSet = new HashSet<>();
+    for (Mpack mpack : mpacks){
+      responseSet.add(new MpackResponse(mpack));
+    }
+    return responseSet;
+  }
+
+  @Override
+  public MpackResponse getMpack(Long mpackId) {
+    Mpack mpack = ambariMetaInfo.getMpack(mpackId);
+    if (mpack != null) {
+      return new MpackResponse(mpack);
+    }else{
+      return null;
+    }
+  }
+
+  @Override
+  public List<Module> getModules(Long mpackId) {
+    return ambariMetaInfo.getModules(mpackId);
+  }
 
 
   @Override
@@ -766,11 +791,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     m_topologyHolder.get().updateData(getAddedComponentsTopologyEvent(requests));
   }
 
-  @Override
-  public ArrayList<Packlet> getPacklets(Long mpackId) {
-    return ambariMetaInfo.getPacklets(mpackId);
-  }
-
   void persistServiceComponentHosts(Set<ServiceComponentHostRequest> requests, boolean isBlueprintProvisioned)
     throws AmbariException {
     Multimap<Cluster, ServiceComponentHost> schMap = ArrayListMultimap.create();
@@ -3821,6 +3841,11 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     ambariMetaInfo.removeMpack(mpackEntity, stackEntity);
   }
 
+  @Override
+  public Set<ServiceConfigVersionResponse> createServiceConfigVersion(Set<ServiceConfigVersionRequest> requests) throws AmbariException, AuthorizationException {
+    return null;
+  }
+
   /**
    * Get a request response for the given request ids.  Note that this method
    * fully populates a request resource including the set of task sub-resources
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
index a2fc28a..7d44c76 100644
--- 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
@@ -34,14 +34,16 @@ public class MpackResponse {
   private String mpackUri;
   private Long registryId;
   private String stackId;
+  private String description;
 
-  public MpackResponse(Mpack mpacks) {
-    this.mpackId = mpacks.getMpackId();
-    this.mpackVersion = mpacks.getVersion();
-    this.mpackUri = mpacks.getMpacksUri();
-    this.mpackName = mpacks.getName();
-    this.registryId = mpacks.getRegistryId();
-    this.stackId = mpacks.getStackId();
+  public MpackResponse(Mpack mpack) {
+    this.mpackId = mpack.getMpackId();
+    this.mpackVersion = mpack.getVersion();
+    this.mpackUri = mpack.getMpacksUri();
+    this.mpackName = mpack.getName();
+    this.registryId = mpack.getRegistryId();
+    this.stackId = mpack.getStackId();
+    this.description = mpack.getDescription();
   }
 
   public String getMpackVersion() {
@@ -92,6 +94,16 @@ public class MpackResponse {
     this.mpackId = mpackId;
   }
 
+
+  public String getDescription() {
+    return description;
+  }
+
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+
   @Override
   public int hashCode() {
     int result = 1;
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
index 11fe3a8..adae593 100644
--- 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
@@ -55,7 +55,7 @@ import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.MpackEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
-import org.apache.ambari.server.state.Packlet;
+import org.apache.ambari.server.state.Module;
 import org.apache.ambari.server.state.StackId;
 import org.apache.commons.lang.Validate;
 
@@ -74,7 +74,8 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
   public static final String MPACK_NAME = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_name";
   public static final String MPACK_VERSION = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_version";
   public static final String MPACK_URI = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_uri";
-  public static final String PACKLETS = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "packlets";
+  public static final String MODULES = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "modules";
+  public static final String MPACK_DESC = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "description";
   public static final String STACK_NAME_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_name";
   public static final String STACK_VERSION_PROPERTY_ID =
     RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_version";
@@ -108,7 +109,8 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     PROPERTY_IDS.add(MPACK_NAME);
     PROPERTY_IDS.add(MPACK_VERSION);
     PROPERTY_IDS.add(MPACK_URI);
-    PROPERTY_IDS.add(PACKLETS);
+    PROPERTY_IDS.add(MPACK_DESC);
+    PROPERTY_IDS.add(MODULES);
     PROPERTY_IDS.add(STACK_NAME_PROPERTY_ID);
     PROPERTY_IDS.add(STACK_VERSION_PROPERTY_ID);
 
@@ -144,10 +146,11 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         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_URI, response.getMpackUri());
+        resource.setProperty(MPACK_DESC, response.getDescription());
+        resource.setProperty(REGISTRY_ID, response.getRegistryId());
         associatedResources.add(resource);
         return getRequestStatus(null, associatedResources);
       }
@@ -221,17 +224,19 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     Long mpackId = null;
     //Fetch all mpacks
     if (predicate == null) {
-      List<MpackEntity> entities = mpackDAO.findAll();
-      if (null == entities) {
-        entities = Collections.emptyList();
+      // Fetch all mpacks
+      Set<MpackResponse> responses = (HashSet)getManagementController().getMpacks();
+      if (null == responses) {
+        responses = Collections.emptySet();
       }
-      for (MpackEntity entity : entities) {
+      for (MpackResponse response : responses){
         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_URI, entity.getMpackUri());
-        resource.setProperty(REGISTRY_ID, entity.getRegistryId());
+        resource.setProperty(MPACK_ID, response.getMpackId());
+        resource.setProperty(MPACK_NAME, response.getMpackName());
+        resource.setProperty(MPACK_VERSION, response.getMpackVersion());
+        resource.setProperty(MPACK_URI, response.getMpackUri());
+        resource.setProperty(MPACK_DESC, response.getDescription());
+        resource.setProperty(REGISTRY_ID, response.getRegistryId());
         results.add(resource);
       }
     } else {
@@ -243,12 +248,15 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
         mpackId = stackEntity.getCurrentMpackId();
         if (mpackId != null) {
-          MpackEntity entity = mpackDAO.findById(mpackId);
+          MpackResponse response = getManagementController().getMpack(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());
+          if (null != response) {
+            resource.setProperty(MPACK_ID, response.getMpackId());
+            resource.setProperty(MPACK_NAME, response.getMpackName());
+            resource.setProperty(MPACK_VERSION, response.getMpackVersion());
+            resource.setProperty(MPACK_URI, response.getMpackUri());
+            resource.setProperty(MPACK_DESC, response.getDescription());
+            resource.setProperty(REGISTRY_ID, response.getRegistryId());
             resource.setProperty(STACK_NAME_PROPERTY_ID, stackName);
             resource.setProperty(STACK_VERSION_PROPERTY_ID, stackVersion);
             results.add(resource);
@@ -262,18 +270,19 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         if(objMpackId != null)
           mpackId = Long.valueOf((String) objMpackId);
 
-        MpackEntity entity = mpackDAO.findById(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_URI, entity.getMpackUri());
-          resource.setProperty(REGISTRY_ID, entity.getRegistryId());
-          List<Packlet> packlets = getManagementController().getPacklets(entity.getMpackId());
-          resource.setProperty(PACKLETS, packlets);
-          results.add(resource);
-        }
+          MpackResponse response = getManagementController().getMpack(mpackId);
+          Resource resource = new ResourceImpl(Resource.Type.Mpack);
+          if (null != response) {
+            resource.setProperty(MPACK_ID, response.getMpackId());
+            resource.setProperty(MPACK_NAME, response.getMpackName());
+            resource.setProperty(MPACK_VERSION, response.getMpackVersion());
+            resource.setProperty(MPACK_URI, response.getMpackUri());
+            resource.setProperty(MPACK_DESC, response.getDescription());
+            resource.setProperty(REGISTRY_ID, response.getRegistryId());
+            List<Module> modules = getManagementController().getModules(response.getMpackId());
+            resource.setProperty(MODULES, modules);
+            results.add(resource);
+          }
       }
       if (results.isEmpty()) {
         throw new NoSuchResourceException(
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
index 6b19b3c..8a1604c 100644
--- 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
@@ -17,9 +17,30 @@
  */
 package org.apache.ambari.server.mpack;
 
+
 import com.google.gson.Gson;
 import com.google.inject.assistedinject.Assisted;
 import com.google.inject.assistedinject.AssistedInject;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
 import org.apache.ambari.server.controller.MpackRequest;
 import org.apache.ambari.server.controller.MpackResponse;
 import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
@@ -27,31 +48,22 @@ import org.apache.ambari.server.orm.dao.MpackDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.MpackEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
+import org.apache.ambari.server.state.Module;
 import org.apache.ambari.server.state.Mpack;
-import org.apache.ambari.server.state.Packlet;
-import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.stack.StackMetainfoXml;
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+
 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
-import java.nio.file.Paths;
-import java.util.Map;
 import java.util.HashMap;
-import java.util.ArrayList;
-import java.util.List;
-import java.io.File;
-import java.io.OutputStream;
-import java.io.FileInputStream;
-import java.io.BufferedInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
+
 
 
 /**
@@ -67,8 +79,10 @@ public class MpackManager {
   private File stackRoot;
   private static final String MPACK_METADATA = "mpack.json";
   private static final String MPACK_TAR_LOCATION = "staging";
-  private static final String SERVICES_DIRECTORY = "services";
-
+  private static final String MODULES_DIRECTORY = "services";
+  private static final String MIN_JDK_PROPERTY = "min-jdk";
+  private static final String MAX_JDK_PROPERTY = "max-jdk";
+  private static final String DEFAULT_JDK_VALUE = "1.8";
   private final static Logger LOG = LoggerFactory.getLogger(MpackManager.class);
 
   @AssistedInject
@@ -97,6 +111,7 @@ public class MpackManager {
       for (final File dirEntry : mpackStaging.listFiles()) {
         if (dirEntry.isDirectory()) {
           String mpackName = dirEntry.getName();
+          LOG.info("Reading mpack :" + mpackName);
           if (!mpackName.equals(MPACK_TAR_LOCATION)) {
             for (final File file : dirEntry.listFiles()) {
               if (file.isDirectory()) {
@@ -111,6 +126,8 @@ public class MpackManager {
                     "UTF-8");
                   Gson gson = new Gson();
                   Mpack existingMpack = gson.fromJson(mpackJsonContents, Mpack.class);
+                  existingMpack.setMpackId(mpackEntity.getMpackId());
+                  existingMpack.setMpacksUri(mpackEntity.getMpackUri());
                   mpackMap.put(mpackEntity.getMpackId(), existingMpack);
                 }
               }
@@ -123,6 +140,16 @@ public class MpackManager {
     }
   }
 
+
+  public Map<Long, Mpack> getMpackMap() {
+    return mpackMap;
+  }
+
+  public void setMpackMap(Map<Long, Mpack> mpackMap) {
+    this.mpackMap = mpackMap;
+  }
+
+
   /**
    * Parses mpack.json to fetch mpack and associated packlet information and
    * stores the mpack to the database and mpackMap
@@ -150,27 +177,34 @@ public class MpackManager {
       mpackVersion = mpackRequest.getMpackVersion();
       mpack.setRegistryId(mpackRequest.getRegistryId());
 
-      //Todo : Madhu implement GET /registries/{registryId}/mpacks
-      mpackTarPath = downloadMpack(mpackRequest.getMpackUri());
+      LOG.info("Mpack Registration via Registry :" + mpackName);
 
-      if (createMpackDirectory(mpack, mpackTarPath)) {
-        isValidMetadata = validateMpackInfo(mpackName, mpackVersion, mpack.getName(), mpack.getVersion());
-        if (isValidMetadata) {
-          mpackDirectory = mpackStaging + File.separator + mpack.getName() + File.separator + mpack.getVersion();
-        } else {
+      mpack = downloadMpackMetadata(mpackRequest.getMpackUri());
+      isValidMetadata = validateMpackInfo(mpackName, mpackVersion, mpack.getName(), mpack.getVersion());
+
+      if (isValidMetadata) {
+        mpackTarPath = downloadMpack(mpackRequest.getMpackUri(), mpack.getDefinition());
+        createMpackDirectory(mpack);
+        mpackDirectory = mpackStaging + File.separator + mpack.getName() + File.separator + mpack.getVersion();
+      }
+      else {
           String message =
             "Incorrect information : Mismatch in - (" + mpackName + "," + mpack.getName() + ") or (" + mpackVersion
               + "," + mpack.getVersion() + ")";
           throw new IllegalArgumentException(message); //Mismatch in information
         }
-
       }
-    } else {    //Mpack registration using direct download
-      mpackTarPath = downloadMpack(mpackRequest.getMpackUri());
+    //Mpack registration using direct download
+    else {
+      mpack = downloadMpackMetadata(mpackRequest.getMpackUri());
+      mpackTarPath = downloadMpack(mpackRequest.getMpackUri(), mpack.getDefinition());
 
-      if (createMpackDirectory(mpack, mpackTarPath)) {
+      LOG.info("Custom Mpack Registration :" + mpackRequest.getMpackUri());
+
+
+      if (createMpackDirectory(mpack)) {
         mpackDirectory = mpackStaging + File.separator + mpack.getName() + File.separator + mpack.getVersion();
-        mpack.setMpacksUri(mpackRequest.getMpackUri());
+
       }
     }
     extractMpackTar(mpack, mpackTarPath, mpackDirectory);
@@ -189,6 +223,31 @@ public class MpackManager {
   }
 
   /***
+   * Download the mpack.json as a primary step towards providing
+   * meta information about mpack and associated services
+   * @param mpackURI
+   * @return
+   * @throws IOException
+   */
+  private Mpack downloadMpackMetadata(String mpackURI) throws IOException  {
+    URL url = new URL(mpackURI);
+    File stagingDir = new File(mpackStaging.toString() + File.separator + MPACK_TAR_LOCATION);
+    Path targetPath = new File(stagingDir.getPath() + File.separator + MPACK_METADATA).toPath();
+
+    LOG.debug("Download mpack.json and store in :" + targetPath);
+
+    if (!stagingDir.exists()) {
+      stagingDir.mkdir();
+    }
+
+    Files.copy(url.openStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
+    //Read the mpack.json file into Mpack Object for further use.
+    Gson gson = new Gson();
+    Mpack mpack = gson.fromJson(new FileReader(targetPath.toString()), Mpack.class);
+    return mpack;
+  }
+
+  /***
    * A generic method to extract tar files.
    *
    * @param tarPath
@@ -199,6 +258,9 @@ public class MpackManager {
       new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(new File(String.valueOf(tarPath))))));
     TarArchiveEntry entry = null;
     File outputFile = null;
+
+    LOG.debug("Extracting tar file :" + tarFile);
+
     //Create a loop to read every single entry in TAR file
     while ((entry = tarFile.getNextTarEntry()) != null) {
       outputFile = new File(untarDirectory, entry.getName());
@@ -246,9 +308,64 @@ public class MpackManager {
           .substring(mpackTarDirectory.lastIndexOf('/') + 1, mpackTarDirectory.indexOf(".tar")) + File.separator),
         Paths.get(mpackDirectory), StandardCopyOption.REPLACE_EXISTING);
 
+    LOG.debug("Extracting Mpack definitions into :" + extractedMpackDirectory);
+
+    createServicesDirectory(extractedMpackDirectory, mpack);
+
+    File metainfoFile = new File(extractedMpackDirectory + File.separator + "metainfo.xml");
+    // if metainfo.xml doesn't exist in mpack generate it
+    if (!metainfoFile.exists()) {
+      generateMetainfo(metainfoFile, mpack);
+    }
+
     createSymLinks();
   }
 
+  /**
+   * Generate metainfo.xml based on prerequisites of mpack and write it to the mpack directory.
+   * If required properties are missing in prerequisites fill them with default values.
+   *
+   * @param metainfoFile
+   * @param mpack
+   * @throws IOException
+   */
+  private void generateMetainfo(File metainfoFile, Mpack mpack) throws IOException {
+    LOG.info("Generating {} for mpack {}", metainfoFile, mpack.getName());
+    StackMetainfoXml generatedMetainfo = new StackMetainfoXml();
+    StackMetainfoXml.Version version = new StackMetainfoXml.Version();
+    version.setActive(true);
+    generatedMetainfo.setVersion(version);
+
+    Map<String, String> prerequisites = mpack.getPrerequisites();
+    if (prerequisites != null && prerequisites.containsKey(MIN_JDK_PROPERTY)) {
+      generatedMetainfo.setMinJdk(mpack.getPrerequisites().get(MIN_JDK_PROPERTY));
+    } else {
+      //this should not happen if mpack was configured correctly
+      LOG.warn("Couldn't detect {} for mpack {}. Using default value {}", MIN_JDK_PROPERTY, mpack.getName(), DEFAULT_JDK_VALUE);
+      generatedMetainfo.setMinJdk(DEFAULT_JDK_VALUE);
+    }
+    if (prerequisites != null && prerequisites.containsKey(MAX_JDK_PROPERTY)) {
+      generatedMetainfo.setMaxJdk(mpack.getPrerequisites().get(MAX_JDK_PROPERTY));
+    } else {
+      //this should not happen if mpack was configured correctly
+      LOG.warn("Couldn't detect {} for mpack {}. Using default value {}", MAX_JDK_PROPERTY, mpack.getName(), DEFAULT_JDK_VALUE);
+      generatedMetainfo.setMaxJdk(DEFAULT_JDK_VALUE);
+    }
+
+    // Export generatedMetainfo to metainfo.xml
+    try {
+      JAXBContext ctx = JAXBContext.newInstance(StackMetainfoXml.class);
+      Marshaller marshaller = ctx.createMarshaller();
+      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+      FileOutputStream stackMetainfoFileStream = new FileOutputStream(metainfoFile);
+      marshaller.marshal(generatedMetainfo, stackMetainfoFileStream);
+      stackMetainfoFileStream.flush();
+      stackMetainfoFileStream.close();
+    } catch (JAXBException e) {
+      e.printStackTrace();
+    }
+  }
+
   /***
    * Create a services directory and extract all the services tar file inside it. This readies it for cluster deployment
    *
@@ -257,76 +374,52 @@ public class MpackManager {
    * @throws IOException
    */
   private void createServicesDirectory(Path extractedMpackDirectory, Mpack mpack) throws IOException {
-    File servicesDir = new File(extractedMpackDirectory.toAbsolutePath() + File.separator + SERVICES_DIRECTORY );
+    File servicesDir = new File(extractedMpackDirectory.toAbsolutePath() + File.separator + MODULES_DIRECTORY);
     if (!servicesDir.exists()) {
       servicesDir.mkdir();
     }
-    List<Packlet> packlets = mpack.getPacklets();
-
-    for (Packlet packlet : packlets) {
-      //if (packlet.getType() == Packlet.PackletType.SERVICE_PACKLET) {
-        String packletSourceLocation = packlet.getSourceDir();
-        File serviceTargetDir = new File(servicesDir + File.separator + packlet.getName());
-        extractTar(Paths.get(extractedMpackDirectory + File.separator + packlet.getSourceDir()), servicesDir);
-        Path extractedServiceDirectory = Files.move(Paths.get(servicesDir + File.separator + packletSourceLocation
-            .substring(packletSourceLocation.indexOf("/") + 1, packletSourceLocation.indexOf(".tar.gz"))),
-          serviceTargetDir.toPath(), StandardCopyOption.REPLACE_EXISTING);
-      }
+    List<Module> modules = mpack.getModules();
+
+    LOG.info("Creating services directory for mpack :" + mpack.getName());
+
+    for (Module module : modules) {
+      //if (module.getType() == Packlet.PackletType.SERVICE_PACKLET) { //Add back if there is going to be a view packlet
+      String moduleDefinitionLocation = module.getDefinition();
+      File serviceTargetDir = new File(servicesDir + File.separator + module.getName());
+      extractTar(Paths.get(extractedMpackDirectory + File.separator + "modules" + File.separator + moduleDefinitionLocation), servicesDir);
+      Path extractedServiceDirectory = Files.move(Paths.get(servicesDir + File.separator + moduleDefinitionLocation
+                      .substring(moduleDefinitionLocation.indexOf("/") + 1, moduleDefinitionLocation.indexOf(".tar.gz"))),
+              serviceTargetDir.toPath(), StandardCopyOption.REPLACE_EXISTING);
+
     }
+  }
 
 
   /**
-   * Reads the mpack.json file within the {mpack-name}.tar.gz file and populates Mpack object.
-   * Extract the mpack-name and mpack-version from mpack.json to create the new mpack directory to hold the mpack files.
+   * Create the new mpack directory to hold the mpack files.
    *
-   * @param mpackTarPath
+   * @param mpack        Mpack to process
+
    * @return boolean
    * @throws IOException
    */
-  private Boolean createMpackDirectory(Mpack mpack, Path mpackTarPath)
+  private Boolean createMpackDirectory(Mpack mpack)
     throws IOException, ResourceAlreadyExistsException {
+        //Check if the mpack already exists
+        List<MpackEntity> mpackEntities = mpackDAO.findByNameVersion(mpack.getName(), mpack.getVersion());
+        if (mpackEntities.size() == 0) {
+          File mpackDirectory = new File(mpackStaging + File.separator + mpack.getName());
 
-    TarArchiveInputStream mpackTarFile = new TarArchiveInputStream(
-      new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(new File(mpackTarPath.toString())))));
-    TarArchiveEntry entry = null;
-    String individualFiles;
-    int offset;
-    // Create a loop to read every single entry in TAR file
-    while ((entry = mpackTarFile.getNextTarEntry()) != null) {
-      // Get the name of the file
-      individualFiles = entry.getName();
-      String[] dirFile = individualFiles.split(File.separator);
-      //Search for mpack.json
-      String fileName = dirFile[dirFile.length - 1];
-      if (fileName.contains("mpack") && fileName.contains(".json")) {
-        // Get Size of the file and create a byte array for the size
-        byte[] content = new byte[(int) entry.getSize()];
-        offset = 0;
-        LOG.debug("Size of the File is: " + entry.getSize());
-        // Read file from the archive into byte array
-        mpackTarFile.read(content, offset, content.length - offset);
-
-        //Read the mpack.json file into Mpack Object for further use.
-        String mpackJsonContents = new String(content, "UTF-8");
-        Gson gson = new Gson();
-        Mpack tempMpack = gson.fromJson(mpackJsonContents, Mpack.class);
-        mpack.copyFrom(tempMpack);
-
-        mpackTarFile.close();
-
-        File mpackDirectory = new File(mpackStaging + File.separator + mpack.getName());
-        if (!mpackDirectory.exists())
-          return mpackDirectory.mkdir();
-        else
+          if (!mpackDirectory.exists()) {
+            mpackDirectory.mkdir();
+          }
           return true;
         } else {
           String message =
             "Mpack: " + mpack.getName() + " version: " + mpack.getVersion() + " already exists in server";
           throw new ResourceAlreadyExistsException(message);
         }
-      }
-    return false;
-    }
+  }
 
   /***
    * Create a linkage between the staging directory and the working directory i.e from mpacks-v2 to stackRoot.
@@ -335,9 +428,17 @@ public class MpackManager {
    */
   private void createSymLinks() throws IOException {
     String stackId = mpack.getStackId();
-    String[] stackMetaData = stackId.split("-");
-    String stackName = stackMetaData[0];
-    String stackVersion = stackMetaData[1];
+    String stackName = "";
+    String stackVersion = "";
+    if (stackId == null) {
+      stackName = mpack.getName();
+      stackVersion = mpack.getVersion();
+    } else {
+      StackId id = new StackId(stackId);
+      stackName = id.getStackName();
+      stackVersion = id.getStackVersion();
+    }
+    File stack = new File(stackRoot + "/" + stackName);
     Path stackPath = Paths.get(stackRoot + "/" + stackName + "/" + stackVersion);
     Path mpackPath = Paths.get(mpackStaging + "/" + mpack.getName() + "/" + mpack.getVersion());
     if(Files.isSymbolicLink(stackPath))
@@ -349,12 +450,20 @@ public class MpackManager {
    * Download the mpack from the given uri
    *
    * @param mpackURI
+   * @param mpackDefinitionLocation
    * @return
    */
-  public Path downloadMpack(String mpackURI) throws IOException {
-    URL url = new URL(mpackURI);
-    String fileName = mpackURI.substring(mpackURI.lastIndexOf('/') + 1, mpackURI.length());
-    Path targetPath = new File(mpackStaging.toString() + File.separator + MPACK_TAR_LOCATION + File.separator + fileName).toPath();
+  public Path downloadMpack(String mpackURI, String mpackDefinitionLocation) throws IOException {
+
+    File stagingDir = new File(mpackStaging.toString() + File.separator + MPACK_TAR_LOCATION);
+    Path targetPath = new File(stagingDir.getPath() + File.separator + mpackDefinitionLocation).toPath();
+    String mpackTarURI = mpackURI.substring(0, mpackURI.lastIndexOf('/')) + File.separator + mpackDefinitionLocation;
+    URL url = new URL(mpackTarURI);
+
+    if (!stagingDir.exists()) {
+      stagingDir.mkdir();
+    }
+
     Files.copy(url.openStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
 
     return targetPath;
@@ -421,9 +530,16 @@ public class MpackManager {
   protected void populateStackDB(Mpack mpacks) throws IOException {
 
     String stackId = mpack.getStackId();
-    String[] stackMetaData = stackId.split("-");
-    String stackName = stackMetaData[0];
-    String stackVersion = stackMetaData[1];
+    String stackName = "";
+    String stackVersion = "";
+    if (stackId == null) {
+      stackName = mpack.getName();
+      stackVersion = mpack.getVersion();
+    } else {
+      StackId id = new StackId(stackId);
+      stackName = id.getStackName();
+      stackVersion = id.getStackVersion();
+    }
 
     StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
     if (stackEntity == null) {
@@ -441,16 +557,14 @@ public class MpackManager {
   }
 
   /**
-   * Fetches the packlet info stored in the memory for mpacks/{mpack_id} call.
+   * Fetches the mpack info stored in the memory for mpacks/{mpack_id} call.
    *
    * @param mpackId
-   * @return ArrayList
+   * @return list of {@link Module}
    */
-  public ArrayList<Packlet> getPacklets(Long mpackId) {
+  public List<Module> getModules(Long mpackId) {
     Mpack mpack = mpackMap.get(mpackId);
-    if (mpack.getPacklets() != null)
-      return mpack.getPacklets();
-    return null;
+    return mpack.getModules();
   }
 
   /***
@@ -468,6 +582,8 @@ public class MpackManager {
     String mpackName = mpackEntity.getMpackName() + "-" + mpackEntity.getMpackVersion() + ".tar.gz";
     Path mpackTarFile = Paths.get(mpackStaging + File.separator + MPACK_TAR_LOCATION +File.separator + mpackName);
 
+    LOG.info("Removing mpack :" + mpackName);
+
     mpackMap.remove(mpackEntity.getMpackId());
     FileUtils.deleteDirectory(mpackDirToDelete);
 
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
index 72aefa2..f195b0c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
@@ -389,15 +389,19 @@ public class StackDirectory extends StackDefinitionDirectory {
         for (File upgradeFile : f.listFiles(XML_FILENAME_FILTER)) {
           if (upgradeFile.getName().toLowerCase().startsWith(CONFIG_UPGRADE_XML_FILENAME_PREFIX)) {
             if (configUpgradePack == null) {
-              configUpgradePack = parseConfigUpgradePack(upgradeFile);
+              if(upgradeFile.length() != 0) {
+                configUpgradePack = parseConfigUpgradePack(upgradeFile);
+              }
             } else { // If user messed things up with lower/upper case filenames
               throw new AmbariException(String.format("There are multiple files with name like %s" + upgradeFile.getAbsolutePath()));
             }
           } else {
             String upgradePackName = FilenameUtils.removeExtension(upgradeFile.getName());
-            UpgradePack pack = parseUpgradePack(upgradePackName, upgradeFile);
-            pack.setName(upgradePackName);
-            upgradeMap.put(upgradePackName, pack);
+            if(upgradeFile.length() != 0) {
+              UpgradePack pack = parseUpgradePack(upgradePackName, upgradeFile);
+              pack.setName(upgradePackName);
+              upgradeMap.put(upgradePackName, pack);
+            }
           }
         }
       }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Module.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Module.java
new file mode 100644
index 0000000..800a9e0
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Module.java
@@ -0,0 +1,163 @@
+/**
+ * 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 java.util.List;
+import java.util.Objects;
+
+import com.google.gson.annotations.SerializedName;
+
+public class Module {
+  public enum Category {
+    @SerializedName("SERVER")
+    SERVER,
+    @SerializedName("CLIENT")
+    CLIENT,
+    @SerializedName("LIBRARY")
+    LIBRARY
+  }
+
+  @SerializedName("id")
+  private String id;
+  @SerializedName("displayName")
+  private String displayName;
+  @SerializedName("description")
+  private String description;
+  @SerializedName("category")
+  private Category category;
+  @SerializedName("name")
+  private String name;
+  @SerializedName("version")
+  private String version;
+  @SerializedName("definition")
+  private String definition;
+  @SerializedName("dependencies")
+  private List<ModuleDependency> dependencies;
+  @SerializedName("components")
+  private List<ModuleComponent> components;
+
+  public Category getCategory() {
+    return category;
+  }
+
+  public void setType(Category category) {
+    this.category = category;
+  }
+
+  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 getDefinition() {
+    return definition;
+  }
+
+  public void setDefinition(String definition) {
+    this.definition = definition;
+  }
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public String getDisplayName() {
+    return displayName;
+  }
+
+  public void setDisplayName(String displayName) {
+    this.displayName = displayName;
+  }
+
+  public String getDescription() {
+    return description;
+  }
+
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+  public void setCategory(Category category) {
+    this.category = category;
+  }
+
+  public List<ModuleDependency> getDependencies() {
+    return dependencies;
+  }
+
+  public void setDependencies(List<ModuleDependency> dependencies) {
+    this.dependencies = dependencies;
+  }
+
+  public List<ModuleComponent> getComponents() {
+    return components;
+  }
+
+  public void setComponents(List<ModuleComponent> components) {
+    this.components = components;
+  }
+
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    Module module = (Module) o;
+
+    return Objects.equals(id, module.id) && Objects.equals(displayName, module.displayName) &&
+            Objects.equals(description, module.description) && Objects.equals(category, module.category) &&
+            Objects.equals(name, module.name) && Objects.equals(version, module.version) && Objects.equals(definition, module.definition)
+            && Objects.equals(dependencies, module.dependencies) && Objects.equals(components, module.components);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(id, displayName, description, category, name, version, definition, dependencies, components);
+  }
+
+  @Override
+  public String toString() {
+    return "Module{" +
+            "id='" + id + '\'' +
+            ", displayName='" + displayName + '\'' +
+            ", description='" + description + '\'' +
+            ", category=" + category +
+            ", name='" + name + '\'' +
+            ", version='" + version + '\'' +
+            ", definition='" + definition + '\'' +
+            ", dependencies=" + dependencies +
+            ", components=" + components +
+            '}';
+  }
+}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ModuleComponent.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ModuleComponent.java
new file mode 100644
index 0000000..56c82af
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ModuleComponent.java
@@ -0,0 +1,109 @@
+/**
+ * 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 ModuleComponent {
+
+  @SerializedName("id")
+  private String id;
+  @SerializedName("name")
+  private String name;
+  @SerializedName("category")
+  private String category;
+  @SerializedName("isExternal")
+  private Boolean isExternal;
+  @SerializedName("version")
+  private String version;
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public String getCategory() {
+    return category;
+  }
+
+  public void setCategory(String category) {
+    this.category = category;
+  }
+
+
+  public String getVersion() {
+    return version;
+  }
+
+  public void setVersion(String version) {
+    this.version = version;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+  public Boolean getIsExternal() {
+    return isExternal;
+  }
+
+  public void setIsExternal(Boolean isExternal) {
+    this.isExternal = isExternal;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ModuleComponent that = (ModuleComponent) o;
+
+    if (id != null ? !id.equals(that.id) : that.id != null) return false;
+    if (name != null ? !name.equals(that.name) : that.name != null) return false;
+    if (category != null ? !category.equals(that.category) : that.category != null) return false;
+    if (isExternal != null ? !isExternal.equals(that.isExternal) : that.isExternal != null) return false;
+    return version != null ? version.equals(that.version) : that.version == null;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = id != null ? id.hashCode() : 0;
+    result = 31 * result + (name != null ? name.hashCode() : 0);
+    result = 31 * result + (category != null ? category.hashCode() : 0);
+    result = 31 * result + (isExternal != null ? isExternal.hashCode() : 0);
+    result = 31 * result + (version != null ? version.hashCode() : 0);
+    return result;
+  }
+
+  @Override
+  public String toString() {
+    return "ModuleComponent{" +
+            "id='" + id + '\'' +
+            ", name='" + name + '\'' +
+            ", category='" + category + '\'' +
+            ", isExternal=" + isExternal +
+            ", version='" + version + '\'' +
+            '}';
+  }
+}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ModuleDependency.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ModuleDependency.java
new file mode 100644
index 0000000..bdce407
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ModuleDependency.java
@@ -0,0 +1,88 @@
+/**
+ * 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 ModuleDependency {
+  @SerializedName("id")
+  private String id;
+  @SerializedName("name")
+  private String name;
+  public enum DependencyType {
+    @SerializedName("RUNTIME")
+    RUNTIME,
+    @SerializedName("INSTALL")
+    INSTALL
+  }
+  @SerializedName("dependencyType")
+  private DependencyType dependencyType;
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public DependencyType getDependencyType() {
+    return dependencyType;
+  }
+
+  public void setDependencyType(DependencyType dependencyType) {
+    this.dependencyType = dependencyType;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ModuleDependency that = (ModuleDependency) o;
+
+    if (id != null ? !id.equals(that.id) : that.id != null) return false;
+    if (name != null ? !name.equals(that.name) : that.name != null) return false;
+    return dependencyType != null ? dependencyType.equals(that.dependencyType) : that.dependencyType == null;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = id != null ? id.hashCode() : 0;
+    result = 31 * result + (name != null ? name.hashCode() : 0);
+    result = 31 * result + (dependencyType != null ? dependencyType.hashCode() : 0);
+    return result;
+  }
+
+  @Override
+  public String toString() {
+    return "ModuleDependency{" +
+            "id='" + id + '\'' +
+            ", name='" + name + '\'' +
+            ", dependencyType='" + dependencyType + '\'' +
+            '}';
+  }
+}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
index 83470ea..1bdd394 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
@@ -19,8 +19,8 @@ package org.apache.ambari.server.state;
 
 import com.google.gson.annotations.SerializedName;
 
-import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 
 /**
  * Represents the state of an mpack.
@@ -37,19 +37,31 @@ public class Mpack {
   @SerializedName("version")
   private String version;
 
-  @SerializedName("description")
-  private String description;
+  @SerializedName("artifacts-path")
+  private String artifactsPath;
 
   @SerializedName("prerequisites")
   private HashMap<String, String> prerequisites;
 
-  @SerializedName("packlets")
-  private ArrayList<Packlet> packlets;
+  @SerializedName("modules")
+  private List<Module> modules;
+
+  @SerializedName("modules-path")
+  private String modulesPath;
+
+  @SerializedName("mpack-path")
+  private String mpackPath;
 
   @SerializedName("stack-id")
   private String stackId;
 
-  private String mpacksUri;
+  @SerializedName("definition")
+  private String definition;
+
+  @SerializedName("description")
+  private String description;
+
+  private String mpackUri;
 
   public Long getMpackId() {
     return mpackId;
@@ -68,11 +80,11 @@ public class Mpack {
   }
 
   public String getMpacksUri() {
-    return mpacksUri;
+    return mpackUri;
   }
 
   public void setMpacksUri(String mpacksUri) {
-    this.mpacksUri = mpacksUri;
+    this.mpackUri = mpacksUri;
   }
 
   public String getName() {
@@ -107,15 +119,14 @@ public class Mpack {
     this.prerequisites = prerequisites;
   }
 
-  public ArrayList<Packlet> getPacklets() {
-    return packlets;
+  public List<Module> getModules() {
+    return modules;
   }
 
-  public void setPacklets(ArrayList<Packlet> packlets) {
-    this.packlets = packlets;
+  public void setModules(List<Module> modules) {
+    this.modules = modules;
   }
 
-
   public String getStackId() {
     return stackId;
   }
@@ -124,129 +135,96 @@ public class Mpack {
     this.stackId = stackId;
   }
 
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    result = prime * result + ((mpackId == null) ? 0 : mpackId.hashCode());
-    result = prime * result + ((name == null) ? 0 : name.hashCode());
-    result = prime * result + ((version == null) ? 0 : version.hashCode());
-    result = prime * result + ((registryId == null) ? 0 : registryId.hashCode());
-    result = prime * result + ((description == null) ? 0 : description.hashCode());
-    result = prime * result + ((prerequisites == null) ? 0 : prerequisites.hashCode());
-    result = prime * result + ((packlets == null) ? 0 : packlets.hashCode());
-    result = prime * result + ((stackId == null) ? 0 : stackId.hashCode());
-    result = prime * result + ((mpacksUri == null) ? 0 : mpacksUri.hashCode());
-    return result;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public boolean equals(Object obj) {
-    if (this == obj) {
-      return true;
-    }
-
-    if (obj == null) {
-      return false;
-    }
-
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
 
-    Mpack other = (Mpack) obj;
-
-    if (name != other.name) {
-      return false;
-    }
+  public String getArtifactsPath() {
+    return artifactsPath;
+  }
 
-    if (version == null) {
-      if (other.version != null) {
-        return false;
-      }
-    } else if (!version.equals(other.version)) {
-      return false;
-    }
+  public void setArtifactsPath(String artifactsPath) {
+    this.artifactsPath = artifactsPath;
+  }
 
-    if (description == null) {
-      if (other.description != null) {
-        return false;
-      }
-    } else if (!description.equals(other.description)) {
-      return false;
-    }
+  public String getModulesPath() {
+    return modulesPath;
+  }
 
-    if (mpackId == null) {
-      if (other.mpackId != null) {
-        return false;
-      }
-    } else if (!mpackId.equals(other.mpackId)) {
-      return false;
-    }
+  public void setModulesPath(String modulesPath) {
+    this.modulesPath = modulesPath;
+  }
 
-    if (registryId == null) {
-      if (other.registryId != null) {
-        return false;
-      }
-    } else if (!registryId.equals(other.registryId)) {
-      return false;
-    }
+  public String getMpackPath() {
+    return mpackPath;
+  }
 
-    if (prerequisites == null) {
-      if (other.prerequisites != null) {
-        return false;
-      }
-    } else if (!prerequisites.equals(other.prerequisites)) {
-      return false;
-    }
+  public void setMpackPath(String mpackPath) {
+    this.mpackPath = mpackPath;
+  }
 
-    if (packlets == null) {
-      if (other.packlets != null) {
-        return false;
-      }
-    } else if (!packlets.equals(other.packlets)) {
-      return false;
-    }
+  public String getDefinition() {
+    return definition;
+  }
 
-    if (mpacksUri == null) {
-      if (other.mpacksUri != null) {
-        return false;
-      }
-    } else if (!mpacksUri.equals(other.mpacksUri)) {
-      return false;
-    }
+  public void setDefinition(String definition) {
+    this.definition = definition;
+  }
 
-    if (stackId == null) {
-      if (other.stackId != null) {
-        return false;
-      }
-    } else if (!stackId.equals(other.stackId)) {
-      return false;
-    }
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    Mpack mpack = (Mpack) o;
+
+    if (!mpackId.equals(mpack.mpackId)) return false;
+    if (registryId != null ? !registryId.equals(mpack.registryId) : mpack.registryId != null) return false;
+    if (!name.equals(mpack.name)) return false;
+    if (!version.equals(mpack.version)) return false;
+    if (!artifactsPath.equals(mpack.artifactsPath)) return false;
+    if (!prerequisites.equals(mpack.prerequisites)) return false;
+    if (!modules.equals(mpack.modules)) return false;
+    if (!modulesPath.equals(mpack.modulesPath)) return false;
+    if (!mpackPath.equals(mpack.mpackPath)) return false;
+    if (!stackId.equals(mpack.stackId)) return false;
+    if (!definition.equals(mpack.definition)) return false;
+    if (!description.equals(mpack.description)) return false;
+    return mpackUri.equals(mpack.mpackUri);
+  }
 
-    return true;
+  @Override
+  public int hashCode() {
+    int result = mpackId.hashCode();
+    result = 31 * result + (registryId != null ? registryId.hashCode() : 0);
+    result = 31 * result + name.hashCode();
+    result = 31 * result + version.hashCode();
+    result = 31 * result + artifactsPath.hashCode();
+    result = 31 * result + prerequisites.hashCode();
+    result = 31 * result + modules.hashCode();
+    result = 31 * result + modulesPath.hashCode();
+    result = 31 * result + mpackPath.hashCode();
+    result = 31 * result + stackId.hashCode();
+    result = 31 * result + definition.hashCode();
+    result = 31 * result + description.hashCode();
+    result = 31 * result + mpackUri.hashCode();
+    return result;
   }
 
   @Override
   public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append('{');
-    sb.append("name=").append(name).append(", ");
-    sb.append("mpackId=").append(mpackId).append(", ");
-    sb.append("version=").append(version).append(", ");
-    sb.append("stackid=").append(stackId).append(", ");
-    sb.append("registryId=").append(registryId).append(", ");
-    sb.append("description=").append(description).append(", ");
-    sb.append("prereq=").append(prerequisites.toString()).append(", ");
-    sb.append("packlets=").append(packlets.toString()).append(", ");
-        sb.append('}');
-    return sb.toString();
+    return "Mpack{" +
+            "mpackId=" + mpackId +
+            ", registryId=" + registryId +
+            ", name='" + name + '\'' +
+            ", version='" + version + '\'' +
+            ", artifactsPath='" + artifactsPath + '\'' +
+            ", prerequisites=" + prerequisites +
+            ", modules=" + modules +
+            ", modulesPath='" + modulesPath + '\'' +
+            ", mpackPath='" + mpackPath + '\'' +
+            ", stackId='" + stackId + '\'' +
+            ", definition='" + definition + '\'' +
+            ", description='" + description + '\'' +
+            ", mpackUri='" + mpackUri + '\'' +
+            '}';
   }
 
   public void copyFrom(Mpack mpack) {
@@ -256,16 +234,30 @@ public class Mpack {
       this.mpackId = mpack.getMpackId();
     if (this.version == null)
       this.version = mpack.getVersion();
-    if (this.stackId == null)
+    if (this.stackId == null) {
       this.stackId = mpack.getStackId();
     if (this.registryId == null)
       this.registryId = mpack.getRegistryId();
     if (this.description == null)
       this.description = mpack.getDescription();
-    if (this.prerequisites == null)
+    }
+    if (this.modules == null) {
+      this.modules = mpack.getModules();
+    }
+    if (this.artifactsPath == null) {
+      this.artifactsPath = mpack.getArtifactsPath();
+    }
+    if (this.prerequisites == null) {
       this.prerequisites = mpack.getPrerequisites();
-    if (this.packlets == null)
-      this.packlets = mpack.getPacklets();
-
+    }
+    if (this.modulesPath == null) {
+      this.modulesPath = mpack.getModulesPath();
+    }
+    if (this.mpackPath == null) {
+      this.mpackPath = mpack.getMpackPath();
+    }
+    if (this.definition == null) {
+      this.definition = mpack.getDefinition();
+    }
   }
 }
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
deleted file mode 100644
index 1fa8dee..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Packlet.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * 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("service-id")
-  private String serviceId;
-  @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;
-  }
-
-
-  public String getServiceId() {
-    return serviceId;
-  }
-
-  public void setServiceId(String serviceId) {
-    this.serviceId = serviceId;
-  }
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    result = prime * result + ((type == null) ? 0 : type.hashCode());
-    result = prime * result + ((name == null) ? 0 : name.hashCode());
-    result = prime * result + ((version == null) ? 0 : version.hashCode());
-    result = prime * result + ((serviceId == null) ? 0 : serviceId.hashCode());
-    result = prime * result + ((sourceDir == null) ? 0 : sourceDir.hashCode());
-    return result;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public boolean equals(Object obj) {
-    if (this == obj) {
-      return true;
-    }
-
-    if (obj == null) {
-      return false;
-    }
-
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
-
-    Packlet other = (Packlet) obj;
-
-    if (type != other.type) {
-      return false;
-    }
-
-    if (name == null) {
-      if (other.name != null) {
-        return false;
-      }
-    } else if (!name.equals(other.name)) {
-      return false;
-    }
-
-    if (version == null) {
-      if (other.version != null) {
-        return false;
-      }
-    } else if (!version.equals(other.version)) {
-      return false;
-    }
-
-    if (serviceId == null) {
-      if (other.serviceId != null) {
-        return false;
-      }
-    } else if (!serviceId.equals(other.serviceId)) {
-      return false;
-    }
-
-    if (sourceDir == null) {
-      if (other.sourceDir != null) {
-        return false;
-      }
-    } else if (!sourceDir.equals(other.sourceDir)) {
-      return false;
-    }
-    return true;
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append('{');
-    sb.append("type=").append(type).append(", ");
-    sb.append("name=").append(name).append(", ");
-    sb.append("version=").append(version).append(", ");
-    sb.append("service id=").append(serviceId).append(", ");
-    sb.append("source directory=").append(sourceDir).append(", ");
-    sb.append('}');
-    return sb.toString();
-  }
-
-}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/StackMetainfoXml.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/StackMetainfoXml.java
index 753c2b8..be2a45c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/StackMetainfoXml.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/StackMetainfoXml.java
@@ -108,10 +108,22 @@ public class StackMetainfoXml implements Validable{
   public Version getVersion() {
     return version;
   }
-  
+
+  public void setVersion(Version version) {
+    this.version = version;
+  }
+
+  public void setMinJdk(String minJdk) {
+    this.minJdk = minJdk;
+  }
+
+  public void setMaxJdk(String maxJdk) {
+    this.maxJdk = maxJdk;
+  }
+
   @XmlAccessorType(XmlAccessType.FIELD)
   public static class Version {
-    private Version() {
+    public Version() {
     }
     private boolean active = false;
     private String upgrade = null;
@@ -129,8 +141,11 @@ public class StackMetainfoXml implements Validable{
     public String getUpgrade() {
       return upgrade;
     }
-    
-    
+
+
+    public void setActive(boolean active) {
+      this.active = active;
+    }
   }  
   
 }
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
index ac4ceb9..f30e030 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
@@ -46,8 +46,7 @@ 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.Mpacks;
-import org.apache.ambari.server.state.Packlet;
+import org.apache.ambari.server.state.Mpack;
 import static org.easymock.EasyMock.anyBoolean;
 import static org.easymock.EasyMock.anyLong;
 import static org.easymock.EasyMock.anyObject;
@@ -116,6 +115,8 @@ import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.Module;
+import org.apache.ambari.server.state.Mpack;
 import org.apache.ambari.server.state.PropertyInfo;
 import org.apache.ambari.server.state.RepositoryInfo;
 import org.apache.ambari.server.state.SecurityType;
@@ -143,7 +144,6 @@ import com.google.gson.Gson;
 import com.google.inject.Binder;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-import com.google.inject.Module;
 import com.google.inject.Provider;
 import com.google.inject.util.Modules;
 
@@ -2270,7 +2270,7 @@ public class AmbariManagementControllerImplTest {
     f.set(controller, metaInfo);
   }
 
-  private class MockModule implements Module {
+  private class MockModule implements com.google.inject.Module {
 
     @Override
     public void configure(Binder binder) {
@@ -2450,16 +2450,17 @@ public class AmbariManagementControllerImplTest {
   @Test
   public void testRegisterMpacks() throws Exception{
     MpackRequest mpackRequest = createNiceMock(MpackRequest.class);
-    Mpacks mpacks = new Mpacks();
-    mpacks.setMpackId((long)100);
-    mpacks.setPacklets(new ArrayList<Packlet>());
-    mpacks.setPrerequisites(new HashMap<String, String>());
-    mpacks.setRegistryId(new Long(100));
-    mpacks.setVersion("3.0");
-    mpacks.setMpacksUri("abc.tar.gz");
-    mpacks.setDescription("Test mpacks");
-    mpacks.setName("testMpack");
-    MpackResponse mpackResponse = new MpackResponse(mpacks);
+    RequestStatusResponse response = new RequestStatusResponse(new Long(201));
+    Mpack mpack = new Mpack();
+    mpack.setMpackId((long)100);
+    mpack.setModules(new ArrayList<Module>());
+    mpack.setPrerequisites(new HashMap<String, String>());
+    mpack.setRegistryId(new Long(100));
+    mpack.setVersion("3.0");
+    mpack.setMpacksUri("abc.tar.gz");
+    mpack.setDescription("Test mpack");
+    mpack.setName("testMpack");
+    MpackResponse mpackResponse = new MpackResponse(mpack);
     Injector injector = createNiceMock(Injector.class);
     expect(injector.getInstance(MaintenanceStateHelper.class)).andReturn(null).atLeastOnce();
     expect(ambariMetaInfo.registerMpack(mpackRequest)).andReturn(mpackResponse);
@@ -2472,21 +2473,21 @@ public class AmbariManagementControllerImplTest {
   @Test
   public void testGetPacklets() throws Exception {
     Long mpackId = new Long(100);
-    ArrayList<Packlet> packletArrayList = new ArrayList<>();
-    Packlet samplePacklet = new Packlet();
+    ArrayList<Module> packletArrayList = new ArrayList<>();
+    Module samplePacklet = new Module();
     Injector injector = createNiceMock(Injector.class);
-    samplePacklet.setType("service");
+    //samplePacklet.setType(Packlet.PackletType.SERVICE_PACKLET);
     samplePacklet.setVersion("3.0.0");
     samplePacklet.setName("NIFI");
-    samplePacklet.setSourceDir("/abc/nifi.tar.gz");
+    samplePacklet.setDefinition("nifi.tar.gz");
     packletArrayList.add(samplePacklet);
     expect(injector.getInstance(MaintenanceStateHelper.class)).andReturn(null).atLeastOnce();
-    expect(ambariMetaInfo.getPacklets(mpackId)).andReturn(packletArrayList).atLeastOnce();
+    expect(ambariMetaInfo.getModules(mpackId)).andReturn(packletArrayList).atLeastOnce();
     replay(ambariMetaInfo,injector);
     AmbariManagementController controller = new AmbariManagementControllerImpl(null, clusters, injector);
     setAmbariMetaInfo(ambariMetaInfo, controller);
 
-    Assert.assertEquals(packletArrayList,controller.getPacklets(mpackId));
+    Assert.assertEquals(packletArrayList,controller.getModules(mpackId));
 
   }
 
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java
index c61d515..22bcce7 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/MpackResponseTest.java
@@ -17,8 +17,13 @@
  */
 package org.apache.ambari.server.controller;
 
-import org.apache.ambari.server.state.Mpacks;
-import org.apache.ambari.server.state.Packlet;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.apache.ambari.server.state.Module;
+import org.apache.ambari.server.state.Mpack;
+import org.junit.Assert;
 import org.junit.Test;
 import org.junit.Assert;
 import java.util.ArrayList;
@@ -30,7 +35,7 @@ import java.util.HashMap;
 public class MpackResponseTest {
   @Test
   public void testBasicGetAndSet() {
-    MpackResponse mpackResponse = new MpackResponse(setupMpacks());
+    MpackResponse mpackResponse = new MpackResponse(setupMpack());
     Assert.assertEquals(new Long(100), mpackResponse.getMpackId());
     Assert.assertEquals("100",mpackResponse.getRegistryId());
     Assert.assertEquals("3.0",mpackResponse.getMpackVersion());
@@ -38,17 +43,18 @@ public class MpackResponseTest {
     Assert.assertEquals("testMpack", mpackResponse.getMpackName());
 
   }
-  public Mpacks setupMpacks(){
-    Mpacks mpacks = new Mpacks();
-    mpacks.setMpackId((long)100);
-    mpacks.setPacklets(new ArrayList<Packlet>());
-    mpacks.setPrerequisites(new HashMap<String, String>());
-    mpacks.setRegistryId(new Long(100));
-    mpacks.setVersion("3.0");
-    mpacks.setMpacksUri("abc.tar.gz");
-    mpacks.setDescription("Test mpacks");
-    mpacks.setName("testMpack");
 
-    return mpacks;
+  public Mpack setupMpack() {
+    Mpack mpack = new Mpack();
+    mpack.setMpackId(100L);
+    mpack.setModules(new ArrayList<Module>());
+    mpack.setPrerequisites(new HashMap<String, String>());
+    mpack.setRegistryId(100L);
+    mpack.setVersion("3.0");
+    mpack.setMpacksUri("abc.tar.gz");
+    mpack.setDescription("Test mpack");
+    mpack.setName("testMpack");
+
+    return mpack;
   }
 }
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
index 944e40d..f3b5aad 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
@@ -17,6 +17,8 @@
  */
 package org.apache.ambari.server.controller.internal;
 
+import com.google.inject.util.Modules;
+import org.apache.ambari.server.state.Module;
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
@@ -33,8 +35,7 @@ import java.util.Set;
 import com.google.inject.Injector;
 import com.google.inject.Binder;
 import com.google.inject.Guice;
-import com.google.inject.util.Modules;
-import com.google.inject.Module;
+
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.MpackResponse;
 import org.apache.ambari.server.controller.spi.Resource;
@@ -46,8 +47,8 @@ import org.apache.ambari.server.controller.utilities.*;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 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.apache.ambari.server.state.Mpack;
+
 import org.easymock.EasyMock;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.createMock;
@@ -56,6 +57,10 @@ import org.junit.Test;
 import org.junit.Assert;
 import org.junit.Before;
 
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
 
 import javax.persistence.EntityManager;
 import java.util.ArrayList;
@@ -168,13 +173,13 @@ public class MpackResourceProviderTest {
     entity.setMpackVersion("3.0");
 
 
-    ArrayList<Packlet> packletArrayList = new ArrayList<>();
-    Packlet packlet = new Packlet();
-    packlet.setName("testService");
-    packlet.setType("service");
-    packlet.setSourceDir("testDir/testDir");
-    packlet.setVersion("3.0");
-    packletArrayList.add(packlet);
+    ArrayList<Module> packletArrayList = new ArrayList<>();
+    org.apache.ambari.server.state.Module module = new Module();
+    module.setName("testService");
+    //module.setType(Module.PackletType.SERVICE_PACKLET);
+    module.setDefinition("testDir");
+    module.setVersion("3.0");
+    packletArrayList.add(module);
 
     Resource resourceExpected1 = new ResourceImpl(Resource.Type.Mpack);
     resourceExpected1.setProperty(MpackResourceProvider.MPACK_ID, (long)1);
@@ -182,11 +187,11 @@ public class MpackResourceProviderTest {
     resourceExpected1.setProperty(MpackResourceProvider.MPACK_VERSION, "3.0");
     resourceExpected1.setProperty(MpackResourceProvider.MPACK_URI, "abcd.tar.gz");
     resourceExpected1.setProperty(MpackResourceProvider.REGISTRY_ID, null);
-    resourceExpected1.setProperty(MpackResourceProvider.PACKLETS,packletArrayList);
+    resourceExpected1.setProperty(MpackResourceProvider.MODULES,packletArrayList);
 
     // set expectations
     EasyMock.expect(m_dao.findById((long)1)).andReturn(entity).anyTimes();
-    EasyMock.expect(m_amc.getPacklets((long)1)).andReturn(packletArrayList).anyTimes();
+    EasyMock.expect(m_amc.getModules((long)1)).andReturn(packletArrayList).anyTimes();
 
     // replay
     replay(m_dao,m_amc);
@@ -206,7 +211,7 @@ public class MpackResourceProviderTest {
       Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.MPACK_VERSION), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_VERSION));
       Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.MPACK_URI), (String) resource.getPropertyValue(MpackResourceProvider.MPACK_URI));
       Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.REGISTRY_ID), (Long) resource.getPropertyValue(MpackResourceProvider.REGISTRY_ID));
-      Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.PACKLETS),(ArrayList)resource.getPropertyValue(MpackResourceProvider.PACKLETS));
+      Assert.assertEquals(resourceExpected1.getPropertyValue(MpackResourceProvider.MODULES),(ArrayList)resource.getPropertyValue(MpackResourceProvider.MODULES));
   }
     // verify
     verify(m_dao,m_amc);
@@ -231,9 +236,9 @@ public class MpackResourceProviderTest {
     replay(m_amc,request);
     // end expectations
 
-    ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
-            Resource.Type.Mpack 
-            );
+    MpackResourceProvider provider = (MpackResourceProvider) AbstractControllerResourceProvider.getResourceProvider(
+            Resource.Type.Mpack);
+
 
     AbstractResourceProviderTest.TestObserver observer = new AbstractResourceProviderTest.TestObserver();
     ((ObservableResourceProvider)provider).addObserver(observer);
@@ -259,10 +264,10 @@ public class MpackResourceProviderTest {
   }
 
 
-  public Mpacks setupMpack() {
-    Mpacks mpack = new Mpacks();
+  public Mpack setupMpack() {
+    Mpack mpack = new Mpack();
     mpack.setMpackId((long)100);
-    mpack.setPacklets(new ArrayList<Packlet>());
+    mpack.setModules(new ArrayList<Module>());
     mpack.setPrerequisites(new HashMap<String, String>());
     mpack.setRegistryId(new Long(100));
     mpack.setVersion("3.0");
@@ -276,7 +281,7 @@ public class MpackResourceProviderTest {
   /**
    *
    */
-  private class MockModule implements Module {
+  private class MockModule implements com.google.inject.Module {
     @Override
     public void configure(Binder binder) {
       binder.bind(EntityManager.class).toInstance(EasyMock.createMock(EntityManager.class));
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
index f21ca64..c561a7a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
@@ -47,50 +47,82 @@ public class MpackTest {
   @Test
   public void testMpacksUsingGson() {
     String mpackJsonContents = "{\n" +
-            "  \"name\" : \"hdf-ambari-mpack\",\n" +
-            "  \"version\": \"3.0.0.0-111\",\n" +
-            "  \"description\" : \"HDF 3.0.0 Ambari Management Pack\",\n" +
-            "  \"prerequisites\": {\n" +
-            "    \"min-ambari-version\" : \"3.0.0.0\"\n" +
-            "  },\n" +
-            "  \"packlets\": [\n" +
-            "    {\n" +
-            "      \"type\" : \"service-packlet\",\n" +
-            "      \"name\" : \"NIFI\",\n" +
-            "      \"version\" : \"1.2.0.0-123\",\n" +
-            "      \"source_location\": \"packlets/NIFI-1.2.0.0-123.tar.gz\"\n" +
-            "    },\n" +
+            "  \"definition\": \"hdpcore-1.0.0-b16-definition.tar.gz\",\n" +
+            "  \"description\": \"Hortonworks Data Platform Core\",\n" +
+            "  \"id\": \"hdpcore\",\n" +
+            "  \"modules\": [\n" +
             "    {\n" +
-            "      \"type\" : \"service-packlet\",\n" +
-            "      \"name\" : \"STREAMLINE\",\n" +
-            "      \"version\" : \"1.0.0.0-100\",\n" +
-            "      \"source_location\": \"packlets/STREAMLINE-1.0.0.0-100.tar.gz\"\n" +
+            "      \"category\": \"SERVER\",\n" +
+            "      \"components\": [\n" +
+            "        {\n" +
+            "          \"id\": \"zookeeper_server\",\n" +
+            "          \"version\": \"3.4.0.0-b17\",\n" +
+            "          \"name\": \"ZOOKEEPER_SERVER\",\n" +
+            "          \"category\": \"MASTER\",\n" +
+            "          \"isExternal\": \"False\"\n" +
+            "        }\n" +
+            "      ],\n" +
+            "      \"definition\": \"zookeeper-3.4.0.0-b17-definition.tar.gz\",\n" +
+            "      \"dependencies\": [\n" +
+            "        {\n" +
+            "          \"id\": \"zookeeper_clients\",\n" +
+            "          \"name\": \"ZOOKEEPER_CLIENTS\",\n" +
+            "          \"dependencyType\": \"INSTALL\"\n" +
+            "        }\n" +
+            "      ],\n" +
+            "      \"description\": \"Centralized service which provides highly reliable distributed coordination\",\n" +
+            "      \"displayName\": \"ZooKeeper\",\n" +
+            "      \"id\": \"zookeeper\",\n" +
+            "      \"name\": \"ZOOKEEPER\",\n" +
+            "      \"version\": \"3.4.0.0-b17\"\n" +
             "    }\n" +
-            "  ]\n" +
-            "}\n";
+            "  ],\n" +
+            "  \"name\": \"HDPCORE\",\n" +
+            "  \"prerequisites\": {\n" +
+            "    \"max-ambari-version\": \"3.1.0.0\",\n" +
+            "    \"min-ambari-version\": \"3.0.0.0\"\n" +
+            "  },\n" +
+            "  \"version\": \"1.0.0-b16\"\n" +
+            "}";
     HashMap<String, String> expectedPrereq = new HashMap<>();
     expectedPrereq.put("min-ambari-version","3.0.0.0");
-    ArrayList<Packlet> expectedPacklets = new ArrayList<>();
-    Packlet nifi = new Packlet();
-    nifi.setType("SERVICE_PACKLET");
-    nifi.setVersion("1.2.0.0-123");
-    nifi.setSourceLocation("packlets/NIFI-1.2.0.0-123.tar.gz");
-    nifi.setName("NIFI");
-    Packlet streamline = new Packlet();
-    streamline.setName("STREAMLINE");
-    streamline.setType(Packlet.PackletType.SERVICE_PACKLET);
-    streamline.setSourceLocation("packlets/STREAMLINE-1.0.0.0-100.tar.gz");
-    streamline.setVersion("1.0.0.0-100");
-    expectedPacklets.add(nifi);
-    expectedPacklets.add(streamline);
+
+    expectedPrereq.put("max-ambari-version","3.1.0.0");
+    ArrayList<Module> expectedModules = new ArrayList<>();
+    Module zkfc = new Module();
+    //nifi.setType(.PackletType.SERVICE_PACKLET);
+    zkfc.setVersion("3.4.0.0-b17");
+    zkfc.setDefinition("zookeeper-3.4.0.0-b17-definition.tar.gz");
+    zkfc.setName("ZOOKEEPER");
+    zkfc.setId("zookeeper");
+    zkfc.setDisplayName("ZooKeeper");
+    zkfc.setDescription("Centralized service which provides highly reliable distributed coordination");
+    zkfc.setCategory(Module.Category.SERVER);
+    ModuleDependency moduleDependency = new ModuleDependency();
+    moduleDependency.setId("zookeeper_clients");
+    moduleDependency.setName("ZOOKEEPER_CLIENTS");
+    moduleDependency.setDependencyType(ModuleDependency.DependencyType.INSTALL);
+    ArrayList moduleDepList = new ArrayList();
+    moduleDepList.add(moduleDependency);
+    zkfc.setDependencies(moduleDepList);
+    ArrayList compList = new ArrayList();
+    ModuleComponent zk_server = new ModuleComponent();
+    zk_server.setId("zookeeper_server");
+    zk_server.setName("ZOOKEEPER_SERVER");
+    zk_server.setCategory("MASTER");
+    zk_server.setIsExternal(Boolean.FALSE);
+    zk_server.setVersion("3.4.0.0-b17");
+    compList.add(zk_server);
+    zkfc.setComponents(compList);
+    expectedModules.add(zkfc);
 
     Gson gson = new Gson();
     Mpack mpack = gson.fromJson(mpackJsonContents, Mpack.class);
-    Assert.assertEquals("hdf-ambari-mpack", mpack.getName());
-    Assert.assertEquals("3.0.0.0-111", mpack.getVersion());
-    Assert.assertEquals("HDF 3.0.0 Ambari Management Pack", mpack.getDescription());
+    Assert.assertEquals("HDPCORE", mpack.getName());
+    Assert.assertEquals("1.0.0-b16", mpack.getVersion());
+    Assert.assertEquals("Hortonworks Data Platform Core", mpack.getDescription());
     Assert.assertEquals(expectedPrereq, mpack.getPrerequisites());
-    Assert.assertEquals(expectedPacklets.toString(), mpack.getPacklets().toString());
+    Assert.assertEquals(expectedModules.toString(), mpack.getModules().toString());
   }
 
 }


[ambari] 18/20: [AMBARI-23254] Mpack should have both displayName and description

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 9360b63c8f12a969f1131268c225d5890bee36cf
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Thu Mar 15 14:40:47 2018 -0700

    [AMBARI-23254] Mpack should have both displayName and description
---
 .../ambari/server/controller/MpackResponse.java    | 10 +++
 .../controller/internal/MpackResourceProvider.java | 23 ++++++
 .../java/org/apache/ambari/server/state/Mpack.java | 96 +++++++++++++++++-----
 3 files changed, 108 insertions(+), 21 deletions(-)

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
index bc1e47d..70ddabe 100644
--- 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
@@ -36,6 +36,7 @@ public class MpackResponse {
   private Long registryId;
   private String stackId;
   private String description;
+  private String displayName;
 
   public MpackResponse(Mpack mpack) {
     this.id = mpack.getResourceId();
@@ -45,6 +46,7 @@ public class MpackResponse {
     this.mpackUri = mpack.getMpackUri();
     this.registryId = mpack.getRegistryId();
     this.description = mpack.getDescription();
+    this.displayName = mpack.getDisplayName();
   }
 
   public Long getId() {
@@ -111,6 +113,14 @@ public class MpackResponse {
     this.stackId = stackId;
   }
 
+  public String getDisplayName() {
+    return displayName;
+  }
+
+  public void setDisplayName(String displayName) {
+    this.displayName = displayName;
+  }
+
   @Override
   public int hashCode() {
     int result = 1;
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
index 57e987d..110e0a2 100644
--- 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
@@ -74,6 +74,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
   public static final String MPACK_NAME = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_name";
   public static final String MPACK_VERSION = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_version";
   public static final String MPACK_DESCRIPTION = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_description";
+  public static final String MPACK_DISPLAY_NAME = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_display_name";
   public static final String MPACK_URI = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_uri";
   public static final String MODULES = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "modules";
   public static final String STACK_NAME_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_name";
@@ -114,6 +115,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     PROPERTY_IDS.add(MODULES);
     PROPERTY_IDS.add(STACK_NAME_PROPERTY_ID);
     PROPERTY_IDS.add(STACK_VERSION_PROPERTY_ID);
+    PROPERTY_IDS.add(MPACK_DISPLAY_NAME);
 
     // keys
     KEY_PROPERTY_IDS.put(Resource.Type.Mpack, MPACK_RESOURCE_ID);
@@ -153,6 +155,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         resource.setProperty(MPACK_URI, response.getMpackUri());
         resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
         resource.setProperty(REGISTRY_ID, response.getRegistryId());
+        resource.setProperty(MPACK_DISPLAY_NAME, response.getDisplayName());
         associatedResources.add(resource);
         return getRequestStatus(null, associatedResources);
       }
@@ -241,6 +244,8 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         resource.setProperty(MPACK_URI, response.getMpackUri());
         resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
         resource.setProperty(REGISTRY_ID, response.getRegistryId());
+        resource.setProperty(MPACK_DISPLAY_NAME, response.getDisplayName());
+
         results.add(resource);
       }
     } else {
@@ -293,6 +298,24 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
             "Either the management pack ID or the stack name and version are required when searching");
       }
 
+      MpackResponse response = getManagementController().getMpack(mpackId);
+      Resource resource = new ResourceImpl(Resource.Type.Mpack);
+      if (null != response) {
+        resource.setProperty(MPACK_RESOURCE_ID, response.getId());
+        resource.setProperty(MPACK_ID, response.getMpackId());
+        resource.setProperty(MPACK_NAME, response.getMpackName());
+        resource.setProperty(MPACK_VERSION, response.getMpackVersion());
+        resource.setProperty(MPACK_URI, response.getMpackUri());
+        resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
+        resource.setProperty(REGISTRY_ID, response.getRegistryId());
+        resource.setProperty(MPACK_DISPLAY_NAME, response.getDisplayName());
+
+        StackId stackId = new StackId(response.getStackId());
+        resource.setProperty(STACK_NAME_PROPERTY_ID, stackId.getStackName());
+        resource.setProperty(STACK_VERSION_PROPERTY_ID, stackId.getStackVersion());
+        results.add(resource);
+      }
+
       if (results.isEmpty()) {
         throw new NoSuchResourceException(
           "The requested resource doesn't exist: " + predicate);
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
index 233cd95..3e76338 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
@@ -18,9 +18,12 @@
 package org.apache.ambari.server.state;
 
 import com.google.gson.annotations.SerializedName;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
 
 import java.util.HashMap;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Represents the state of an mpack.
@@ -59,6 +62,9 @@ public class Mpack {
   @SerializedName("description")
   private String description;
 
+  @SerializedName("displayName")
+  private String displayName;
+
   private String mpackUri;
 
   public Long getResourceId() {
@@ -141,6 +147,54 @@ public class Mpack {
     this.definition = definition;
   }
 
+  public String getDisplayName() {
+    return displayName;
+  }
+
+  public void setDisplayName(String displayName) {
+    this.displayName = displayName;
+  }
+
+  /**
+   * Gets the module with the given name. Module names are service names.
+   *
+   * @param moduleName
+   *          the name of the module.
+   * @return the module or {@code null}.
+   */
+  public Module getModule(String moduleName) {
+    for (Module module : modules) {
+      if (StringUtils.equals(moduleName, module.getName())) {
+        return module;
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * Gets a component from a given module.
+   *
+   * @param moduleName
+   *          the module (service) name.
+   * @param moduleComponentName
+   *          the name of the component.
+   * @return the component or {@code null}.
+   */
+  public ModuleComponent getModuleComponent(String moduleName, String moduleComponentName) {
+    for (Module module : modules) {
+      ModuleComponent moduleComponent = module.getModuleComponent(moduleComponentName);
+      if (null != moduleComponent) {
+        return moduleComponent;
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public boolean equals(Object o) {
     if (this == o) return true;
@@ -148,31 +202,27 @@ public class Mpack {
 
     Mpack mpack = (Mpack) o;
 
-    if (!resourceId.equals(mpack.resourceId)) return false;
-    if (registryId != null ? !registryId.equals(mpack.registryId) : mpack.registryId != null) return false;
-    if (!mpackId.equals(mpack.mpackId)) return false;
-    if (!name.equals(mpack.name)) return false;
-    if (!version.equals(mpack.version)) return false;
-    if (!prerequisites.equals(mpack.prerequisites)) return false;
-    if (!modules.equals(mpack.modules)) return false;
-    if (!definition.equals(mpack.definition)) return false;
-    if (!description.equals(mpack.description)) return false;
-    return mpackUri.equals(mpack.mpackUri);
+    Mpack that = (Mpack) o;
+    EqualsBuilder equalsBuilder = new EqualsBuilder();
+    equalsBuilder.append(resourceId, that.resourceId);
+    equalsBuilder.append(registryId, that.registryId);
+    equalsBuilder.append(mpackId, that.mpackId);
+    equalsBuilder.append(name, that.name);
+    equalsBuilder.append(version, that.version);
+    equalsBuilder.append(prerequisites, that.prerequisites);
+    equalsBuilder.append(modules, that.modules);
+    equalsBuilder.append(definition, that.definition);
+    equalsBuilder.append(description, that.description);
+    equalsBuilder.append(mpackUri, that.mpackUri);
+    equalsBuilder.append(displayName, that.displayName);
+
+    return equalsBuilder.isEquals();
   }
 
   @Override
   public int hashCode() {
-    int result = resourceId.hashCode();
-    result = 31 * result + (registryId != null ? registryId.hashCode() : 0);
-    result = 31 * result + mpackId.hashCode();
-    result = 31 * result + name.hashCode();
-    result = 31 * result + version.hashCode();
-    result = 31 * result + prerequisites.hashCode();
-    result = 31 * result + modules.hashCode();
-    result = 31 * result + definition.hashCode();
-    result = 31 * result + description.hashCode();
-    result = 31 * result + mpackUri.hashCode();
-    return result;
+    return Objects.hash(resourceId, registryId, mpackId, name, version, prerequisites, modules,
+        definition, description, mpackUri, displayName);
   }
 
   @Override
@@ -188,6 +238,7 @@ public class Mpack {
             ", definition='" + definition + '\'' +
             ", description='" + description + '\'' +
             ", mpackUri='" + mpackUri + '\'' +
+            ", displayName='" + mpackUri + '\'' +
             '}';
   }
 
@@ -216,5 +267,8 @@ public class Mpack {
     if (this.definition == null) {
       this.definition = mpack.getDefinition();
     }
+    if (displayName == null) {
+      displayName = mpack.getDisplayName();
+    }
   }
 }


[ambari] 17/20: [AMBARI-23223] Stack Mpack link broken in stacks api

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit ffe161fcdff875b5b6ec1828659ff77ad17c0ecf
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Thu Mar 15 12:16:42 2018 -0700

    [AMBARI-23223] Stack Mpack link broken in stacks api
---
 .../controller/AmbariManagementControllerImpl.java | 18 +++--
 .../controller/internal/MpackResourceProvider.java | 76 +++++++++++-----------
 .../internal/StackVersionResourceProvider.java     | 14 ++--
 3 files changed, 60 insertions(+), 48 deletions(-)

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 29e42d9..6061640 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
@@ -4736,14 +4736,24 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     String stackName = request.getStackName();
     String stackVersion = request.getStackVersion();
     String propertyName = request.getPropertyName();
+    Set<PropertyInfo> configs;
 
-    Set<PropertyInfo> properties;
+    //properties : cluster-env
+    //TODO: Remove after getting rid of cluster-env
     if (propertyName != null) {
-      properties = ambariMetaInfo.getStackPropertiesByName(stackName, stackVersion, propertyName);
+      configs = ambariMetaInfo.getStackPropertiesByName(stackName, stackVersion, propertyName);
     } else {
-      properties = ambariMetaInfo.getStackProperties(stackName, stackVersion);
+      configs = ambariMetaInfo.getStackProperties(stackName, stackVersion);
     }
-    for (PropertyInfo property: properties) {
+
+    //settings : stackSettings
+    if(configs.size() == 0){
+      if (propertyName != null) {
+        configs = ambariMetaInfo.getStackSettingsByName(stackName, stackVersion, propertyName);
+      } else
+        configs = ambariMetaInfo.getStackSettings(stackName, stackVersion);
+    }
+    for (PropertyInfo property: configs) {
       response.add(property.convertToResponse());
     }
 
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
index 3169eda..57e987d 100644
--- 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
@@ -31,7 +31,6 @@ 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.AmbariException;
 import org.apache.ambari.server.StaticallyInject;
@@ -247,50 +246,53 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     } else {
       // Fetch a particular mpack based on id
       Map<String, Object> propertyMap = new HashMap<>(PredicateHelper.getProperties(predicate));
-      if (propertyMap.containsKey(STACK_NAME_PROPERTY_ID) && propertyMap.containsKey(STACK_VERSION_PROPERTY_ID)) {
+      if (propertyMap.containsKey(MPACK_RESOURCE_ID)) {
+        Object objMpackId = propertyMap.get(MPACK_RESOURCE_ID);
+        if (objMpackId != null) {
+          mpackId = Long.valueOf((String) objMpackId);
+        }
+        MpackResponse response = getManagementController().getMpack(mpackId);
+        Resource resource = new ResourceImpl(Resource.Type.Mpack);
+        if (null != response) {
+          resource.setProperty(MPACK_RESOURCE_ID, response.getId());
+          resource.setProperty(MPACK_ID, response.getMpackId());
+          resource.setProperty(MPACK_NAME, response.getMpackName());
+          resource.setProperty(MPACK_VERSION, response.getMpackVersion());
+          resource.setProperty(MPACK_URI, response.getMpackUri());
+          resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
+          resource.setProperty(REGISTRY_ID, response.getRegistryId());
+          List<Module> modules = getManagementController().getModules(response.getId());
+          resource.setProperty(MODULES, modules);
+          results.add(resource);
+        }
+      } //Fetch an mpack based on a stackVersion query
+      else if (propertyMap.containsKey(STACK_NAME_PROPERTY_ID)
+          && propertyMap.containsKey(STACK_VERSION_PROPERTY_ID)) {
         String stackName = (String) propertyMap.get(STACK_NAME_PROPERTY_ID);
         String stackVersion = (String) propertyMap.get(STACK_VERSION_PROPERTY_ID);
         StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
         mpackId = stackEntity.getMpackId();
-        if (mpackId != null) {
-          MpackResponse response = getManagementController().getMpack(mpackId);
-          Resource resource = new ResourceImpl(Resource.Type.Mpack);
-          if (null != response) {
-            resource.setProperty(MPACK_RESOURCE_ID, response.getId());
-            resource.setProperty(MPACK_ID, response.getMpackId());
-            resource.setProperty(MPACK_NAME, response.getMpackName());
-            resource.setProperty(MPACK_VERSION, response.getMpackVersion());
-            resource.setProperty(MPACK_URI, response.getMpackUri());
-            resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
-            resource.setProperty(REGISTRY_ID, response.getRegistryId());
-            resource.setProperty(STACK_NAME_PROPERTY_ID, stackName);
-            resource.setProperty(STACK_VERSION_PROPERTY_ID, stackVersion);
-            results.add(resource);
-          }
+        MpackResponse response = getManagementController().getMpack(mpackId);
+        Resource resource = new ResourceImpl(Resource.Type.Mpack);
+        if (null != response) {
+          resource.setProperty(MPACK_RESOURCE_ID, response.getId());
+          resource.setProperty(MPACK_ID, response.getMpackId());
+          resource.setProperty(MPACK_NAME, response.getMpackName());
+          resource.setProperty(MPACK_VERSION, response.getMpackVersion());
+          resource.setProperty(MPACK_URI, response.getMpackUri());
+          resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
+          resource.setProperty(REGISTRY_ID, response.getRegistryId());
+          resource.setProperty(STACK_NAME_PROPERTY_ID, stackName);
+          resource.setProperty(STACK_VERSION_PROPERTY_ID, stackVersion);
+          results.add(resource);
         }
         return results;
       }
-
-      if (propertyMap.containsKey(MPACK_RESOURCE_ID)) {
-        Object objMpackId = propertyMap.get(MPACK_RESOURCE_ID);
-        if (objMpackId != null)
-          mpackId = Long.valueOf((String) objMpackId);
-
-          MpackResponse response = getManagementController().getMpack(mpackId);
-          Resource resource = new ResourceImpl(Resource.Type.Mpack);
-          if (null != response) {
-            resource.setProperty(MPACK_RESOURCE_ID, response.getId());
-            resource.setProperty(MPACK_ID, response.getMpackId());
-            resource.setProperty(MPACK_NAME, response.getMpackName());
-            resource.setProperty(MPACK_VERSION, response.getMpackVersion());
-            resource.setProperty(MPACK_URI, response.getMpackUri());
-            resource.setProperty(MPACK_DESCRIPTION, response.getDescription());
-            resource.setProperty(REGISTRY_ID, response.getRegistryId());
-            List<Module> modules = getManagementController().getModules(response.getId());
-            resource.setProperty(MODULES, modules);
-            results.add(resource);
-          }
+      if (null == mpackId) {
+        throw new IllegalArgumentException(
+            "Either the management pack ID or the stack name and version are required when searching");
       }
+
       if (results.isEmpty()) {
         throw new NoSuchResourceException(
           "The requested resource doesn't exist: " + predicate);
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
index d1e8a42..e678d1a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
@@ -60,7 +60,7 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
   public static final String UPGRADE_PACKS_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "upgrade_packs";
   public static final String STACK_MIN_JDK     = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "min_jdk";
   public static final String STACK_MAX_JDK     = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "max_jdk";
-  public static final String MPACK_ID     = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_id";
+  public static final String MPACK_RESOURCE_ID     = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "id";
 
   public static final Set<String> PROPERTY_IDS = new HashSet<>();
 
@@ -68,7 +68,7 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
   protected static StackDAO stackDAO;
 
   private static Set<String> pkPropertyIds = new HashSet<>(
-    Arrays.asList(new String[]{STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID, MPACK_ID}));
+    Arrays.asList(new String[]{STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID, MPACK_RESOURCE_ID}));
 
   /**
    * The key property ids for a mpack resource.
@@ -77,7 +77,7 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
 
   static {
     // properties
-    PROPERTY_IDS.add(MPACK_ID);
+    PROPERTY_IDS.add(MPACK_RESOURCE_ID);
     PROPERTY_IDS.add(STACK_VERSION_PROPERTY_ID);
     PROPERTY_IDS.add(STACK_NAME_PROPERTY_ID);
     PROPERTY_IDS.add(STACK_MIN_VERSION_PROPERTY_ID);
@@ -91,7 +91,7 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
     PROPERTY_IDS.add(STACK_MAX_JDK);
 
     // keys
-    KEY_PROPERTY_IDS.put(Resource.Type.Mpack, MPACK_ID);
+    KEY_PROPERTY_IDS.put(Resource.Type.Mpack, MPACK_RESOURCE_ID);
     KEY_PROPERTY_IDS.put(Resource.Type.Stack, STACK_NAME_PROPERTY_ID);
     KEY_PROPERTY_IDS.put(Resource.Type.StackVersion, STACK_VERSION_PROPERTY_ID);
 
@@ -115,9 +115,9 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
       requests.add(getRequest(Collections.emptyMap()));
     } else {
       Map<String, Object> propertyMap = new HashMap<>(PredicateHelper.getProperties(predicate));
-      if (propertyMap.containsKey(MPACK_ID)) {
+      if (propertyMap.containsKey(MPACK_RESOURCE_ID)) {
         Resource resource = new ResourceImpl(Resource.Type.StackVersion);
-        Long mpackId = Long.valueOf((String) propertyMap.get(MPACK_ID));
+        Long mpackId = Long.valueOf((String) propertyMap.get(MPACK_RESOURCE_ID));
         StackEntity stackEntity = stackDAO.findByMpack(mpackId);
         requests.add(new StackVersionRequest(stackEntity.getStackName(), stackEntity.getStackVersion()));
         resource.setProperty(STACK_NAME_PROPERTY_ID,
@@ -126,7 +126,7 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
         resource.setProperty(STACK_VERSION_PROPERTY_ID,
                 (String)stackEntity.getStackVersion());
 
-        resource.setProperty(MPACK_ID, mpackId);
+        resource.setProperty(MPACK_RESOURCE_ID, mpackId);
 
         resources.add(resource);
 


[ambari] 08/20: AMBARI-21849 : Addendum to fix checkstyle issues and null check (mradhakrishnan)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 4cfd7a9815afea337fd757bd7d12b2d3e9eb1164
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Wed Aug 30 14:52:54 2017 -0700

    AMBARI-21849 : Addendum to fix checkstyle issues and null check (mradhakrishnan)
---
 .../java/org/apache/ambari/server/api/services/AmbariMetaInfo.java    | 4 +++-
 .../ambari/server/controller/internal/MpackResourceProvider.java      | 4 +++-
 .../ambari/server/controller/internal/MpackResourceProviderTest.java  | 3 ---
 3 files changed, 6 insertions(+), 5 deletions(-)

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 6ae0e1c..1fa30ef 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
@@ -665,7 +665,9 @@ public class AmbariMetaInfo {
    * @throws ResourceAlreadyExistsException
    */
   public MpackResponse registerMpack(MpackRequest mpackRequest) throws IOException, ResourceAlreadyExistsException {
-    versionDefinitions.clear();
+    if (versionDefinitions != null) {
+      versionDefinitions.clear();
+    }
     return mpackManager.registerMpack(mpackRequest);
   }
 
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
index c4833d1..70b6d74 100644
--- 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
@@ -56,11 +56,13 @@ import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.MpackEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.Packlet;
-
 import org.apache.ambari.server.state.StackId;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.Validate;
 
+import com.google.inject.Inject;
+
+
 /**
  * ResourceProvider for Mpack instances
  */
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
index 0e38b08..944e40d 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/MpackResourceProviderTest.java
@@ -17,13 +17,10 @@
  */
 package org.apache.ambari.server.controller.internal;
 
-import org.apache.commons.io.IOUtils;
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 
-import java.net.URI;
-import java.net.URL;
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.HashMap;


[ambari] 06/20: AMBARI-21796 : Clear versionDefinition map during new mpack registration and mpack deletion (mradhakrishnan)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 32023fb66ab0e0b163bf4c4d4937e0d846d3b2ca
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Wed Aug 23 15:04:52 2017 -0700

    AMBARI-21796 : Clear versionDefinition map during new mpack registration and mpack deletion (mradhakrishnan)
---
 .../ambari/server/api/services/AmbariMetaInfo.java |  6 +-
 .../org/apache/ambari/server/state/MpackTest.java  | 96 ++++++++++++++++++++++
 2 files changed, 100 insertions(+), 2 deletions(-)

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 1ea5369..6812bf2 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
@@ -665,6 +665,7 @@ public class AmbariMetaInfo {
    * @throws ResourceAlreadyExistsException
    */
   public MpackResponse registerMpack(MpackRequest mpackRequest) throws IOException, ResourceAlreadyExistsException {
+    versionDefinitions.clear();
     return mpackManager.registerMpack(mpackRequest);
   }
 
@@ -1453,7 +1454,8 @@ public class AmbariMetaInfo {
    */
   private synchronized void ensureVersionDefinitions() {
     if (null != versionDefinitions) {
-      return;
+      if(versionDefinitions.size() > 0)
+        return;
     }
 
     versionDefinitions = new HashMap<>();
@@ -1552,7 +1554,7 @@ public class AmbariMetaInfo {
    * @throws IOException
    */
   public void removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException {
-
+    versionDefinitions.clear();
     boolean stackDelete = mpackManager.removeMpack(mpackEntity, stackEntity);
 
     if(stackDelete) {
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
new file mode 100644
index 0000000..388c256
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
@@ -0,0 +1,96 @@
+/**
+ * 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 java.util.ArrayList;
+import java.util.HashMap;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+
+public class MpackTest {
+  @Test
+  public void testMpacks() {
+    Mpacks mpack = new Mpacks();
+    mpack.setName("name");
+    mpack.setMpackId((long)100);
+    mpack.setDescription("desc");
+    mpack.setVersion("3.0");
+    mpack.setMpacksUri("abc.tar.gz");
+    mpack.setRegistryId(new Long(100));
+
+    Assert.assertEquals("name", mpack.getName());
+    Assert.assertEquals(new Long(100), mpack.getMpackId());
+    Assert.assertEquals("desc", mpack.getDescription());
+    Assert.assertEquals("abc.tar.gz", mpack.getMpacksUri());
+    Assert.assertEquals(new Long(100), mpack.getRegistryId());
+
+  }
+
+  @Test
+  public void testMpacksUsingGson() {
+    String mpackJsonContents = "{\n" +
+            "  \"name\" : \"hdf-ambari-mpack\",\n" +
+            "  \"version\": \"3.0.0.0-111\",\n" +
+            "  \"description\" : \"HDF 3.0.0 Ambari Management Pack\",\n" +
+            "  \"prerequisites\": {\n" +
+            "    \"min-ambari-version\" : \"3.0.0.0\"\n" +
+            "  },\n" +
+            "  \"packlets\": [\n" +
+            "    {\n" +
+            "      \"type\" : \"service-packlet\",\n" +
+            "      \"name\" : \"NIFI\",\n" +
+            "      \"version\" : \"1.2.0.0-123\",\n" +
+            "      \"source_location\": \"packlets/NIFI-1.2.0.0-123.tar.gz\"\n" +
+            "    },\n" +
+            "    {\n" +
+            "      \"type\" : \"service-packlet\",\n" +
+            "      \"name\" : \"STREAMLINE\",\n" +
+            "      \"version\" : \"1.0.0.0-100\",\n" +
+            "      \"source_location\": \"packlets/STREAMLINE-1.0.0.0-100.tar.gz\"\n" +
+            "    }\n" +
+            "  ]\n" +
+            "}\n";
+    HashMap<String, String> expectedPrereq = new HashMap<>();
+    expectedPrereq.put("min-ambari-version","3.0.0.0");
+    ArrayList<Packlet> expectedPacklets = new ArrayList<>();
+    Packlet nifi = new Packlet();
+    nifi.setType("SERVICE_PACKLET");
+    nifi.setVersion("1.2.0.0-123");
+    nifi.setSourceLocation("packlets/NIFI-1.2.0.0-123.tar.gz");
+    nifi.setName("NIFI");
+    Packlet streamline = new Packlet();
+    streamline.setName("STREAMLINE");
+    streamline.setType(Packlet.PackletType.SERVICE_PACKLET);
+    streamline.setSourceLocation("packlets/STREAMLINE-1.0.0.0-100.tar.gz");
+    streamline.setVersion("1.0.0.0-100");
+    expectedPacklets.add(nifi);
+    expectedPacklets.add(streamline);
+
+    Gson gson = new Gson();
+    Mpack mpack = gson.fromJson(mpackJsonContents, Mpack.class);
+    Assert.assertEquals("hdf-ambari-mpack", mpack.getName());
+    Assert.assertEquals("3.0.0.0-111", mpack.getVersion());
+    Assert.assertEquals("HDF 3.0.0 Ambari Management Pack", mpack.getDescription());
+    Assert.assertEquals(expectedPrereq, mpack.getPrerequisites());
+    Assert.assertEquals(expectedPacklets.toString(), mpack.getPacklets().toString());
+  }
+
+}


[ambari] 09/20: AMBARI-22082: Create missing parent directory when expanding mpack tarball (jluniya)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit a82e169c7ed66c4a38795f0617711c784bb224a3
Author: Jayush Luniya <jl...@hortonworks.com>
AuthorDate: Thu Sep 28 10:50:13 2017 -0700

    AMBARI-22082: Create missing parent directory when expanding mpack tarball (jluniya)
---
 .../ambari/server/controller/MpackResponse.java    |   4 +-
 .../controller/internal/MpackResourceProvider.java |  43 ++---
 .../apache/ambari/server/mpack/MpackManager.java   | 188 +++++++++++++++------
 .../server/state/{Mpacks.java => Mpack.java}       |   6 +-
 .../org/apache/ambari/server/state/MpackTest.java  |   2 +-
 5 files changed, 161 insertions(+), 82 deletions(-)

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
index 16eb03c..a2fc28a 100644
--- 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
@@ -18,7 +18,7 @@
 package org.apache.ambari.server.controller;
 
 
-import org.apache.ambari.server.state.Mpacks;
+import org.apache.ambari.server.state.Mpack;
 import org.apache.ambari.server.controller.internal.MpackResourceProvider;
 
 import io.swagger.annotations.ApiModelProperty;
@@ -35,7 +35,7 @@ public class MpackResponse {
   private Long registryId;
   private String stackId;
 
-  public MpackResponse(Mpacks mpacks) {
+  public MpackResponse(Mpack mpacks) {
     this.mpackId = mpacks.getMpackId();
     this.mpackVersion = mpacks.getVersion();
     this.mpackUri = mpacks.getMpacksUri();
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
index 70b6d74..694bf3c 100644
--- 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
@@ -57,12 +57,10 @@ import org.apache.ambari.server.orm.entities.MpackEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.Packlet;
 import org.apache.ambari.server.state.StackId;
-import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.Validate;
 
 import com.google.inject.Inject;
 
-
 /**
  * ResourceProvider for Mpack instances
  */
@@ -78,10 +76,11 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
   public static final String MPACK_URI = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "mpack_uri";
   public static final String PACKLETS = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "packlets";
   public static final String STACK_NAME_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_name";
-  public static final String STACK_VERSION_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_version";
+  public static final String STACK_VERSION_PROPERTY_ID =
+    RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "stack_version";
 
   private static Set<String> pkPropertyIds = new HashSet<>(
-          Arrays.asList(MPACK_ID, STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID));
+    Arrays.asList(MPACK_ID, STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID));
 
   /**
    * The property ids for an mpack resource.
@@ -163,6 +162,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
 
   /***
    * Validates the request body for the required properties in order to create an Mpack resource.
+   *
    * @param mpackRequest
    */
   private void validateCreateRequest(MpackRequest mpackRequest) {
@@ -171,24 +171,24 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     final Long registryId = mpackRequest.getRegistryId();
     final String mpackVersion = mpackRequest.getMpackVersion();
 
-    if(registryId == null) {
+    if (registryId == null) {
       Validate.isTrue(mpackUrl != null);
       LOG.info("Received a createMpack request"
-              + ", mpackUrl=" + mpackUrl);
+        + ", mpackUrl=" + mpackUrl);
     } else {
       Validate.notNull(mpackName, "MpackName should not be null");
       Validate.notNull(mpackVersion, "MpackVersion should not be null");
       LOG.info("Received a createMpack request"
-              + ", mpackName=" + mpackName
-              + ", mpackVersion=" + mpackVersion
-              + ", registryId=" + registryId);
+        + ", mpackName=" + mpackName
+        + ", mpackVersion=" + mpackVersion
+        + ", registryId=" + registryId);
     }
     try {
       URI uri = new URI(mpackUrl);
       URL url = uri.toURL();
-      String jsonString = IOUtils.toString(url);
-    }catch(Exception e){
-      Validate.isTrue(e == null, e.getMessage() + " is an invalid mpack uri. Please check the download link for the mpack again.");
+    } catch (Exception e) {
+      Validate.isTrue(e == null,
+        e.getMessage() + " is an invalid mpack uri. Please check the download link for the mpack again.");
     }
   }
 
@@ -201,7 +201,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
         return null;
       //Fetch Mpack Download Url using the given registry id
       else if (!propertyMap.containsKey(MPACK_URI)) {
-        mpackRequest.setRegistryId((Long) propertyMap.get(REGISTRY_ID));
+        mpackRequest.setRegistryId(Long.valueOf((String) propertyMap.get(REGISTRY_ID)));
         mpackRequest.setMpackName((String) propertyMap.get(MPACK_NAME));
         mpackRequest.setMpackVersion((String) propertyMap.get(MPACK_VERSION));
       }
@@ -215,8 +215,8 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
 
   @Override
   public Set<Resource> getResources(Request request, Predicate predicate)
-          throws SystemException, UnsupportedPropertyException,
-          NoSuchResourceException, NoSuchParentResourceException {
+    throws SystemException, UnsupportedPropertyException,
+    NoSuchResourceException, NoSuchParentResourceException {
 
     Set<Resource> results = new LinkedHashSet<>();
     Long mpackId = null;
@@ -279,7 +279,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
       }
       if (results.isEmpty()) {
         throw new NoSuchResourceException(
-                "The requested resource doesn't exist: " + predicate);
+          "The requested resource doesn't exist: " + predicate);
       }
     }
     return results;
@@ -287,15 +287,16 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
 
   @Override
   protected RequestStatus deleteResourcesAuthorized(final Request request, Predicate predicate)
-          throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+    throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
 
     final Long mpackId;
     Map<String, Object> propertyMap = new HashMap<>(PredicateHelper.getProperties(predicate));
     DeleteStatusMetaData deleteStatusMetaData = null;
 
-    //Allow deleting mpack only if there are no cluster services deploying using this mpack. Support deleting mpacks only if no cluster has been deployed
+    // Allow deleting mpack only if there are no cluster services deploying using this mpack.
+    // Support deleting mpacks only if no cluster has been deployed
     // (i.e. you should be able to delete an mpack during install wizard only).
-    //Todo : Relax the rule
+    // TODO : Relax the rule
     if (getManagementController().getClusters().getClusters().size() > 0) {
       throw new SystemException("Delete request cannot be completed since there is a cluster deployed");
     } else {
@@ -315,7 +316,8 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
                 @Override
                 public DeleteStatusMetaData invoke() throws AmbariException {
                   if (stackEntity != null) {
-                    repositoryVersionDAO.removeByStack(new StackId(stackEntity.getStackName() + "-" + stackEntity.getStackVersion()));
+                    repositoryVersionDAO
+                      .removeByStack(new StackId(stackEntity.getStackName() + "-" + stackEntity.getStackVersion()));
                     stackDAO.removeByMpack(mpackId);
                     notifyDelete(Resource.Type.Stack, predicate);
                   }
@@ -340,6 +342,5 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
       return getRequestStatus(null, null, deleteStatusMetaData);
     }
   }
-
 }
 
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
index 619823c..5ae7e1d 100644
--- 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
@@ -27,7 +27,7 @@ import org.apache.ambari.server.orm.dao.MpackDAO;
 import org.apache.ambari.server.orm.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.MpackEntity;
 import org.apache.ambari.server.orm.entities.StackEntity;
-import org.apache.ambari.server.state.Mpacks;
+import org.apache.ambari.server.state.Mpack;
 import org.apache.ambari.server.state.Packlet;
 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
@@ -59,20 +59,25 @@ import java.io.IOException;
  * mpack information.
  */
 public class MpackManager {
-  protected Map<Long, Mpacks> mpackMap = new HashMap<>();
+  protected Map<Long, Mpack> mpackMap = new HashMap<>();
   private File mpackStaging;
   private MpackDAO mpackDAO;
   private StackDAO stackDAO;
-  private Mpacks mpack;
+  private Mpack mpack;
   private File stackRoot;
   private static final String MPACK_METADATA = "mpack.json";
   private static final String MPACK_TAR_LOCATION = "staging";
+  private static final String SERVICES_DIRECTORY = "services";
 
   private final static Logger LOG = LoggerFactory.getLogger(MpackManager.class);
 
   @AssistedInject
-  public MpackManager(@Assisted("mpackv2Staging") File mpackStagingLocation, @Assisted("stackRoot") File stackRootDir, MpackDAO mpackDAOObj, StackDAO stackDAOObj) {
-    mpackStaging = mpackStagingLocation;
+  public MpackManager(
+    @Assisted("mpacksv2Staging") File mpacksStagingLocation,
+    @Assisted("stackRoot") File stackRootDir,
+    MpackDAO mpackDAOObj,
+    StackDAO stackDAOObj) {
+    mpackStaging = mpacksStagingLocation;
     mpackDAO = mpackDAOObj;
     stackRoot = stackRootDir;
     stackDAO = stackDAOObj;
@@ -97,13 +102,17 @@ public class MpackManager {
               if (file.isDirectory()) {
                 String mpackVersion = file.getName();
                 List resultSet = mpackDAO.findByNameVersion(mpackName, mpackVersion);
-                MpackEntity mpackEntity = (MpackEntity) resultSet.get(0);
 
-                //Read the mpack.json file into Mpack Object for further use.
-                String mpackJsonContents = new String((Files.readAllBytes(Paths.get(file + "/" + MPACK_METADATA))), "UTF-8");
-                Gson gson = new Gson();
-                Mpacks existingMpack = gson.fromJson(mpackJsonContents, Mpacks.class);
-                mpackMap.put(mpackEntity.getMpackId(), existingMpack);
+                if (resultSet.size() > 0) {
+                  MpackEntity mpackEntity = (MpackEntity) resultSet.get(0);
+
+                  // Read the mpack.json file into Mpack Object for further use.
+                  String mpackJsonContents = new String((Files.readAllBytes(Paths.get(file + "/" + MPACK_METADATA))),
+                    "UTF-8");
+                  Gson gson = new Gson();
+                  Mpack existingMpack = gson.fromJson(mpackJsonContents, Mpack.class);
+                  mpackMap.put(mpackEntity.getMpackId(), existingMpack);
+                }
               }
             }
           }
@@ -114,7 +123,6 @@ public class MpackManager {
     }
   }
 
-
   /**
    * Parses mpack.json to fetch mpack and associated packlet information and
    * stores the mpack to the database and mpackMap
@@ -125,12 +133,13 @@ public class MpackManager {
    * @throws IllegalArgumentException
    * @throws ResourceAlreadyExistsException
    */
-  public MpackResponse registerMpack(MpackRequest mpackRequest) throws IOException, IllegalArgumentException, ResourceAlreadyExistsException {
+  public MpackResponse registerMpack(MpackRequest mpackRequest)
+    throws IOException, IllegalArgumentException, ResourceAlreadyExistsException {
 
     Long mpackId;
     String mpackName = "";
     String mpackVersion = "";
-    mpack = new Mpacks();
+    mpack = new Mpack();
     boolean isValidMetadata;
     String mpackDirectory = "";
     Path mpackTarPath;
@@ -144,12 +153,14 @@ public class MpackManager {
       //Todo : Madhu implement GET /registries/{registryId}/mpacks
       mpackTarPath = downloadMpack(mpackRequest.getMpackUri());
 
-      if (createMpackDirectory(mpackTarPath)) {
+      if (createMpackDirectory(mpack, mpackTarPath)) {
         isValidMetadata = validateMpackInfo(mpackName, mpackVersion, mpack.getName(), mpack.getVersion());
         if (isValidMetadata) {
           mpackDirectory = mpackStaging + File.separator + mpack.getName() + File.separator + mpack.getVersion();
         } else {
-          String message = "Incorrect information : Mismatch in - (" + mpackName + "," + mpack.getName() + ") or (" + mpackVersion + "," + mpack.getVersion() + ")";
+          String message =
+            "Incorrect information : Mismatch in - (" + mpackName + "," + mpack.getName() + ") or (" + mpackVersion
+              + "," + mpack.getVersion() + ")";
           throw new IllegalArgumentException(message); //Mismatch in information
         }
 
@@ -157,12 +168,12 @@ public class MpackManager {
     } else {    //Mpack registration using direct download
       mpackTarPath = downloadMpack(mpackRequest.getMpackUri());
 
-      if (createMpackDirectory(mpackTarPath)) {
+      if (createMpackDirectory(mpack, mpackTarPath)) {
         mpackDirectory = mpackStaging + File.separator + mpack.getName() + File.separator + mpack.getVersion();
         mpack.setMpacksUri(mpackRequest.getMpackUri());
       }
     }
-    extractMpackTar(mpackTarPath, mpackDirectory);
+    extractMpackTar(mpack, mpackTarPath, mpackDirectory);
     mpackId = populateDB(mpack);
 
     if (mpackId != null) {
@@ -171,50 +182,99 @@ public class MpackManager {
       populateStackDB(mpack);
       return new MpackResponse(mpack);
     } else {
-      String message = "Mpack :" + mpackRequest.getMpackName() + " version: " + mpackRequest.getMpackVersion() + " already exists in server";
+      String message = "Mpack :" + mpackRequest.getMpackName() + " version: " + mpackRequest.getMpackVersion()
+        + " already exists in server";
       throw new ResourceAlreadyExistsException(message);
     }
   }
 
-  /**
-   * Mpack is downloaded as a tar.gz file. It is extracted into mpack-v2-staging/{mpack-name}/{mpack-version}/ directory
+  /***
+   * A generic method to extract tar files.
    *
-   * @param mpackTarPath
-   * @param mpackDirectory
+   * @param tarPath
    * @throws IOException
    */
-  private void extractMpackTar(Path mpackTarPath, String mpackDirectory) throws IOException {
-    TarArchiveInputStream mpackTarFile = new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(new File(String.valueOf(mpackTarPath))))));
-    // To read individual TAR file
+  private void extractTar(Path tarPath, File untarDirectory) throws IOException {
+    TarArchiveInputStream tarFile = new TarArchiveInputStream(
+      new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(new File(String.valueOf(tarPath))))));
     TarArchiveEntry entry = null;
     File outputFile = null;
     //Create a loop to read every single entry in TAR file
-    while ((entry = mpackTarFile.getNextTarEntry()) != null) {
-      outputFile = new File(mpackStaging, entry.getName());
+    while ((entry = tarFile.getNextTarEntry()) != null) {
+      outputFile = new File(untarDirectory, entry.getName());
+
       if (entry.isDirectory()) {
-        LOG.debug("Attempting to write output directory" + outputFile.getAbsolutePath());
         if (!outputFile.exists()) {
-          LOG.debug("Attempting to create output directory " + outputFile.getAbsolutePath());
+          LOG.debug("Creating output directory " + outputFile.getAbsolutePath());
           if (!outputFile.mkdirs()) {
-            throw new IllegalStateException(String.format("Couldn't create directory %s.", outputFile.getAbsolutePath()));
+            throw new IllegalStateException("Couldn't create directory " + outputFile.getAbsolutePath());
           }
         }
       } else {
-        LOG.debug("Creating output file %s." + outputFile.getAbsolutePath());
+        File parentDir = outputFile.getParentFile();
+        if (!parentDir.exists()) {
+          LOG.debug("Attempting to create output directory " + parentDir.getAbsolutePath());
+          if (!parentDir.mkdirs()) {
+            throw new IllegalStateException("Couldn't create directory " + parentDir.getAbsolutePath());
+          }
+        }
+        LOG.debug("Creating output file " + outputFile.getAbsolutePath());
         final OutputStream outputFileStream = new FileOutputStream(outputFile);
-        IOUtils.copy(mpackTarFile, outputFileStream);
+        IOUtils.copy(tarFile, outputFileStream);
         outputFileStream.close();
       }
     }
-    mpackTarFile.close();
+    tarFile.close();
+  }
+
+  /**
+   * Mpack is downloaded as a tar.gz file.
+   * It is extracted into /var/lib/ambari-server/resources/mpack-v2/{mpack-name}/{mpack-version} directory
+   *
+   * @param mpack          Mpack to process
+   * @param mpackTarPath   Path to mpack tarball
+   * @param mpackDirectory Mpack directory
+   * @throws IOException
+   */
+  private void extractMpackTar(Mpack mpack, Path mpackTarPath, String mpackDirectory) throws IOException {
+
+    extractTar(mpackTarPath, mpackStaging);
+
     String mpackTarDirectory = mpackTarPath.toString();
     Path extractedMpackDirectory = Files.move
-            (Paths.get(mpackStaging + File.separator + mpackTarDirectory.substring(mpackTarDirectory.lastIndexOf('/') + 1, mpackTarDirectory.indexOf(".tar")) + File.separator),
-                    Paths.get(mpackDirectory), StandardCopyOption.REPLACE_EXISTING);
+      (Paths.get(mpackStaging + File.separator + mpackTarDirectory
+          .substring(mpackTarDirectory.lastIndexOf('/') + 1, mpackTarDirectory.indexOf(".tar")) + File.separator),
+        Paths.get(mpackDirectory), StandardCopyOption.REPLACE_EXISTING);
 
     createSymLinks();
   }
 
+  /***
+   * Create a services directory and extract all the services tar file inside it. This readies it for cluster deployment
+   *
+   * @param extractedMpackDirectory
+   * @param mpack
+   * @throws IOException
+   */
+  private void createServicesDirectory(Path extractedMpackDirectory, Mpack mpack) throws IOException {
+    File servicesDir = new File(extractedMpackDirectory.toAbsolutePath() + File.separator + SERVICES_DIRECTORY );
+    if (!servicesDir.exists()) {
+      servicesDir.mkdir();
+    }
+    List<Packlet> packlets = mpack.getPacklets();
+
+    for (Packlet packlet : packlets) {
+      //if (packlet.getType() == Packlet.PackletType.SERVICE_PACKLET) {
+        String packletSourceLocation = packlet.getSourceDir();
+        File serviceTargetDir = new File(servicesDir + File.separator + packlet.getName());
+        extractTar(Paths.get(extractedMpackDirectory + File.separator + packlet.getSourceDir()), servicesDir);
+        Path extractedServiceDirectory = Files.move(Paths.get(servicesDir + File.separator + packletSourceLocation
+            .substring(packletSourceLocation.indexOf("/") + 1, packletSourceLocation.indexOf(".tar.gz"))),
+          serviceTargetDir.toPath(), StandardCopyOption.REPLACE_EXISTING);
+      }
+    }
+  
+
   /**
    * Reads the mpack.json file within the {mpack-name}.tar.gz file and populates Mpack object.
    * Extract the mpack-name and mpack-version from mpack.json to create the new mpack directory to hold the mpack files.
@@ -223,9 +283,11 @@ public class MpackManager {
    * @return boolean
    * @throws IOException
    */
-  private Boolean createMpackDirectory(Path mpackTarPath) throws IOException {
-    TarArchiveInputStream mpackTarFile = new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(new File(mpackTarPath.toString())))));
-    // To read individual TAR file
+  private Boolean createMpackDirectory(Mpack mpack, Path mpackTarPath)
+    throws IOException, ResourceAlreadyExistsException {
+
+    TarArchiveInputStream mpackTarFile = new TarArchiveInputStream(
+      new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(new File(mpackTarPath.toString())))));
     TarArchiveEntry entry = null;
     String individualFiles;
     int offset;
@@ -247,7 +309,7 @@ public class MpackManager {
         //Read the mpack.json file into Mpack Object for further use.
         String mpackJsonContents = new String(content, "UTF-8");
         Gson gson = new Gson();
-        Mpacks tempMpack = gson.fromJson(mpackJsonContents, Mpacks.class);
+        Mpack tempMpack = gson.fromJson(mpackJsonContents, Mpack.class);
         mpack.copyFrom(tempMpack);
 
         mpackTarFile.close();
@@ -257,11 +319,14 @@ public class MpackManager {
           return mpackDirectory.mkdir();
         else
           return true;
+        } else {
+          String message =
+            "Mpack: " + mpack.getName() + " version: " + mpack.getVersion() + " already exists in server";
+          throw new ResourceAlreadyExistsException(message);
+        }
       }
-    }
-
     return false;
-  }
+    }
 
   /***
    * Create a linkage between the staging directory and the working directory i.e from mpacks-v2 to stackRoot.
@@ -280,9 +345,9 @@ public class MpackManager {
     Files.createSymbolicLink(stackPath, mpackPath);
   }
 
-
   /***
    * Download the mpack from the given uri
+   *
    * @param mpackURI
    * @return
    */
@@ -295,7 +360,6 @@ public class MpackManager {
     return targetPath;
   }
 
-
   /**
    * Compares if the user's mpack information matches the downloaded mpack information.
    *
@@ -305,12 +369,21 @@ public class MpackManager {
    * @param actualMpackVersion
    * @return boolean
    */
-  protected boolean validateMpackInfo(String expectedMpackName, String expectedMpackVersion, String actualMpackName, String actualMpackVersion) {
-    if (expectedMpackName.equalsIgnoreCase(actualMpackName) && expectedMpackVersion.equalsIgnoreCase(actualMpackVersion))
+  protected boolean validateMpackInfo(
+    String expectedMpackName,
+    String expectedMpackVersion,
+    String actualMpackName,
+    String actualMpackVersion) {
+
+    String strippedActualMpackVersion = actualMpackVersion.substring(0, actualMpackVersion.lastIndexOf('.'));
+    if (expectedMpackName.equalsIgnoreCase(actualMpackName) && expectedMpackVersion
+      .equalsIgnoreCase(strippedActualMpackVersion)) {
       return true;
-    else
-      LOG.info("Incorrect information : Mismatch in - (" + expectedMpackName + "," + actualMpackName + ") or (" + expectedMpackVersion + "," + actualMpackVersion + ")");
-    return false;
+    } else {
+      LOG.info("Incorrect information : Mismatch in - (" + expectedMpackName + "," + actualMpackName + ") or ("
+        + expectedMpackVersion + "," + actualMpackVersion + ")");
+      return false;
+    }
   }
 
   /**
@@ -320,7 +393,7 @@ public class MpackManager {
    * @return
    * @throws IOException
    */
-  protected Long populateDB(Mpacks mpacks) throws IOException {
+  protected Long populateDB(Mpack mpacks) throws IOException {
     String mpackName = mpacks.getName();
     String mpackVersion = mpacks.getVersion();
     List resultSet = mpackDAO.findByNameVersion(mpackName, mpackVersion);
@@ -339,11 +412,13 @@ public class MpackManager {
   }
 
   /***
-   * Makes an entry or updates the entry in the stack table to establish a link between the mpack and the associated stack
+   * Makes an entry or updates the entry in the stack table to establish a link between the mpack and the
+   * associated stack
+   *
    * @param mpacks
    * @throws IOException
    */
-  protected void populateStackDB(Mpacks mpacks) throws IOException {
+  protected void populateStackDB(Mpack mpacks) throws IOException {
 
     String stackId = mpack.getStackId();
     String[] stackMetaData = stackId.split("-");
@@ -364,6 +439,7 @@ public class MpackManager {
       stackDAO.merge(stackEntity);
     }
   }
+
   /**
    * Fetches the packlet info stored in the memory for mpacks/{mpack_id} call.
    *
@@ -371,7 +447,7 @@ public class MpackManager {
    * @return ArrayList
    */
   public ArrayList<Packlet> getPacklets(Long mpackId) {
-    Mpacks mpack = mpackMap.get(mpackId);
+    Mpack mpack = mpackMap.get(mpackId);
     if (mpack.getPacklets() != null)
       return mpack.getPacklets();
     return null;
@@ -379,13 +455,15 @@ public class MpackManager {
 
   /***
    * Remove the mpack and stack directories when a request comes in to delete a particular mpack.
+   *
    * @param mpackEntity
    * @throws IOException
    */
   public boolean removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException {
 
     boolean stackDelete = false;
-    File mpackDirToDelete = new File(mpackStaging + File.separator + mpackEntity.getMpackName() + File.separator + mpackEntity.getMpackVersion());
+    File mpackDirToDelete = new File(
+      mpackStaging + File.separator + mpackEntity.getMpackName() + File.separator + mpackEntity.getMpackVersion());
     File mpackDirectory = new File(mpackStaging + "/" + mpackEntity.getMpackName());
     String mpackName = mpackEntity.getMpackName() + "-" + mpackEntity.getMpackVersion() + ".tar.gz";
     Path mpackTarFile = Paths.get(mpackStaging + File.separator + MPACK_TAR_LOCATION +File.separator + mpackName);
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/Mpack.java
similarity index 98%
rename from ambari-server/src/main/java/org/apache/ambari/server/state/Mpacks.java
rename to ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
index 8b7d055..83470ea 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Mpacks.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Mpack.java
@@ -25,7 +25,7 @@ import java.util.HashMap;
 /**
  * Represents the state of an mpack.
  */
-public class Mpacks {
+public class Mpack {
 
   private Long mpackId;
 
@@ -160,7 +160,7 @@ public class Mpacks {
       return false;
     }
 
-    Mpacks other = (Mpacks) obj;
+    Mpack other = (Mpack) obj;
 
     if (name != other.name) {
       return false;
@@ -249,7 +249,7 @@ public class Mpacks {
     return sb.toString();
   }
 
-  public void copyFrom(Mpacks mpack) {
+  public void copyFrom(Mpack mpack) {
     if (this.name == null)
       this.name = mpack.getName();
     if (this.mpackId == null)
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
index 388c256..f21ca64 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/MpackTest.java
@@ -28,7 +28,7 @@ import com.google.gson.Gson;
 public class MpackTest {
   @Test
   public void testMpacks() {
-    Mpacks mpack = new Mpacks();
+    Mpack mpack = new Mpack();
     mpack.setName("name");
     mpack.setMpackId((long)100);
     mpack.setDescription("desc");


[ambari] 03/20: AMBARI-21231: Mpack to Stack Linkage and Parsing mpacks at bootstrap (mradhakrishnan)

Posted by mr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

mradhakrishnan pushed a commit to branch AMBARI-24711
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 9106dccb0cc93497253ba57a215c00238dc300ff
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
AuthorDate: Fri Jul 7 09:49:10 2017 -0700

    AMBARI-21231: Mpack to Stack Linkage and Parsing mpacks at bootstrap  (mradhakrishnan)
---
 ambari-server/src/main/assemblies/server.xml       |   8 +
 .../api/resources/MpackResourceDefinition.java     |  52 +++
 .../resources/StackVersionResourceDefinition.java  |   8 +-
 .../ambari/server/api/services/AmbariMetaInfo.java |   5 +-
 .../controller/AmbariManagementControllerImpl.java |  45 ++-
 .../ambari/server/controller/MpackResponse.java    |  10 +
 .../controller/internal/MpackResourceProvider.java |  47 ++-
 .../apache/ambari/server/mpack/MpackManager.java   | 179 +++++++---
 .../ambari/server/mpack/MpackManagerFactory.java   |   3 +-
 .../ambari/server/orm/entities/StackEntity.java    |  15 +
 .../apache/ambari/server/stack/StackManager.java   |   5 +-
 .../org/apache/ambari/server/state/Mpacks.java     | 382 +++++++++++----------
 .../org/apache/ambari/server/state/Packlet.java    |  22 ++
 .../src/main/resources/Ambari-DDL-Derby-CREATE.sql |  36 +-
 .../src/main/resources/Ambari-DDL-MySQL-CREATE.sql |  35 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql    |  36 +-
 .../main/resources/Ambari-DDL-Postgres-CREATE.sql  |  36 +-
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql    |  36 +-
 .../main/resources/Ambari-DDL-SQLServer-CREATE.sql |  36 +-
 .../src/main/resources/mpacks-v2/README.txt        |   1 +
 20 files changed, 658 insertions(+), 339 deletions(-)

diff --git a/ambari-server/src/main/assemblies/server.xml b/ambari-server/src/main/assemblies/server.xml
index 67858e7..21524ee 100644
--- a/ambari-server/src/main/assemblies/server.xml
+++ b/ambari-server/src/main/assemblies/server.xml
@@ -203,6 +203,14 @@
 	  </includes>
     </fileSet>
     <fileSet>
+      <directoryMode>700</directoryMode>
+      <directory>src/main/resources/mpacks-v2</directory>
+      <outputDirectory>/var/lib/ambari-server/resources/mpacks-v2</outputDirectory>
+      <excludes>
+        <exclude>*/**</exclude>
+      </excludes>
+    </fileSet>
+    <fileSet>
       <fileMode>755</fileMode>
       <directory>src/main/python/ambari_server</directory>
       <outputDirectory>/usr/lib/ambari-server/lib/ambari_server</outputDirectory>
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
index e33cd31..26972d8 100644
--- 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
@@ -17,11 +17,18 @@
  */
 package org.apache.ambari.server.api.resources;
 
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.ambari.server.controller.internal.ResourceImpl;
 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;
 
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+
 /**
  * Resource Definition for Mpack Resource types.
  */
@@ -47,4 +54,49 @@ public class MpackResourceDefinition extends BaseResourceDefinition {
   public String getSingularName() {
     return "mpack";
   }
+
+  @Override
+  public List<PostProcessor> getPostProcessors() {
+    List<PostProcessor> listProcessors = new ArrayList<>();
+    listProcessors.add(new MpackHrefProcessor());
+    listProcessors.add(new MpackPostProcessor());
+    return listProcessors;
+  }
+
+  /**
+   * Post Processing the mpack href when the call comes from stack endpoint to ensure that the
+   * href is a backreference to the mpacks end point
+   */
+  private class MpackHrefProcessor extends BaseHrefPostProcessor {
+    @Override
+    public void process(Request request, TreeNode<Resource> resultNode, String href) {
+      if (href.contains("/stacks/")) {
+        ResourceImpl mpack = (ResourceImpl) resultNode.getObject();
+        Map<String, Map<String, Object>> mapInfo = mpack.getPropertiesMap();
+        Map<String, Object> mpackInfo = mapInfo.get("MpackInfo");
+
+        int idx = href.indexOf("stacks/");
+        Long mpackId = (Long)mpackInfo.get("mpack_id");
+        href = href.substring(0, idx) + "mpacks/" + mpackId;
+        resultNode.setProperty("href", href);
+      } else {
+        super.process(request, resultNode, href);
+      }
+    }
+  }
+
+  /***
+   * Post processing to change the name of the result node to current_mpack
+   */
+  private class MpackPostProcessor implements PostProcessor {
+    @Override
+    public void process(Request request, TreeNode<Resource> resultNode, String href) {
+      if (href.contains("/stacks/")) {
+        resultNode.setName("current_mpack");
+
+      }
+    }
+  }
+
+
 }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
index dff11bb..14f8b4f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
@@ -7,7 +7,7 @@
  * "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
+ * 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,
@@ -20,7 +20,6 @@ package org.apache.ambari.server.api.resources;
 
 import java.util.HashSet;
 import java.util.Set;
-
 import org.apache.ambari.server.controller.spi.Resource;
 
 public class StackVersionResourceDefinition extends BaseResourceDefinition {
@@ -50,7 +49,8 @@ public class StackVersionResourceDefinition extends BaseResourceDefinition {
     children.add(new SubResourceDefinition(Resource.Type.RepositoryVersion));
     children.add(new SubResourceDefinition(Resource.Type.StackArtifact));
     children.add(new SubResourceDefinition(Resource.Type.CompatibleRepositoryVersion));
-
+    children.add(new SubResourceDefinition(Resource.Type.Mpack, null, false));
     return children;
   }
-}
+
+ }
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 8ad5357..ea0c68b 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
@@ -59,6 +59,7 @@ 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.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
 import org.apache.ambari.server.stack.StackManager;
 import org.apache.ambari.server.stack.StackManagerFactory;
@@ -280,7 +281,7 @@ public class AmbariMetaInfo {
     stackManager = stackManagerFactory.create(stackRoot, commonServicesRoot, extensionsRoot,
         osFamily, false);
 
-    mpackManager = mpackManagerFactory.create(mpacksV2Staging);
+    mpackManager = mpackManagerFactory.create(mpacksV2Staging, stackRoot);
 
     getCustomActionDefinitions(customActionRoot);
   }
@@ -1506,6 +1507,7 @@ public class AmbariMetaInfo {
     return versionDefinitions;
   }
 
+
   /**
    * Reads a Kerberos descriptor from the specified file path.
    *
@@ -1538,4 +1540,5 @@ public class AmbariMetaInfo {
   public File getCommonWidgetsDescriptorFile() {
     return commonWidgetsDescriptorFile;
   }
+
 }
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 9ac40c0..9632d47 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
@@ -202,6 +202,20 @@ 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.Clusters;
+import org.apache.ambari.server.state.ServiceComponentFactory;
+import org.apache.ambari.server.state.ServiceComponentHostFactory;
+import org.apache.ambari.server.state.ConfigFactory;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.CommandScriptDefinition;
 import org.apache.ambari.server.state.PropertyInfo.PropertyType;
 import org.apache.ambari.server.state.RepositoryInfo;
 import org.apache.ambari.server.state.SecurityType;
@@ -220,6 +234,24 @@ import org.apache.ambari.server.state.UnlimitedKeyJCERequirement;
 import org.apache.ambari.server.state.*;
 import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
+import org.apache.ambari.server.state.PropertyInfo;
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.DesiredConfig;
+import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.SecurityType;
+import org.apache.ambari.server.state.HostState;
+import org.apache.ambari.server.state.ServiceComponentHostEvent;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.RepositoryVersionState;
+import org.apache.ambari.server.state.ServiceOsSpecific;
+import org.apache.ambari.server.state.UnlimitedKeyJCERequirement;
+import org.apache.ambari.server.state.ExtensionInfo;
+import org.apache.ambari.server.state.RepositoryInfo;
+import org.apache.ambari.server.state.OperatingSystemInfo;
+import org.apache.ambari.server.state.Packlet;
+import org.apache.ambari.server.state.HostComponentAdminState;
+import org.apache.ambari.server.state.PropertyDependencyInfo;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityController;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityControllerFactory;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinksProfile;
@@ -559,6 +591,14 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     createHostComponents(requests, false);
   }
 
+  public MpackResponse registerMpack(MpackRequest request) throws IOException, AuthorizationException, ResourceAlreadyExistsException{
+    MpackResponse mpackResponse = ambariMetaInfo.registerMpack(request);
+    updateStacks();
+    return mpackResponse;
+  }
+
+
+
   @Override
   public synchronized void createHostComponents(Set<ServiceComponentHostRequest> requests, boolean isBlueprintProvisioned)
      throws AmbariException, AuthorizationException {
@@ -719,11 +759,6 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     m_topologyHolder.get().updateData(getAddedComponentsTopologyEvent(requests));
   }
 
-  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);
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
index 05687c2..d111913 100644
--- 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
@@ -29,6 +29,7 @@ public class MpackResponse {
   private String mpackName;
   private String mpackUri;
   private Long registryId;
+  private String stackId;
 
   public MpackResponse(Mpacks mpacks) {
     this.mpackId = mpacks.getMpackId();
@@ -36,6 +37,7 @@ public class MpackResponse {
     this.mpackUri = mpacks.getMpacksUri();
     this.mpackName = mpacks.getName();
     this.registryId = mpacks.getRegistryId();
+    this.stackId = mpacks.getStackId();
   }
 
   public String getMpackVersion() {
@@ -50,6 +52,14 @@ public class MpackResponse {
     return mpackId;
   }
 
+  public String getStackId() {
+    return stackId;
+  }
+
+  public void setStackId(String stackId) {
+    this.stackId = stackId;
+  }
+
   public String getMpackName() {
     return mpackName;
   }
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
index 65eaeb6..6f90e04 100644
--- 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
@@ -43,12 +43,11 @@ 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.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.Packlet;
 
 /**
@@ -63,10 +62,11 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
   public static final String MPACK_VERSION = "MpackInfo/mpack_version";
   public static final String MPACK_URI = "MpackInfo/mpack_uri";
   public static final String PACKLETS = "MpackInfo/packlets";
-
+  public static final String STACK_NAME_PROPERTY_ID = "MpackInfo/stack_name";
+  public static final String STACK_VERSION_PROPERTY_ID = "MpackInfo/stack_version";
 
   private static Set<String> pkPropertyIds = new HashSet<>(
-          Arrays.asList(MPACK_ID));
+          Arrays.asList(MPACK_ID, STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID));
 
   /**
    * The property ids for an mpack resource.
@@ -81,6 +81,9 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
   @Inject
   protected static MpackDAO mpackDAO;
 
+  @Inject
+  protected static StackDAO stackDAO;
+
   static {
     // properties
     PROPERTY_IDS.add(MPACK_ID);
@@ -89,9 +92,13 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     PROPERTY_IDS.add(MPACK_VERSION);
     PROPERTY_IDS.add(MPACK_URI);
     PROPERTY_IDS.add(PACKLETS);
+    PROPERTY_IDS.add(STACK_NAME_PROPERTY_ID);
+    PROPERTY_IDS.add(STACK_VERSION_PROPERTY_ID);
 
     // keys
     KEY_PROPERTY_IDS.put(Resource.Type.Mpack, MPACK_ID);
+    KEY_PROPERTY_IDS.put(Resource.Type.Stack, STACK_NAME_PROPERTY_ID);
+    KEY_PROPERTY_IDS.put(Resource.Type.StackVersion, STACK_VERSION_PROPERTY_ID);
 
   }
 
@@ -161,7 +168,7 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
           NoSuchResourceException, NoSuchParentResourceException {
 
     Set<Resource> results = new LinkedHashSet<>();
-
+    Long mpackId = null;
     //Fetch all mpacks
     if (predicate == null) {
       List<MpackEntity> entities = mpackDAO.findAll();
@@ -180,9 +187,32 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
     } //Fetch a particular mpack based on id
     else {
       Map<String, Object> propertyMap = new HashMap<>(PredicateHelper.getProperties(predicate));
+      if (propertyMap.containsKey(STACK_NAME_PROPERTY_ID) && propertyMap.containsKey(STACK_VERSION_PROPERTY_ID)) {
+        String stackName = (String) propertyMap.get(STACK_NAME_PROPERTY_ID);
+        String stackVersion = (String) propertyMap.get(STACK_VERSION_PROPERTY_ID);
+        StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
+        mpackId = stackEntity.getCurrentMpackId();
+        if (mpackId != null) {
+          MpackEntity entity = mpackDAO.findById(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(STACK_NAME_PROPERTY_ID, stackName);
+            resource.setProperty(STACK_VERSION_PROPERTY_ID, stackVersion);
+            results.add(resource);
+          }
+        }
+        return results;
+      }
+
       if (propertyMap.containsKey(MPACK_ID)) {
-        String mpackId = (String) propertyMap.get(MPACK_ID);
-        MpackEntity entity = mpackDAO.findById(Long.parseLong((mpackId)));
+        Object objMpackId = propertyMap.get(MPACK_ID);
+        if(objMpackId != null)
+          mpackId = Long.valueOf((String) objMpackId);
+
+        MpackEntity entity = mpackDAO.findById(mpackId);
         Resource resource = new ResourceImpl(Resource.Type.Mpack);
         if (null != entity) {
           resource.setProperty(MPACK_ID, entity.getMpackId());
@@ -201,7 +231,6 @@ public class MpackResourceProvider extends AbstractControllerResourceProvider {
                 "The requested resource doesn't exist: " + predicate);
       }
     }
-
     return results;
   }
 
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
index a031af3..f19320e 100644
--- 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
@@ -24,7 +24,9 @@ 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.dao.StackDAO;
 import org.apache.ambari.server.orm.entities.MpackEntity;
+import org.apache.ambari.server.orm.entities.StackEntity;
 import org.apache.ambari.server.state.Mpacks;
 import org.apache.ambari.server.state.Packlet;
 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
@@ -59,17 +61,59 @@ public class MpackManager {
   protected Map<Long, Mpacks> mpackMap = new HashMap<>();
   private File mpackStaging;
   private MpackDAO mpackDAO;
+  private StackDAO stackDAO;
   private Mpacks mpack;
+  private File stackRoot;
+  private static final String MPACK_METADATA = "mpack.json";
+  private static final String MPACK_TAR_LOCATION = "staging";
 
   private final static Logger LOG = LoggerFactory.getLogger(MpackManager.class);
 
   @AssistedInject
-  public MpackManager(@Assisted("mpackv2Staging") File mpackStagingLoc, MpackDAO mpackDAOObj) {
-    mpackStaging = mpackStagingLoc;
+  public MpackManager(@Assisted("mpackv2Staging") File mpackStagingLocation, @Assisted("stackRoot") File stackRootDir, MpackDAO mpackDAOObj, StackDAO stackDAOObj) {
+    mpackStaging = mpackStagingLocation;
     mpackDAO = mpackDAOObj;
-    //Todo : Madhu Load all mpack.json into mpackMap during ambari-server startup
+    stackRoot = stackRootDir;
+    stackDAO = stackDAOObj;
+
+    parseMpackDirectories();
+
+  }
+
+  /**
+   * Parses mpackdirectories during boostrap/ambari-server restart
+   * Reads from /var/lib/ambari-server/mpacks-v2/
+   *
+   * @throws IOException
+   */
+  private void parseMpackDirectories() {
+    try {
+      for (final File dirEntry : mpackStaging.listFiles()) {
+        if (dirEntry.isDirectory()) {
+          String mpackName = dirEntry.getName();
+          if (!mpackName.equals(MPACK_TAR_LOCATION)) {
+            for (final File file : dirEntry.listFiles()) {
+              if (file.isDirectory()) {
+                String mpackVersion = file.getName();
+                List resultSet = mpackDAO.findByNameVersion(mpackName, mpackVersion);
+                MpackEntity mpackEntity = (MpackEntity) resultSet.get(0);
+
+                //Read the mpack.json file into Mpack Object for further use.
+                String mpackJsonContents = new String((Files.readAllBytes(Paths.get(file + "/" + MPACK_METADATA))), "UTF-8");
+                Gson gson = new Gson();
+                Mpacks existingMpack = gson.fromJson(mpackJsonContents, Mpacks.class);
+                mpackMap.put(mpackEntity.getMpackId(), existingMpack);
+              }
+            }
+          }
+        }
+      }
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
   }
 
+
   /**
    * Parses mpack.json to fetch mpack and associated packlet information and
    * stores the mpack to the database and mpackMap
@@ -81,48 +125,53 @@ public class MpackManager {
    * @throws ResourceAlreadyExistsException
    */
   public MpackResponse registerMpack(MpackRequest mpackRequest) throws IOException, IllegalArgumentException, ResourceAlreadyExistsException {
-    //Todo : Madhu Update StacksAPI
 
     Long mpackId;
-    mpack = new Mpacks();
     String mpackName = "";
     String mpackVersion = "";
-    boolean isValidMetadata = true;
+    mpack = new Mpacks();
+    boolean isValidMetadata;
+    String mpackDirectory = "";
+    Path mpackTarPath;
 
     //Mpack registration using a software registry
     if (mpackRequest.getRegistryId() != null) {
       mpackName = mpackRequest.getMpackName();
       mpackVersion = mpackRequest.getMpackVersion();
       mpack.setRegistryId(mpackRequest.getRegistryId());
-      //Validate the Post request
-      isValidMetadata = validateMpackInfo(mpackName, mpackVersion, mpack.getName(), mpack.getVersion());
+
       //Todo : Madhu implement GET /registries/{registryId}/mpacks
-    } else {
-      //Mpack registration using direct download
-      mpack.setMpacksUri(mpackRequest.getMpackUri());
-    }
+      mpackTarPath = downloadMpack(mpackRequest.getMpackUri());
 
-    //Download the mpack and return the path.
-    Path mpackTarPath = downloadMpack(mpackRequest.getMpackUri(), mpackStaging + File.separator);
-    //create a directory as mpack-staging-path/mpack-name/mpack-version
-    if (createMpackDirectory(mpackTarPath)) {
-      //expand the mpack.tar.gz file inside the directory created above
-      String mpackDirectory = mpackStaging + File.separator + mpack.getName() + File.separator + mpack.getVersion();
-      extractMpackTar(mpackTarPath, mpackDirectory);
-    }
-    if (isValidMetadata) {
-      mpackId = populateDB(mpack);
-      if (mpackId != null) {
-        mpackMap.put(mpackId, mpack);
-        mpack.setMpackId(mpackId);
-        return new MpackResponse(mpack);
-      } else {
-        String message = "Mpack :" + mpackRequest.getMpackName() + " version: " + mpackRequest.getMpackVersion() + " already exists in server";
-        throw new ResourceAlreadyExistsException(message);
+      if (createMpackDirectory(mpackTarPath)) {
+        isValidMetadata = validateMpackInfo(mpackName, mpackVersion, mpack.getName(), mpack.getVersion());
+        if (isValidMetadata) {
+          mpackDirectory = mpackStaging + File.separator + mpack.getName() + File.separator + mpack.getVersion();
+        } else {
+          String message = "Incorrect information : Mismatch in - (" + mpackName + "," + mpack.getName() + ") or (" + mpackVersion + "," + mpack.getVersion() + ")";
+          throw new IllegalArgumentException(message); //Mismatch in information
+        }
+
+      }
+    } else {    //Mpack registration using direct download
+      mpackTarPath = downloadMpack(mpackRequest.getMpackUri());
+
+      if (createMpackDirectory(mpackTarPath)) {
+        mpackDirectory = mpackStaging + File.separator + mpack.getName() + File.separator + mpack.getVersion();
+        mpack.setMpacksUri(mpackRequest.getMpackUri());
       }
+    }
+    extractMpackTar(mpackTarPath, mpackDirectory);
+    mpackId = populateDB(mpack);
+
+    if (mpackId != null) {
+      mpackMap.put(mpackId, mpack);
+      mpack.setMpackId(mpackId);
+      populateStackDB(mpack);
+      return new MpackResponse(mpack);
     } else {
-      String message = "Incorrect information : Mismatch in - (" + mpackName + "," + mpack.getName() + ") or (" + mpackVersion + "," + mpack.getVersion() + ")";
-      throw new IllegalArgumentException(message); //Mismatch in information
+      String message = "Mpack :" + mpackRequest.getMpackName() + " version: " + mpackRequest.getMpackVersion() + " already exists in server";
+      throw new ResourceAlreadyExistsException(message);
     }
   }
 
@@ -161,6 +210,8 @@ public class MpackManager {
     Path extractedMpackDirectory = Files.move
             (Paths.get(mpackStaging + File.separator + mpackTarDirectory.substring(mpackTarDirectory.lastIndexOf('/') + 1, mpackTarDirectory.indexOf(".tar")) + File.separator),
                     Paths.get(mpackDirectory), StandardCopyOption.REPLACE_EXISTING);
+
+    createSymLinks();
   }
 
   /**
@@ -188,7 +239,6 @@ public class MpackManager {
         // Get Size of the file and create a byte array for the size
         byte[] content = new byte[(int) entry.getSize()];
         offset = 0;
-        LOG.info("File Name in TAR File is: " + fileName);
         LOG.debug("Size of the File is: " + entry.getSize());
         // Read file from the archive into byte array
         mpackTarFile.read(content, offset, content.length - offset);
@@ -196,29 +246,49 @@ public class MpackManager {
         //Read the mpack.json file into Mpack Object for further use.
         String mpackJsonContents = new String(content, "UTF-8");
         Gson gson = new Gson();
-        mpack = gson.fromJson(mpackJsonContents, Mpacks.class);
+        Mpacks tempMpack = gson.fromJson(mpackJsonContents, Mpacks.class);
+        mpack.copyFrom(tempMpack);
 
         mpackTarFile.close();
 
-        return new File(mpackStaging + File.separator + mpack.getName()).mkdir();
-
+        File mpackDirectory = new File(mpackStaging + File.separator + mpack.getName());
+        if (!mpackDirectory.exists())
+          return mpackDirectory.mkdir();
+        else
+          return true;
       }
     }
 
     return false;
   }
 
+  /***
+   * Create a linkage between the staging directory and the working directory i.e from mpacks-v2 to stackRoot.
+   * This will enable StackManager to parse the newly registered mpack as part of the stacks.
+   * @throws IOException
+   */
+  private void createSymLinks() throws IOException {
+    String stackId = mpack.getStackId();
+    String[] stackMetaData = stackId.split("-");
+    String stackName = stackMetaData[0];
+    String stackVersion = stackMetaData[1];
+    Path stackPath = Paths.get(stackRoot + "/" + stackName + "/" + stackVersion);
+    Path mpackPath = Paths.get(mpackStaging + "/" + mpack.getName() + "/" + mpack.getVersion());
+    if(Files.isSymbolicLink(stackPath))
+      Files.delete(stackPath);
+    Files.createSymbolicLink(stackPath, mpackPath);
+  }
+
 
   /***
    * Download the mpack from the given uri
-   * @param sourceURI
-   * @param targetDirectory
+   * @param mpackURI
    * @return
    */
-  public static Path downloadMpack(String sourceURI, String targetDirectory) throws IOException {
-    URL url = new URL(sourceURI);
-    String fileName = sourceURI.substring(sourceURI.lastIndexOf('/') + 1, sourceURI.length());
-    Path targetPath = new File(targetDirectory + File.separator + fileName).toPath();
+  public Path downloadMpack(String mpackURI) throws IOException {
+    URL url = new URL(mpackURI);
+    String fileName = mpackURI.substring(mpackURI.lastIndexOf('/') + 1, mpackURI.length());
+    Path targetPath = new File(mpackStaging.toString() + File.separator + MPACK_TAR_LOCATION + File.separator + fileName).toPath();
     Files.copy(url.openStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
 
     return targetPath;
@@ -267,8 +337,35 @@ public class MpackManager {
     return null;
   }
 
+  /***
+   * Makes an entry or updates the entry in the stack table to establish a link between the mpack and the associated stack
+   * @param mpacks
+   * @throws IOException
+   */
+  protected void populateStackDB(Mpacks mpacks) throws IOException {
+
+    String stackId = mpack.getStackId();
+    String[] stackMetaData = stackId.split("-");
+    String stackName = stackMetaData[0];
+    String stackVersion = stackMetaData[1];
+
+    StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
+    if (stackEntity == null) {
+      LOG.info("Adding stack {}-{} to the database", stackName, stackVersion);
+      stackEntity = new StackEntity();
+      stackEntity.setStackName(stackName);
+      stackEntity.setStackVersion(stackVersion);
+      stackEntity.setCurrentMpackId(mpacks.getMpackId());
+      stackDAO.create(stackEntity);
+    } else {
+      LOG.info("Updating stack {}-{} to the database", stackName, stackVersion);
+      stackEntity.setCurrentMpackId(mpacks.getMpackId());
+      stackDAO.merge(stackEntity);
+    }
+  }
   /**
    * Fetches the packlet info stored in the memory for mpacks/{mpack_id} call.
+   *
    * @param mpackId
    * @return ArrayList
    */
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
index 67820c8..2336b1a 100644
--- 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
@@ -31,7 +31,8 @@ public interface MpackManagerFactory {
   /**
    * @param mpackStaging
    *        the folder location where mpack is downloaded. (not {@code null}).
+   * @param stackRoot
    * @return a mpack manager instance.
    */
-  MpackManager create(@Assisted("mpackv2Staging") File mpackStaging);
+  MpackManager create(@Assisted("mpackv2Staging") File mpackStaging, @Assisted("stackRoot") File stackRoot);
 }
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
index 2cfe07c..0cb8628 100644
--- 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
@@ -59,6 +59,20 @@ public class StackEntity {
   @Column(name = "stack_version", length = 255, nullable = false)
   private String stackVersion;
 
+
+  @Column(name = "current_mpack_id")
+  private Long currentMpackId;
+
+
+  public Long getCurrentMpackId() {
+    return currentMpackId;
+  }
+
+  public void setCurrentMpackId(Long currentMpackId) {
+    this.currentMpackId = currentMpackId;
+  }
+
+
   /**
    * Constructor.
    */
@@ -154,6 +168,7 @@ public class StackEntity {
     buffer.append("id=").append(stackId);
     buffer.append(", name=").append(stackName);
     buffer.append(", version=").append(stackVersion);
+    buffer.append(", current_mpack_id=").append(currentMpackId);
     buffer.append("}");
     return buffer.toString();
   }
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 3473fe8..fbd0d8c 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
@@ -115,7 +115,7 @@ public class StackManager {
   /**
    * Constructor. Initialize stack manager.
    *
-   * @param stackRoot
+   * @param stackRootDir
    *          stack root directory
    * @param commonServicesRoot
    *          common services root directory
@@ -140,7 +140,7 @@ public class StackManager {
    *           if an exception occurs while processing the stacks
    */
   @AssistedInject
-  public StackManager(@Assisted("stackRoot") File stackRoot,
+  public StackManager(@Assisted("stackRoot") File stackRootDir,
       @Assisted("commonServicesRoot") @Nullable File commonServicesRoot,
       @Assisted("extensionRoot") @Nullable File extensionRoot,
       @Assisted OsFamily osFamily, @Assisted boolean validate,
@@ -150,6 +150,7 @@ public class StackManager {
 
     LOG.info("Initializing the stack manager...");
 
+    stackRoot = stackRootDir;
     if (validate) {
       validateStackDirectory(stackRoot);
       validateCommonServicesDirectory(commonServicesRoot);
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
index 9a457b0..8b7d055 100644
--- 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
@@ -27,211 +27,245 @@ import java.util.HashMap;
  */
 public class Mpacks {
 
-    private Long mpackId;
+  private Long mpackId;
 
-    private Long registryId;
+  private Long registryId;
 
-    @SerializedName("name")
-    private String name;
+  @SerializedName("name")
+  private String name;
 
-    @SerializedName("version")
-    private String version;
+  @SerializedName("version")
+  private String version;
 
-    @SerializedName("description")
-    private String description;
+  @SerializedName("description")
+  private String description;
 
-    @SerializedName("prerequisites")
-    private HashMap<String,String> prerequisites;
+  @SerializedName("prerequisites")
+  private HashMap<String, String> prerequisites;
 
-    @SerializedName("packlets")
-    private ArrayList<Packlet> packlets;
+  @SerializedName("packlets")
+  private ArrayList<Packlet> packlets;
 
-    private String mpacksUri;
-
-    public Long getMpackId() {
-        return mpackId;
-    }
-
-    public void setMpackId(Long mpackId) {
-        this.mpackId = mpackId;
+  @SerializedName("stack-id")
+  private String stackId;
+
+  private String mpacksUri;
+
+  public Long getMpackId() {
+    return mpackId;
+  }
+
+  public void setMpackId(Long mpackId) {
+    this.mpackId = mpackId;
+  }
+
+  public Long getRegistryId() {
+    return registryId;
+  }
+
+  public void setRegistryId(Long registryId) {
+    this.registryId = registryId;
+  }
+
+  public String getMpacksUri() {
+    return mpacksUri;
+  }
+
+  public void setMpacksUri(String mpacksUri) {
+    this.mpacksUri = mpacksUri;
+  }
+
+  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;
+  }
+
+
+  public String getStackId() {
+    return stackId;
+  }
+
+  public void setStackId(String stackId) {
+    this.stackId = stackId;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((mpackId == null) ? 0 : mpackId.hashCode());
+    result = prime * result + ((name == null) ? 0 : name.hashCode());
+    result = prime * result + ((version == null) ? 0 : version.hashCode());
+    result = prime * result + ((registryId == null) ? 0 : registryId.hashCode());
+    result = prime * result + ((description == null) ? 0 : description.hashCode());
+    result = prime * result + ((prerequisites == null) ? 0 : prerequisites.hashCode());
+    result = prime * result + ((packlets == null) ? 0 : packlets.hashCode());
+    result = prime * result + ((stackId == null) ? 0 : stackId.hashCode());
+    result = prime * result + ((mpacksUri == null) ? 0 : mpacksUri.hashCode());
+    return result;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
     }
 
-    public Long getRegistryId() {
-        return registryId;
+    if (obj == null) {
+      return false;
     }
 
-    public void setRegistryId(Long registryId) {
-        this.registryId = registryId;
+    if (getClass() != obj.getClass()) {
+      return false;
     }
 
-    public String getMpacksUri() {
-        return mpacksUri;
-    }
+    Mpacks other = (Mpacks) obj;
 
-    public void setMpacksUri(String mpacksUri) {
-        this.mpacksUri = mpacksUri;
+    if (name != other.name) {
+      return false;
     }
 
-    public String getName() {
-        return name;
+    if (version == null) {
+      if (other.version != null) {
+        return false;
+      }
+    } else if (!version.equals(other.version)) {
+      return false;
     }
 
-    public void setName(String name) {
-        this.name = name;
+    if (description == null) {
+      if (other.description != null) {
+        return false;
+      }
+    } else if (!description.equals(other.description)) {
+      return false;
     }
 
-    public String getVersion() {
-        return version;
+    if (mpackId == null) {
+      if (other.mpackId != null) {
+        return false;
+      }
+    } else if (!mpackId.equals(other.mpackId)) {
+      return false;
     }
 
-    public void setVersion(String version) {
-        this.version = version;
+    if (registryId == null) {
+      if (other.registryId != null) {
+        return false;
+      }
+    } else if (!registryId.equals(other.registryId)) {
+      return false;
     }
 
-    public String getDescription() {
-        return description;
+    if (prerequisites == null) {
+      if (other.prerequisites != null) {
+        return false;
+      }
+    } else if (!prerequisites.equals(other.prerequisites)) {
+      return false;
     }
 
-    public void setDescription(String description) {
-        this.description = description;
+    if (packlets == null) {
+      if (other.packlets != null) {
+        return false;
+      }
+    } else if (!packlets.equals(other.packlets)) {
+      return false;
     }
 
-    public HashMap<String, String> getPrerequisites() {
-        return prerequisites;
+    if (mpacksUri == null) {
+      if (other.mpacksUri != null) {
+        return false;
+      }
+    } else if (!mpacksUri.equals(other.mpacksUri)) {
+      return false;
     }
 
-    public void setPrerequisites(HashMap<String, String> prerequisites) {
-        this.prerequisites = prerequisites;
+    if (stackId == null) {
+      if (other.stackId != null) {
+        return false;
+      }
+    } else if (!stackId.equals(other.stackId)) {
+      return false;
     }
 
-    public ArrayList<Packlet> getPacklets() {
-        return packlets;
-    }
-
-    public void setPacklets(ArrayList<Packlet> packlets) {
-        this.packlets = packlets;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((mpackId == null) ? 0 : mpackId.hashCode());
-        result = prime * result + ((name == null) ? 0 : name.hashCode());
-        result = prime * result + ((version == null) ? 0 : version.hashCode());
-        result = prime * result + ((registryId == null) ? 0 : registryId.hashCode());
-        result = prime * result + ((description == null) ? 0 : description.hashCode());
-        result = prime * result + ((prerequisites == null) ? 0 : prerequisites.hashCode());
-        result = prime * result + ((packlets == null) ? 0 : packlets.hashCode());
-        result = prime * result + ((mpacksUri == null) ? 0 : mpacksUri.hashCode());
-        return result;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-
-        if (obj == null) {
-            return false;
-        }
-
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-
-        Mpacks other = (Mpacks) obj;
-
-        if (name != other.name) {
-            return false;
-        }
-
-        if (version == null) {
-            if (other.version != null) {
-                return false;
-            }
-        } else if (!version.equals(other.version)) {
-            return false;
-        }
-
-        if (description == null) {
-            if (other.description != null) {
-                return false;
-            }
-        } else if (!description.equals(other.description)) {
-            return false;
-        }
-
-        if (mpackId == null) {
-            if (other.mpackId != null) {
-                return false;
-            }
-        } else if (!mpackId.equals(other.mpackId)) {
-            return false;
-        }
-
-        if (registryId == null) {
-            if (other.registryId != null) {
-                return false;
-            }
-        } else if (!registryId.equals(other.registryId)) {
-            return false;
-        }
-
-        if (registryId == null) {
-            if (other.registryId != null) {
-                return false;
-            }
-        } else if (!registryId.equals(other.registryId)) {
-            return false;
-        }
-
-        if (registryId == null) {
-            if (other.registryId != null) {
-                return false;
-            }
-        } else if (!registryId.equals(other.registryId)) {
-            return false;
-        }
-
-        if (prerequisites == null) {
-            if (other.prerequisites != null) {
-                return false;
-            }
-        } else if (!prerequisites.equals(other.prerequisites)) {
-            return false;
-        }
-
-        if (packlets == null) {
-            if (other.packlets != null) {
-                return false;
-            }
-        } else if (!packlets.equals(other.packlets)) {
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append('{');
-        sb.append("name=").append(name).append(", ");
-        sb.append("mpackId=").append(mpackId).append(", ");
-        sb.append("version=").append(version).append(", ");
-        sb.append("registryId=").append(registryId).append(", ");
-        sb.append("description=").append(description).append(", ");
-        sb.append("prereq=").append(prerequisites.toString()).append(", ");
-        sb.append("packlets=").append(packlets.toString()).append(", ");
+    return true;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    sb.append('{');
+    sb.append("name=").append(name).append(", ");
+    sb.append("mpackId=").append(mpackId).append(", ");
+    sb.append("version=").append(version).append(", ");
+    sb.append("stackid=").append(stackId).append(", ");
+    sb.append("registryId=").append(registryId).append(", ");
+    sb.append("description=").append(description).append(", ");
+    sb.append("prereq=").append(prerequisites.toString()).append(", ");
+    sb.append("packlets=").append(packlets.toString()).append(", ");
         sb.append('}');
-        return sb.toString();
-    }
+    return sb.toString();
+  }
+
+  public void copyFrom(Mpacks mpack) {
+    if (this.name == null)
+      this.name = mpack.getName();
+    if (this.mpackId == null)
+      this.mpackId = mpack.getMpackId();
+    if (this.version == null)
+      this.version = mpack.getVersion();
+    if (this.stackId == null)
+      this.stackId = mpack.getStackId();
+    if (this.registryId == null)
+      this.registryId = mpack.getRegistryId();
+    if (this.description == null)
+      this.description = mpack.getDescription();
+    if (this.prerequisites == null)
+      this.prerequisites = mpack.getPrerequisites();
+    if (this.packlets == null)
+      this.packlets = mpack.getPacklets();
+
+  }
 }
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
index 0bd2479..1fa8dee 100644
--- 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
@@ -27,6 +27,8 @@ public class Packlet {
   private String name;
   @SerializedName("version")
   private String version;
+  @SerializedName("service-id")
+  private String serviceId;
   @SerializedName("source_dir")
   private String sourceDir;
 
@@ -62,6 +64,16 @@ public class Packlet {
     this.sourceDir = sourceDir;
   }
 
+
+  public String getServiceId() {
+    return serviceId;
+  }
+
+  public void setServiceId(String serviceId) {
+    this.serviceId = serviceId;
+  }
+
+
   /**
    * {@inheritDoc}
    */
@@ -72,6 +84,7 @@ public class Packlet {
     result = prime * result + ((type == null) ? 0 : type.hashCode());
     result = prime * result + ((name == null) ? 0 : name.hashCode());
     result = prime * result + ((version == null) ? 0 : version.hashCode());
+    result = prime * result + ((serviceId == null) ? 0 : serviceId.hashCode());
     result = prime * result + ((sourceDir == null) ? 0 : sourceDir.hashCode());
     return result;
   }
@@ -115,6 +128,14 @@ public class Packlet {
       return false;
     }
 
+    if (serviceId == null) {
+      if (other.serviceId != null) {
+        return false;
+      }
+    } else if (!serviceId.equals(other.serviceId)) {
+      return false;
+    }
+
     if (sourceDir == null) {
       if (other.sourceDir != null) {
         return false;
@@ -132,6 +153,7 @@ public class Packlet {
     sb.append("type=").append(type).append(", ");
     sb.append("name=").append(name).append(", ");
     sb.append("version=").append(version).append(", ");
+    sb.append("service id=").append(serviceId).append(", ");
     sb.append("source directory=").append(sourceDir).append(", ");
     sb.append('}');
     return sb.toString();
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 6b559a3..bef2c1c 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -17,11 +17,30 @@
 --
 
 ------create tables and grant privileges to db user---------
+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 TABLE stack(
   stack_id BIGINT NOT NULL,
   stack_name VARCHAR(255) NOT NULL,
   stack_version VARCHAR(255) NOT NULL,
+  current_mpack_id BIGINT,
   CONSTRAINT PK_stack PRIMARY KEY (stack_id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
@@ -939,23 +958,6 @@ 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);
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 3f77778..f24844e 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -36,12 +36,30 @@ prepare statement from @engine_stmt;
 execute statement;
 DEALLOCATE PREPARE statement;
 
+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 TABLE stack(
   stack_id BIGINT NOT NULL,
   stack_name VARCHAR(100) NOT NULL,
   stack_version VARCHAR(100) NOT NULL,
+  current_mpack_id BIGINT,
   CONSTRAINT PK_stack PRIMARY KEY (stack_id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
@@ -1128,23 +1146,6 @@ 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);
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 ca192cf..7c8ca77 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -17,11 +17,30 @@
 --
 
 ------create tables---------
+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 TABLE stack(
   stack_id NUMBER(19) NOT NULL,
   stack_name VARCHAR2(255) NOT NULL,
   stack_version VARCHAR2(255) NOT NULL,
+  current_mpack_id BIGINT,
   CONSTRAINT PK_stack PRIMARY KEY (stack_id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
@@ -1107,23 +1126,6 @@ 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);
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 c888dac..a6efcbc 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -17,11 +17,30 @@
 --
 
 ------create tables and grant privileges to db user---------
+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 TABLE stack(
   stack_id BIGINT NOT NULL,
   stack_name VARCHAR(255) NOT NULL,
   stack_version VARCHAR(255) NOT NULL,
+  current_mpack_id BIGINT,
   CONSTRAINT PK_stack PRIMARY KEY (stack_id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
@@ -1642,23 +1661,6 @@ 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);
 
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 eb01504..76fa36c 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -16,11 +16,30 @@
 -- limitations under the License.
 --
 
+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 TABLE stack(
   stack_id NUMERIC(19) NOT NULL,
   stack_name VARCHAR(255) NOT NULL,
   stack_version VARCHAR(255) NOT NULL,
+  current_mpack_id BIGINT,
   CONSTRAINT PK_stack PRIMARY KEY (stack_id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
@@ -1107,23 +1126,6 @@ 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);
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 7b3298b..0ce1cde 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -29,11 +29,30 @@ sqlcmd -S localhost\SQLEXPRESS -i C:\app\ambari-server-1.3.0-SNAPSHOT\resources\
 ------create the database------
 
 ------create tables and grant privileges to db user---------
+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 TABLE stack(
   stack_id BIGINT NOT NULL,
   stack_name VARCHAR(255) NOT NULL,
   stack_version VARCHAR(255) NOT NULL,
+  current_mpack_id BIGINT,
   CONSTRAINT PK_stack PRIMARY KEY CLUSTERED (stack_id),
+  CONSTRAINT FK_mpacks FOREIGN KEY (current_mpack_id) REFERENCES mpacks(id),
   CONSTRAINT UQ_stack UNIQUE (stack_name, stack_version));
 
 CREATE TABLE extension(
@@ -1131,23 +1150,6 @@ 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);
diff --git a/ambari-server/src/main/resources/mpacks-v2/README.txt b/ambari-server/src/main/resources/mpacks-v2/README.txt
new file mode 100644
index 0000000..fae891f
--- /dev/null
+++ b/ambari-server/src/main/resources/mpacks-v2/README.txt
@@ -0,0 +1 @@
+This folder is reserved for mpacks.
\ No newline at end of file