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 <[email protected]>
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());
   }
 
 }

Reply via email to