AMBARI-22650 Add ability to define packages at stack level (dsen)

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

Branch: refs/heads/branch-feature-AMBARI-14714
Commit: 0b1ce86bb270432b8c58c5f05a18008ea1e864ca
Parents: 481175d
Author: Dmytro Sen <d...@apache.org>
Authored: Fri Dec 15 14:16:55 2017 +0200
Committer: Dmytro Sen <d...@apache.org>
Committed: Fri Dec 15 14:16:55 2017 +0200

----------------------------------------------------------------------
 .../controller/AmbariManagementController.java  |   8 +-
 .../AmbariManagementControllerImpl.java         |  63 ++---
 .../internal/ClientConfigResourceProvider.java  |  57 +----
 .../ClusterStackVersionResourceProvider.java    |   2 -
 .../server/stack/ModuleFileUnmarshaller.java    |   4 +-
 .../apache/ambari/server/stack/StackModule.java |   1 +
 .../apache/ambari/server/state/OsSpecific.java  | 250 +++++++++++++++++++
 .../apache/ambari/server/state/ServiceInfo.java |  12 +-
 .../ambari/server/state/ServiceOsSpecific.java  | 249 ------------------
 .../apache/ambari/server/state/StackInfo.java   |  19 ++
 .../server/state/stack/StackMetainfoXml.java    |  44 +++-
 .../stack/upgrade/RepositoryVersionHelper.java  |  16 +-
 .../AmbariManagementControllerImplTest.java     |  46 ++--
 .../AmbariManagementControllerTest.java         |  27 +-
 .../ClientConfigResourceProviderTest.java       |  30 +--
 ...ClusterStackVersionResourceProviderTest.java |  80 +++---
 .../HostStackVersionResourceProviderTest.java   |  30 ++-
 .../ambari/server/stack/ServiceModuleTest.java  |  10 +-
 .../stack/StackManagerCommonServicesTest.java   |  24 +-
 .../ambari/server/stack/StackManagerTest.java   |  28 ++-
 .../test/resources/stacks/HDP/0.1/metainfo.xml  |  10 +
 .../resources/stacks/HDP/2.0.1/metainfo.xml     |  18 ++
 .../stacks/HDP/2.0.1/services/HIVE/metainfo.xml |   8 -
 .../HDP/0.1/metainfo.xml                        |  10 +
 24 files changed, 573 insertions(+), 473 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index 6385118..c2bf783 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
@@ -57,6 +57,7 @@ import org.apache.ambari.server.state.Config;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.HostState;
 import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.OsSpecific;
 import org.apache.ambari.server.state.Packlet;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
@@ -65,8 +66,8 @@ import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.ServiceFactory;
 import org.apache.ambari.server.state.ServiceGroupFactory;
 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.configgroup.ConfigGroupFactory;
 import 
org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityController;
@@ -870,13 +871,14 @@ public interface AmbariManagementController {
   Set<ReadOnlyConfigurationResponse> 
getResourceLevelClusterSettings(Set<RootClusterSettingRequest> requests) throws 
AmbariException;
 
   /**
+   * @param stackInfo stack info for a given service stack
    * @param serviceInfo service info for a given service
    * @param hostParams parameter map. May be changed during method execution
    * @param osFamily os family for host
-   * @return a full list of package dependencies for a service that should be
+   * @return a full list of package dependencies for a stack service that 
should be
    * installed on a host
    */
-  List<ServiceOsSpecific.Package> getPackagesForServiceHost(ServiceInfo 
serviceInfo,
+  List<OsSpecific.Package> getPackagesForStackServiceHost(StackInfo stackInfo, 
ServiceInfo serviceInfo,
                                                             Map<String, 
String> hostParams, String osFamily);
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 9be79e7..1bf5299 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
@@ -175,6 +175,7 @@ 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.OperatingSystemInfo;
+import org.apache.ambari.server.state.OsSpecific;
 import org.apache.ambari.server.state.Packlet;
 import org.apache.ambari.server.state.PropertyDependencyInfo;
 import org.apache.ambari.server.state.PropertyInfo;
@@ -190,7 +191,6 @@ import 
org.apache.ambari.server.state.ServiceComponentHostFactory;
 import org.apache.ambari.server.state.ServiceFactory;
 import org.apache.ambari.server.state.ServiceGroupFactory;
 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;
@@ -2653,8 +2653,8 @@ public class AmbariManagementControllerImpl implements 
AmbariManagementControlle
       hostParams.put(KeyNames.REPO_VERSION_ID, repoVersion.getId().toString());
     }
 
-    List<ServiceOsSpecific.Package> packages =
-            getPackagesForServiceHost(serviceInfo, hostParams, osFamily);
+    List<OsSpecific.Package> packages =
+        getPackagesForStackServiceHost(ambariMetaInfo.getStack(stackId), 
serviceInfo, hostParams, osFamily);
     String packageList = gson.toJson(packages);
     hostParams.put(PACKAGE_LIST, packageList);
 
@@ -2742,59 +2742,64 @@ public class AmbariManagementControllerImpl implements 
AmbariManagementControlle
   }
 
   /**
-   * Computes os-dependent packages for service/host. Does not take into
+   * Computes os-dependent packages for osSpecificMap. Does not take into
    * account package dependencies for ANY_OS. Instead of this method
-   * you should use getPackagesForServiceHost()
+   * you should use getPackagesForStackServiceHost()
    * because it takes into account both os-dependent and os-independent lists
-   * of packages for service.
+   * of packages for stack service.
    * @param hostParams may be modified (appended SERVICE_REPO_INFO)
    * @return a list of os-dependent packages for host
    */
-  protected ServiceOsSpecific populateServicePackagesInfo(ServiceInfo 
serviceInfo, Map<String, String> hostParams,
+  protected OsSpecific populatePackagesInfo(Map<String, OsSpecific> 
osSpecificMap, Map<String, String> hostParams,
                                                         String osFamily) {
-    ServiceOsSpecific hostOs = new ServiceOsSpecific(osFamily);
-    List<ServiceOsSpecific> foundOSSpecifics = 
getOSSpecificsByFamily(serviceInfo.getOsSpecifics(), osFamily);
+    OsSpecific hostOs = new OsSpecific(osFamily);
+    List<OsSpecific> foundOSSpecifics = getOSSpecificsByFamily(osSpecificMap, 
osFamily);
     if (!foundOSSpecifics.isEmpty()) {
-      for (ServiceOsSpecific osSpecific : foundOSSpecifics) {
+      for (OsSpecific osSpecific : foundOSSpecifics) {
         hostOs.addPackages(osSpecific.getPackages());
       }
+
+      //TODO this looks deprecated. Need to investigate if it's actually used
       // Choose repo that is relevant for host
-      ServiceOsSpecific.Repo serviceRepo = hostOs.getRepo();
-      if (serviceRepo != null) {
-        String serviceRepoInfo = gson.toJson(serviceRepo);
+      OsSpecific.Repo repos = hostOs.getRepo();
+      if (repos != null) {
+        String serviceRepoInfo = gson.toJson(repos);
         hostParams.put(SERVICE_REPO_INFO, serviceRepoInfo);
       }
     }
     return hostOs;
   }
 
-  @Override
-  public List<ServiceOsSpecific.Package> getPackagesForServiceHost(ServiceInfo 
serviceInfo, Map<String, String> hostParams, String osFamily) {
-    // Write down os specific info for the service
-    ServiceOsSpecific anyOs = null;
+  public List<OsSpecific.Package> getPackagesForStackServiceHost(StackInfo 
stackInfo, ServiceInfo serviceInfo, Map<String, String> hostParams, String 
osFamily) {
+    List<OsSpecific.Package> packages = new ArrayList<>();
+    //add all packages for ANY_OS
+    if (stackInfo.getOsSpecifics().containsKey(AmbariMetaInfo.ANY_OS)) {
+      
packages.addAll(stackInfo.getOsSpecifics().get(AmbariMetaInfo.ANY_OS).getPackages());
+    }
+
     if (serviceInfo.getOsSpecifics().containsKey(AmbariMetaInfo.ANY_OS)) {
-      anyOs = serviceInfo.getOsSpecifics().get(AmbariMetaInfo.ANY_OS);
+      
packages.addAll(serviceInfo.getOsSpecifics().get(AmbariMetaInfo.ANY_OS).getPackages());
     }
 
-    ServiceOsSpecific hostOs = populateServicePackagesInfo(serviceInfo, 
hostParams, osFamily);
+    //Each call for populatePackagesInfo might set SERVICE_REPO_INFO in 
hostParams, we assume service might override
+    // those set on stack level. That's why we first call the stack level and 
then the service.
+    OsSpecific stackHostOs = populatePackagesInfo(stackInfo.getOsSpecifics(), 
hostParams, osFamily);
+    OsSpecific serviceHostOs = 
populatePackagesInfo(serviceInfo.getOsSpecifics(), hostParams, osFamily);
 
-    // Build package list that is relevant for host
-    List<ServiceOsSpecific.Package> packages =
-            new ArrayList<>();
-    if (anyOs != null) {
-      packages.addAll(anyOs.getPackages());
+    if (stackHostOs != null) {
+      packages.addAll(stackHostOs.getPackages());
     }
 
-    if (hostOs != null) {
-      packages.addAll(hostOs.getPackages());
+    if (serviceHostOs != null) {
+      packages.addAll(serviceHostOs.getPackages());
     }
 
     return packages;
   }
 
-  private List<ServiceOsSpecific> getOSSpecificsByFamily(Map<String, 
ServiceOsSpecific> osSpecifics, String osFamily) {
-    List<ServiceOsSpecific> foundOSSpecifics = new ArrayList<>();
-    for (Entry<String, ServiceOsSpecific> osSpecific : osSpecifics.entrySet()) 
{
+  private List<OsSpecific> getOSSpecificsByFamily(Map<String, OsSpecific> 
osSpecifics, String osFamily) {
+    List<OsSpecific> foundOSSpecifics = new ArrayList<>();
+    for (Entry<String, OsSpecific> osSpecific : osSpecifics.entrySet()) {
       String[] osFamilyNames = osSpecific.getKey().split("\\s*,\\s*");
 
       for(String osFamilyName:osFamilyNames) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
index 838aa23..af014b7 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
@@ -29,7 +29,6 @@ import static 
org.apache.ambari.server.agent.ExecutionCommand.KeyNames.MYSQL_JDB
 import static 
org.apache.ambari.server.agent.ExecutionCommand.KeyNames.NOT_MANAGED_HDFS_PATH_LIST;
 import static 
org.apache.ambari.server.agent.ExecutionCommand.KeyNames.ORACLE_JDBC_URL;
 import static 
org.apache.ambari.server.agent.ExecutionCommand.KeyNames.PACKAGE_LIST;
-import static 
org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
 import static 
org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_NAME;
 import static 
org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_VERSION;
 import static 
org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_GROUPS;
@@ -62,7 +61,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.MaintenanceStateHelper;
@@ -85,12 +83,13 @@ 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.OsSpecific;
 import org.apache.ambari.server.state.PropertyInfo.PropertyType;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
 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.utils.SecretReference;
 import org.apache.ambari.server.utils.StageUtils;
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
@@ -351,6 +350,7 @@ public class ClientConfigResourceProvider extends 
AbstractControllerResourceProv
         }
 
         Map<String, Set<String>> clusterHostInfo = 
StageUtils.getClusterHostInfo(cluster);
+        StackInfo stackInfo = 
managementController.getAmbariMetaInfo().getStack(stackId);
         ServiceInfo serviceInfo = 
managementController.getAmbariMetaInfo().getService(stackId.getStackName(),
           stackId.getStackVersion(), response.getServiceType());
         try {
@@ -379,24 +379,8 @@ public class ClientConfigResourceProvider extends 
AbstractControllerResourceProv
         hostLevelParams.put(AGENT_STACK_RETRY_COUNT, 
configs.getAgentStackRetryOnInstallCount());
         hostLevelParams.put(GPL_LICENSE_ACCEPTED, 
configs.getGplLicenseAccepted().toString());
 
-        // Write down os specific info for the service
-        ServiceOsSpecific anyOs = null;
-        if (serviceInfo.getOsSpecifics().containsKey(AmbariMetaInfo.ANY_OS)) {
-          anyOs = serviceInfo.getOsSpecifics().get(AmbariMetaInfo.ANY_OS);
-        }
-
-        ServiceOsSpecific hostOs = populateServicePackagesInfo(serviceInfo, 
hostLevelParams, osFamily);
-
-        // Build package list that is relevant for host
-        List<ServiceOsSpecific.Package> packages =
-          new ArrayList<>();
-        if (anyOs != null) {
-          packages.addAll(anyOs.getPackages());
-        }
-
-        if (hostOs != null) {
-          packages.addAll(hostOs.getPackages());
-        }
+        //may set SERVICE_REPO_INFO in hostLevelParams inside the method
+        List<OsSpecific.Package> packages = 
managementController.getPackagesForStackServiceHost(stackInfo, serviceInfo, 
hostLevelParams, osFamily);
         String packageList = gson.toJson(packages);
         hostLevelParams.put(PACKAGE_LIST, packageList);
 
@@ -921,35 +905,4 @@ public class ClientConfigResourceProvider extends 
AbstractControllerResourceProv
             (String) properties.get(HOST_COMPONENT_HOST_NAME_PROPERTY_ID),
             null);
   }
-
-
-  protected ServiceOsSpecific populateServicePackagesInfo(ServiceInfo 
serviceInfo, Map<String, String> hostParams,
-                                                          String osFamily) {
-    ServiceOsSpecific hostOs = new ServiceOsSpecific(osFamily);
-    List<ServiceOsSpecific> foundedOSSpecifics = 
getOSSpecificsByFamily(serviceInfo.getOsSpecifics(), osFamily);
-    if (!foundedOSSpecifics.isEmpty()) {
-      for (ServiceOsSpecific osSpecific : foundedOSSpecifics) {
-        hostOs.addPackages(osSpecific.getPackages());
-      }
-      // Choose repo that is relevant for host
-      ServiceOsSpecific.Repo serviceRepo = hostOs.getRepo();
-      if (serviceRepo != null) {
-        String serviceRepoInfo = gson.toJson(serviceRepo);
-        hostParams.put(SERVICE_REPO_INFO, serviceRepoInfo);
-      }
-    }
-
-    return hostOs;
-  }
-
-  private List<ServiceOsSpecific> getOSSpecificsByFamily(Map<String, 
ServiceOsSpecific> osSpecifics, String osFamily) {
-    List<ServiceOsSpecific> foundedOSSpecifics = new ArrayList<>();
-    for (Map.Entry<String, ServiceOsSpecific> osSpecific : 
osSpecifics.entrySet()) {
-      if (osSpecific.getKey().indexOf(osFamily) != -1) {
-        foundedOSSpecifics.add(osSpecific.getValue());
-      }
-    }
-    return foundedOSSpecifics;
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index 6b1acf3..8b70737 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -77,7 +77,6 @@ import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.RepositoryType;
 import org.apache.ambari.server.state.RepositoryVersionState;
 import org.apache.ambari.server.state.ServiceComponentHost;
-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.repository.AvailableService;
@@ -713,7 +712,6 @@ public class ClusterStackVersionResourceProvider extends 
AbstractControllerResou
     }
 
     // determine packages for all services that are installed on host
-    List<ServiceOsSpecific.Package> packages = new ArrayList<>();
     Set<String> servicesOnHost = new HashSet<>();
     List<ServiceComponentHost> components = 
cluster.getServiceComponentHosts(host.getHostName());
     for (ServiceComponentHost component : components) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
index 5b25aaa..975bf19 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/ModuleFileUnmarshaller.java
@@ -153,14 +153,14 @@ public class ModuleFileUnmarshaller {
   static {
     try {
       // three classes define the top-level element "metainfo", so we need 3 
contexts for them
-      JAXBContext ctx = JAXBContext.newInstance(StackMetainfoXml.class, 
RepositoryXml.class,
+      JAXBContext ctx = JAXBContext.newInstance(RepositoryXml.class,
           ConfigurationXml.class, UpgradePack.class, ConfigUpgradePack.class);
 
-      jaxbContexts.put(StackMetainfoXml.class, ctx);
       jaxbContexts.put(RepositoryXml.class, ctx);
       jaxbContexts.put(ConfigurationXml.class, ctx);
       jaxbContexts.put(UpgradePack.class, ctx);
       jaxbContexts.put(ConfigUpgradePack.class, ctx);
+      jaxbContexts.put(StackMetainfoXml.class, 
JAXBContext.newInstance(StackMetainfoXml.class));
       jaxbContexts.put(ServiceMetainfoXml.class, 
JAXBContext.newInstance(ServiceMetainfoXml.class));
       jaxbContexts.put(ExtensionMetainfoXml.class, 
JAXBContext.newInstance(ExtensionMetainfoXml.class));
     } catch (JAXBException e) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
index dc16ae2..b57715d 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
@@ -566,6 +566,7 @@ public class StackModule extends BaseModule<StackModule, 
StackInfo> implements V
       stackInfo.setMinJdk(smx.getMinJdk());
       stackInfo.setMaxJdk(smx.getMaxJdk());
       stackInfo.setMinUpgradeVersion(smx.getVersion().getUpgrade());
+      stackInfo.setOsSpecifics(smx.getOsSpecifics());
       stackInfo.setActive(smx.getVersion().isActive());
       stackInfo.setParentStackVersion(smx.getExtends());
       stackInfo.setRcoFileLocation(stackDirectory.getRcoFilePath());

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/state/OsSpecific.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/OsSpecific.java 
b/ambari-server/src/main/java/org/apache/ambari/server/state/OsSpecific.java
new file mode 100644
index 0000000..73300dd
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/OsSpecific.java
@@ -0,0 +1,250 @@
+/*
+ * 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.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlElements;
+
+import com.google.gson.annotations.SerializedName;
+/**
+ * Represents service os-specific details (like repositories and packages). 
+ * Represents <code>osSpecific</code>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public class OsSpecific {
+
+  private String osFamily;
+  private Repo repo;
+
+  public OsSpecific() {
+  }
+
+  public OsSpecific(String osFamily) {
+    this.osFamily = osFamily;
+  }
+
+  @XmlElementWrapper(name="packages")
+  @XmlElements(@XmlElement(name="package"))
+  private List<Package> packages = new ArrayList<>();
+
+
+  public String getOsFamily() {
+    return osFamily;
+  }
+
+
+  public Repo getRepo() {
+    return repo;
+  }
+
+
+  public List<Package> getPackages() {
+    return packages;
+  }
+
+  public void addPackages(List<Package> packages) {
+    this.packages.addAll(packages);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    OsSpecific that = (OsSpecific) o;
+
+    if (osFamily != null ? !osFamily.equals(that.osFamily) : that.osFamily != 
null) return false;
+    if (packages != null ? !packages.equals(that.packages) : that.packages != 
null) return false;
+    if (repo != null ? !repo.equals(that.repo) : that.repo != null) return 
false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = osFamily != null ? osFamily.hashCode() : 0;
+    result = 31 * result + (repo != null ? repo.hashCode() : 0);
+    result = 31 * result + (packages != null ? packages.hashCode() : 0);
+    return result;
+  }
+
+  /**
+   * The <code>repo</code> tag. It has different set of fields compared to
+   * <link>org.apache.ambari.server.state.RepositoryInfo</link>,
+   * that's why we need another class
+   */
+  //TODO this looks deprecated. Need to investigate if it's actually used
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class Repo {
+
+    @SerializedName("baseUrl")
+    private String baseurl;
+    @SerializedName("mirrorsList")
+    private String mirrorslist;
+    @SerializedName("repoId")
+    private String repoid;
+    @SerializedName("repoName")
+    private String reponame;
+    @SerializedName("distribution")
+    private String distribution;
+    @SerializedName("components")
+    private String components;
+
+    private Repo() {
+    }
+    
+    /**
+     * @return the base url
+     */
+    public String getBaseUrl() {
+      return (null == baseurl || baseurl.isEmpty()) ? null : baseurl;
+    }
+
+    /**
+     * @return the mirrorlist field
+     */
+    public String getMirrorsList() {
+      return (null == mirrorslist || mirrorslist.isEmpty()) ? null : 
mirrorslist;
+    }
+    
+    /**
+     * @return the repo id
+     */
+    public String getRepoId() {
+      return repoid;
+    }
+    
+    /**
+     * @return the repo name
+     */
+    public String getRepoName() {
+      return reponame;
+    }
+
+    public String getDistribution() {
+      return distribution;
+    }
+
+    public String getComponents() {
+      return components;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      Repo repo = (Repo) o;
+
+      if (baseurl != null ? !baseurl.equals(repo.baseurl) : repo.baseurl != 
null) return false;
+      if (mirrorslist != null ? !mirrorslist.equals(repo.mirrorslist) : 
repo.mirrorslist != null) return false;
+      if (repoid != null ? !repoid.equals(repo.repoid) : repo.repoid != null) 
return false;
+      if (reponame != null ? !reponame.equals(repo.reponame) : repo.reponame 
!= null) return false;
+      if (distribution != null ? !distribution.equals(repo.distribution) : 
repo.distribution != null) return false;
+      if (components != null ? !components.equals(repo.components) : 
repo.components != null) return false;
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int result = baseurl != null ? baseurl.hashCode() : 0;
+      result = 31 * result + (mirrorslist != null ? mirrorslist.hashCode() : 
0);
+      result = 31 * result + (repoid != null ? repoid.hashCode() : 0);
+      result = 31 * result + (reponame != null ? reponame.hashCode() : 0);
+      result = 31 * result + (distribution != null ? distribution.hashCode() : 
0);
+      result = 31 * result + (components != null ? components.hashCode() : 0);
+      return result;
+    }
+  }
+
+
+
+  /**
+   * The <code>package</code> tag.
+   */
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class Package {
+    private String name;
+    private String condition = "";
+
+    /**
+     * If true, package will not be attempted to be upgraded during RU.
+     * Typically, packages that are located outside of HDP* repositories,
+     * should be marked as true
+     */
+    private Boolean skipUpgrade = Boolean.FALSE;
+
+    public String getName() {
+      return name;
+    }
+
+    public void setName(String name) {
+      this.name = name;
+    }
+    
+    public String getCondition() {
+      return condition;
+    }
+
+    public void setCondition(String condition) {
+      this.condition = condition;
+    }
+
+    public Boolean getSkipUpgrade() {
+      return skipUpgrade;
+    }
+
+    public void setSkipUpgrade(Boolean skipUpgrade) {
+      this.skipUpgrade = skipUpgrade;
+    }
+
+    public Package() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      Package aPackage = (Package) o;
+
+      if (!name.equals(aPackage.name)) return false;
+      if (!skipUpgrade.equals(aPackage.skipUpgrade)) return false;
+      if (!condition.equals(aPackage.condition)) return false;
+      
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int result = name.hashCode();
+      result = 31 * result + skipUpgrade.hashCode();
+      result = 31 * result + condition.hashCode();
+      
+      return result;
+    }
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
index 8385c9f..618a9a5 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
@@ -231,7 +231,7 @@ public class ServiceInfo implements Validable, Cloneable {
   @JsonIgnore
   @XmlElementWrapper(name="osSpecifics")
   @XmlElements(@XmlElement(name="osSpecific"))
-  private List<ServiceOsSpecific> serviceOsSpecifics;
+  private List<OsSpecific> serviceOsSpecifics;
 
   @JsonIgnore
   @XmlElement(name="configuration-dir")
@@ -267,7 +267,7 @@ public class ServiceInfo implements Validable, Cloneable {
    * Added at schema ver 2
    */
   @XmlTransient
-  private volatile Map<String, ServiceOsSpecific> serviceOsSpecificsMap;
+  private volatile Map<String, OsSpecific> serviceOsSpecificsMap;
 
   /**
    * This is used to add service check actions for services.
@@ -851,14 +851,14 @@ public class ServiceInfo implements Validable, Cloneable {
    * Exposes (and initializes on first use) map of os-specific details.
    * @return  map of OS specific details keyed by family
    */
-  public Map<String, ServiceOsSpecific> getOsSpecifics() {
+  public Map<String, OsSpecific> getOsSpecifics() {
     if (serviceOsSpecificsMap == null) {
       synchronized (this) { // Double-checked locking pattern
         if (serviceOsSpecificsMap == null) {
-          Map<String, ServiceOsSpecific> tmpMap =
+          Map<String, OsSpecific> tmpMap =
             new TreeMap<>();
           if (serviceOsSpecifics != null) {
-            for (ServiceOsSpecific osSpecific : serviceOsSpecifics) {
+            for (OsSpecific osSpecific : serviceOsSpecifics) {
               tmpMap.put(osSpecific.getOsFamily(), osSpecific);
             }
           }
@@ -869,7 +869,7 @@ public class ServiceInfo implements Validable, Cloneable {
     return serviceOsSpecificsMap;
   }
 
-  public void setOsSpecifics(Map<String, ServiceOsSpecific> 
serviceOsSpecificsMap) {
+  public void setOsSpecifics(Map<String, OsSpecific> serviceOsSpecificsMap) {
     this.serviceOsSpecificsMap = serviceOsSpecificsMap;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceOsSpecific.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceOsSpecific.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceOsSpecific.java
deleted file mode 100644
index f692eb5..0000000
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceOsSpecific.java
+++ /dev/null
@@ -1,249 +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 java.util.ArrayList;
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlElements;
-
-import com.google.gson.annotations.SerializedName;
-/**
- * Represents service os-specific details (like repositories and packages). 
- * Represents <code>osSpecific</code>
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-public class ServiceOsSpecific {
-
-  private String osFamily;
-  private Repo repo;
-
-  public ServiceOsSpecific() {
-  }
-
-  public ServiceOsSpecific(String osFamily) {
-    this.osFamily = osFamily;
-  }
-
-  @XmlElementWrapper(name="packages")
-  @XmlElements(@XmlElement(name="package"))
-  private List<Package> packages = new ArrayList<>();
-
-
-  public String getOsFamily() {
-    return osFamily;
-  }
-
-
-  public Repo getRepo() {
-    return repo;
-  }
-
-
-  public List<Package> getPackages() {
-    return packages;
-  }
-
-  public void addPackages(List<Package> packages) {
-    this.packages.addAll(packages);
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    ServiceOsSpecific that = (ServiceOsSpecific) o;
-
-    if (osFamily != null ? !osFamily.equals(that.osFamily) : that.osFamily != 
null) return false;
-    if (packages != null ? !packages.equals(that.packages) : that.packages != 
null) return false;
-    if (repo != null ? !repo.equals(that.repo) : that.repo != null) return 
false;
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    int result = osFamily != null ? osFamily.hashCode() : 0;
-    result = 31 * result + (repo != null ? repo.hashCode() : 0);
-    result = 31 * result + (packages != null ? packages.hashCode() : 0);
-    return result;
-  }
-
-  /**
-   * The <code>repo</code> tag. It has different set of fields compared to
-   * <link>org.apache.ambari.server.state.RepositoryInfo</link>,
-   * that's why we need another class
-   */
-  @XmlAccessorType(XmlAccessType.FIELD)
-  public static class Repo {
-
-    @SerializedName("baseUrl")
-    private String baseurl;
-    @SerializedName("mirrorsList")
-    private String mirrorslist;
-    @SerializedName("repoId")
-    private String repoid;
-    @SerializedName("repoName")
-    private String reponame;
-    @SerializedName("distribution")
-    private String distribution;
-    @SerializedName("components")
-    private String components;
-
-    private Repo() {
-    }
-    
-    /**
-     * @return the base url
-     */
-    public String getBaseUrl() {
-      return (null == baseurl || baseurl.isEmpty()) ? null : baseurl;
-    }
-
-    /**
-     * @return the mirrorlist field
-     */
-    public String getMirrorsList() {
-      return (null == mirrorslist || mirrorslist.isEmpty()) ? null : 
mirrorslist;
-    }
-    
-    /**
-     * @return the repo id
-     */
-    public String getRepoId() {
-      return repoid;
-    }
-    
-    /**
-     * @return the repo name
-     */
-    public String getRepoName() {
-      return reponame;
-    }
-
-    public String getDistribution() {
-      return distribution;
-    }
-
-    public String getComponents() {
-      return components;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (this == o) return true;
-      if (o == null || getClass() != o.getClass()) return false;
-
-      Repo repo = (Repo) o;
-
-      if (baseurl != null ? !baseurl.equals(repo.baseurl) : repo.baseurl != 
null) return false;
-      if (mirrorslist != null ? !mirrorslist.equals(repo.mirrorslist) : 
repo.mirrorslist != null) return false;
-      if (repoid != null ? !repoid.equals(repo.repoid) : repo.repoid != null) 
return false;
-      if (reponame != null ? !reponame.equals(repo.reponame) : repo.reponame 
!= null) return false;
-      if (distribution != null ? !distribution.equals(repo.distribution) : 
repo.distribution != null) return false;
-      if (components != null ? !components.equals(repo.components) : 
repo.components != null) return false;
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      int result = baseurl != null ? baseurl.hashCode() : 0;
-      result = 31 * result + (mirrorslist != null ? mirrorslist.hashCode() : 
0);
-      result = 31 * result + (repoid != null ? repoid.hashCode() : 0);
-      result = 31 * result + (reponame != null ? reponame.hashCode() : 0);
-      result = 31 * result + (distribution != null ? distribution.hashCode() : 
0);
-      result = 31 * result + (components != null ? components.hashCode() : 0);
-      return result;
-    }
-  }
-
-
-
-  /**
-   * The <code>package</code> tag.
-   */
-  @XmlAccessorType(XmlAccessType.FIELD)
-  public static class Package {
-    private String name;
-    private String condition = "";
-
-    /**
-     * If true, package will not be attempted to be upgraded during RU.
-     * Typically, packages that are located outside of HDP* repositories,
-     * should be marked as true
-     */
-    private Boolean skipUpgrade = Boolean.FALSE;
-
-    public String getName() {
-      return name;
-    }
-
-    public void setName(String name) {
-      this.name = name;
-    }
-    
-    public String getCondition() {
-      return condition;
-    }
-
-    public void setCondition(String condition) {
-      this.condition = condition;
-    }
-
-    public Boolean getSkipUpgrade() {
-      return skipUpgrade;
-    }
-
-    public void setSkipUpgrade(Boolean skipUpgrade) {
-      this.skipUpgrade = skipUpgrade;
-    }
-
-    public Package() {
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (this == o) return true;
-      if (o == null || getClass() != o.getClass()) return false;
-
-      Package aPackage = (Package) o;
-
-      if (!name.equals(aPackage.name)) return false;
-      if (!skipUpgrade.equals(aPackage.skipUpgrade)) return false;
-      if (!condition.equals(aPackage.condition)) return false;
-      
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      int result = name.hashCode();
-      result = 31 * result + skipUpgrade.hashCode();
-      result = 31 * result + condition.hashCode();
-      
-      return result;
-    }
-  }
-}
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java 
b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
index df0d2dc..9db7fd6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
@@ -97,6 +97,25 @@ public class StackInfo implements Comparable<StackInfo>, 
Validable {
 
   private RefreshCommandConfiguration refreshCommandConfiguration = new 
RefreshCommandConfiguration();
 
+  /**
+   * Map of of os-specific details that is exposed (and initialised from list)
+   * at getter.
+   * Added at schema ver 2
+   */
+  private volatile Map<String, OsSpecific> stackOsSpecificsMap;
+
+  /**
+   * Exposes  map of os-specific details.
+   * @return  map of OS specific details keyed by family
+   */
+  public Map<String, OsSpecific> getOsSpecifics() {
+    return stackOsSpecificsMap;
+  }
+
+  public void setOsSpecifics(Map<String, OsSpecific> serviceOsSpecificsMap) {
+    this.stackOsSpecificsMap = serviceOsSpecificsMap;
+  }
+
   public String getMinJdk() {
     return minJdk;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/StackMetainfoXml.java
----------------------------------------------------------------------
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 82096eb..7f56b50 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
@@ -19,15 +19,21 @@ package org.apache.ambari.server.state.stack;
 
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlElements;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 
 import org.apache.ambari.server.stack.Validable;
+import org.apache.ambari.server.state.OsSpecific;
 
 /**
  * Represents the stack <code>metainfo.xml</code> file.
@@ -124,7 +130,43 @@ public class StackMetainfoXml implements Validable{
   public void setVersion(Version version) {
     this.version = version;
   }
-  
+
+  /**
+   * Internal list of os-specific details (loaded from xml). Added at schema 
ver 2
+   */
+  @XmlElementWrapper(name="osSpecifics")
+  @XmlElements(@XmlElement(name="osSpecific"))
+  private List<OsSpecific> osSpecifics;
+
+  /**
+   * Map of of os-specific details that is exposed (and initialised from list)
+   * at getter.
+   * Added at schema ver 2
+   */
+  @XmlTransient
+  private volatile Map<String, OsSpecific> stackOsSpecificsMap;
+
+  public Map<String,OsSpecific> getOsSpecifics() {
+    if (stackOsSpecificsMap == null) {
+      synchronized (this) { // Double-checked locking pattern
+        if (stackOsSpecificsMap == null) {
+          Map<String, OsSpecific> tmpMap =
+              new TreeMap<>();
+          if (osSpecifics != null) {
+            for (OsSpecific osSpecific : osSpecifics) {
+              tmpMap.put(osSpecific.getOsFamily(), osSpecific);
+            }
+          }
+          stackOsSpecificsMap = tmpMap;
+        }
+      }
+    }
+    return stackOsSpecificsMap;
+  }
+  public void setOsSpecifics(Map<String, OsSpecific> stackOsSpecificsMap) {
+    this.stackOsSpecificsMap = stackOsSpecificsMap;
+  }
+
   @XmlAccessorType(XmlAccessType.FIELD)
   public static class Version {
     public Version() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
index 39e5d5c..fa41d72 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
@@ -45,13 +45,14 @@ import 
org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.OsSpecific;
 import org.apache.ambari.server.state.RepositoryInfo;
 import org.apache.ambari.server.state.RepositoryType;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
 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.repository.ClusterVersionSummary;
 import org.apache.ambari.server.state.repository.VersionDefinitionXml;
 import org.apache.ambari.server.state.stack.OsFamily;
@@ -334,10 +335,11 @@ public class RepositoryVersionHelper {
 
     StackId stackId = repoVersion.getStackId();
 
-    List<ServiceOsSpecific.Package> packages = new ArrayList<>();
+    List<OsSpecific.Package> packages = new ArrayList<>();
 
     for (String serviceName : servicesOnHost) {
-      ServiceInfo info;
+      ServiceInfo serviceInfo;
+      StackInfo stackInfo;
 
       try {
         if (ami.get().isServiceRemovedInStack(stackId.getStackName(), 
stackId.getStackVersion(), serviceName)) {
@@ -345,17 +347,17 @@ public class RepositoryVersionHelper {
           continue; //No need to calculate install packages for removed 
services
         }
 
-        info = ami.get().getService(stackId.getStackName(), 
stackId.getStackVersion(), serviceName);
+        stackInfo = ami.get().getStack(stackId);
+        serviceInfo = ami.get().getService(stackId.getStackName(), 
stackId.getStackVersion(), serviceName);
       } catch (AmbariException e) {
         throw new SystemException(String.format("Cannot obtain stack 
information for %s-%s", stackId.getStackName(), stackId.getStackVersion()), e);
       }
 
-      List<ServiceOsSpecific.Package> packagesForService = 
amc.getPackagesForServiceHost(info,
+      List<OsSpecific.Package> packagesForStackService = 
amc.getPackagesForStackServiceHost(stackInfo, serviceInfo,
         new HashMap<>(), osFamily);
 
       List<String> blacklistedPackagePrefixes = 
configuration.get().getRollingUpgradeSkipPackagesPrefixes();
-
-      for (ServiceOsSpecific.Package aPackage : packagesForService) {
+      for (OsSpecific.Package aPackage : packagesForStackService) {
         if (!aPackage.getSkipUpgrade()) {
           boolean blacklisted = false;
           for (String prefix : blacklistedPackagePrefixes) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
----------------------------------------------------------------------
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 db5df10..14ab8cf 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
@@ -97,6 +97,7 @@ 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.Mpack;
+import org.apache.ambari.server.state.OsSpecific;
 import org.apache.ambari.server.state.Packlet;
 import org.apache.ambari.server.state.PropertyInfo;
 import org.apache.ambari.server.state.RepositoryInfo;
@@ -105,7 +106,6 @@ 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;
@@ -2003,39 +2003,49 @@ public class AmbariManagementControllerImplTest {
   }
 
   @Test
-  public void testPopulateServicePackagesInfo() throws Exception {
+  public void testPopulatePackagesInfo() throws Exception {
     Capture<AmbariManagementController> controllerCapture = 
EasyMock.newCapture();
     Injector injector = createStrictMock(Injector.class);
     MaintenanceStateHelper maintHelper = 
createNiceMock(MaintenanceStateHelper.class);
 
     ServiceInfo serviceInfo = createNiceMock(ServiceInfo.class);
+    StackInfo stackInfo = createNiceMock(StackInfo.class);
     Map<String, String> hostParams = new HashMap<>();
     String osFamily = "testOSFamily";
 
-    Map<String, ServiceOsSpecific> osSpecifics = new HashMap<>();
+    Map<String, OsSpecific> osSpecificsService = new HashMap<>();
+    Map<String, OsSpecific> osSpecificsStack = new HashMap<>();
 
-    ServiceOsSpecific.Package package1 = new ServiceOsSpecific.Package();
+    OsSpecific.Package package1 = new OsSpecific.Package();
     package1.setName("testrpm1");
-    ServiceOsSpecific.Package package2 = new ServiceOsSpecific.Package();
+    OsSpecific.Package package2 = new OsSpecific.Package();
     package2.setName("testrpm2");
-    ServiceOsSpecific.Package package3 = new ServiceOsSpecific.Package();
+    OsSpecific.Package package3 = new OsSpecific.Package();
     package3.setName("testrpm3");
+    OsSpecific.Package packageStack = new OsSpecific.Package();
+    package3.setName("testrpmStack");
 
-    List<ServiceOsSpecific.Package> packageList1 = new ArrayList<>();
+    List<OsSpecific.Package> packageList1 = new ArrayList<>();
     packageList1.add(package1);
-    List<ServiceOsSpecific.Package> packageList2 = new ArrayList<>();
+    List<OsSpecific.Package> packageList2 = new ArrayList<>();
     packageList2.add(package2);
     packageList2.add(package3);
+    List<OsSpecific.Package> packageListStack = new ArrayList<>();
+    packageListStack.add(packageStack);
 
-    ServiceOsSpecific osSpecific1 = new ServiceOsSpecific("testOSFamily");
+    OsSpecific osSpecific1 = new OsSpecific("testOSFamily");
     osSpecific1.addPackages(packageList1);
-    ServiceOsSpecific osSpecific2 = new 
ServiceOsSpecific("testOSFamily1,testOSFamily,testOSFamily2");
+    OsSpecific osSpecific2 = new 
OsSpecific("testOSFamily1,testOSFamily,testOSFamily2");
     osSpecific2.addPackages(packageList2);
+    OsSpecific osSpecificStack = new OsSpecific("testOSFamily");
+    osSpecificStack.addPackages(packageListStack);
 
-    osSpecifics.put("testOSFamily", osSpecific1);
-    osSpecifics.put("testOSFamily1,testOSFamily,testOSFamily2", osSpecific2);
+    osSpecificsService.put("testOSFamily", osSpecific1);
+    osSpecificsService.put("testOSFamily1,testOSFamily,testOSFamily2", 
osSpecific2);
+    osSpecificsStack.put("testOSFamily", osSpecificStack);
 
-    expect(serviceInfo.getOsSpecifics()).andReturn(osSpecifics);
+    expect(serviceInfo.getOsSpecifics()).andReturn(osSpecificsService);
+    expect(stackInfo.getOsSpecifics()).andReturn(osSpecificsStack);
     injector.injectMembers(capture(controllerCapture));
     expect(injector.getInstance(Gson.class)).andReturn(null);
     
expect(injector.getInstance(MaintenanceStateHelper.class)).andReturn(maintHelper).anyTimes();
@@ -2044,14 +2054,18 @@ public class AmbariManagementControllerImplTest {
     OsFamily osFamilyMock = createNiceMock(OsFamily.class);
 
     
EasyMock.expect(osFamilyMock.isVersionedOsFamilyExtendedByVersionedFamily("testOSFamily",
 "testOSFamily")).andReturn(true).times(3);
-    replay(maintHelper, injector, clusters, serviceInfo, osFamilyMock);
+    replay(maintHelper, injector, clusters, stackInfo, serviceInfo, 
osFamilyMock);
 
     AmbariManagementControllerImplTest.NestedTestClass nestedTestClass = 
this.new NestedTestClass(null, clusters,
         injector, osFamilyMock);
 
-    ServiceOsSpecific serviceOsSpecific = 
nestedTestClass.populateServicePackagesInfo(serviceInfo, hostParams, osFamily);
+    OsSpecific osSpecific = 
nestedTestClass.populatePackagesInfo(stackInfo.getOsSpecifics(), hostParams, 
osFamily);
+
+    assertEquals(1, osSpecific.getPackages().size());
+
+    osSpecific = 
nestedTestClass.populatePackagesInfo(serviceInfo.getOsSpecifics(), hostParams, 
osFamily);
 
-    assertEquals(3, serviceOsSpecific.getPackages().size());
+    assertEquals(3, osSpecific.getPackages().size());
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index e584322..0cc64e9 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -128,6 +128,7 @@ import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.HostComponentAdminState;
 import org.apache.ambari.server.state.HostState;
 import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.OsSpecific;
 import org.apache.ambari.server.state.RepositoryInfo;
 import org.apache.ambari.server.state.SecurityType;
 import org.apache.ambari.server.state.Service;
@@ -138,7 +139,6 @@ import 
org.apache.ambari.server.state.ServiceComponentHostFactory;
 import org.apache.ambari.server.state.ServiceFactory;
 import org.apache.ambari.server.state.ServiceGroup;
 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;
@@ -10331,32 +10331,35 @@ public class AmbariManagementControllerTest {
   }
 
   @Test
-  public void testGetPackagesForServiceHost() throws Exception {
-    ServiceInfo service = ambariMetaInfo.getStack("HDP", 
"2.0.1").getService("HIVE");
+  public void testGetPackagesForStackServiceHost() throws Exception {
+    StackInfo stack = ambariMetaInfo.getStack("HDP", "2.0.1");
+    ServiceInfo service = stack.getService("HIVE");
     HashMap<String, String> hostParams = new HashMap<>();
 
-    Map<String, ServiceOsSpecific.Package> packages = new HashMap<>();
-    String [] packageNames = {"hive", "mysql-connector-java", "mysql", 
"mysql-server", "mysql-client"};
+    Map<String, OsSpecific.Package> packages = new HashMap<>();
+    String [] packageNames = {"stack_any_package", "hive", 
"mysql-connector-java", "mysql", "mysql-server", "mysql-client"};
     for (String packageName : packageNames) {
-      ServiceOsSpecific.Package pkg = new ServiceOsSpecific.Package();
+      OsSpecific.Package pkg = new OsSpecific.Package();
       pkg.setName(packageName);
       packages.put(packageName, pkg);
     }
 
-    List<ServiceOsSpecific.Package> rhel5Packages = 
controller.getPackagesForServiceHost(service, hostParams, "redhat5");
-    List<ServiceOsSpecific.Package> expectedRhel5 = Arrays.asList(
+    List<OsSpecific.Package> rhel5Packages = 
controller.getPackagesForStackServiceHost(stack, service, hostParams, 
"redhat5");
+    List<OsSpecific.Package> expectedRhel5 = Arrays.asList(
+            packages.get("stack_any_package"),
             packages.get("hive"),
             packages.get("mysql-connector-java"),
             packages.get("mysql"),
             packages.get("mysql-server")
     );
 
-    List<ServiceOsSpecific.Package> sles11Packages = 
controller.getPackagesForServiceHost(service, hostParams, "suse11");
-    List<ServiceOsSpecific.Package> expectedSles11 = Arrays.asList(
+    List<OsSpecific.Package> sles11Packages = 
controller.getPackagesForStackServiceHost(stack, service, hostParams, "suse11");
+    List<OsSpecific.Package> expectedSles11 = Arrays.asList(
+            packages.get("stack_any_package"),
             packages.get("hive"),
             packages.get("mysql-connector-java"),
-            packages.get("mysql"),
-            packages.get("mysql-client")
+            packages.get("mysql-client"),
+            packages.get("mysql")
     );
     assertThat(rhel5Packages, is(expectedRhel5));
     assertThat(sles11Packages, is(expectedSles11));

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java
index e9f57b1..1cd553c 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java
@@ -65,13 +65,14 @@ 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.OsSpecific;
 import org.apache.ambari.server.state.PropertyInfo;
 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.UserGroupInfo;
 import org.apache.ambari.server.state.ValueAttributesInfo;
 import org.apache.ambari.server.utils.StageUtils;
@@ -179,6 +180,7 @@ public class ClientConfigResourceProviderTest {
     AmbariMetaInfo ambariMetaInfo = createNiceMock(AmbariMetaInfo.class);
     StackId stackId = createNiceMock(StackId.class);
     ComponentInfo componentInfo = createNiceMock(ComponentInfo.class);
+    StackInfo stackInfo = createNiceMock(StackInfo.class);
     ServiceInfo serviceInfo = createNiceMock(ServiceInfo.class);
     CommandScriptDefinition commandScriptDefinition = 
createNiceMock(CommandScriptDefinition.class);
     Config clusterConfig = createNiceMock(Config.class);
@@ -187,7 +189,7 @@ public class ClientConfigResourceProviderTest {
     Service service = createNiceMock(Service.class);
     ServiceComponent serviceComponent = createNiceMock(ServiceComponent.class);
     ServiceComponentHost serviceComponentHost = 
createNiceMock(ServiceComponentHost.class);
-    ServiceOsSpecific serviceOsSpecific = 
createNiceMock(ServiceOsSpecific.class);
+    OsSpecific osSpecific = createNiceMock(OsSpecific.class);
     ConfigHelper configHelper = createNiceMock(ConfigHelper.class);
     Configuration configuration = 
PowerMock.createStrictMockAndExpectNew(Configuration.class);
     Map<String, String> configMap = createNiceMock(Map.class);
@@ -245,8 +247,8 @@ public class ClientConfigResourceProviderTest {
     serviceComponentMap.put(componentName,serviceComponent);
     HashMap<String, ServiceComponentHost> serviceComponentHosts = new 
HashMap<>();
     serviceComponentHosts.put(componentName, serviceComponentHost);
-    HashMap<String, ServiceOsSpecific> serviceOsSpecificHashMap = new 
HashMap<>();
-    serviceOsSpecificHashMap.put("key",serviceOsSpecific);
+    HashMap<String, OsSpecific> serviceOsSpecificHashMap = new HashMap<>();
+    serviceOsSpecificHashMap.put("key", osSpecific);
 
     ServiceComponentHostResponse shr1 = new ServiceComponentHostResponse(1L, 
clusterName, 1L, "CORE", 1L, serviceName, serviceName, 1L,
         componentName, displayName, hostName, publicHostname, desiredState, 
"", null, null, null,
@@ -330,8 +332,7 @@ public class ClientConfigResourceProviderTest {
     HashMap<String, String> rcaParams = new HashMap<>();
     rcaParams.put("key","value");
     
expect(managementController.getRcaParameters()).andReturn(rcaParams).anyTimes();
-    expect(ambariMetaInfo.getService(stackName, stackVersion, 
serviceName)).andReturn(serviceInfo);
-    expect(serviceInfo.getOsSpecifics()).andReturn(new HashMap<>()).anyTimes();
+    expect(stackInfo.getOsSpecifics()).andReturn(new HashMap<>()).anyTimes();
     Set<String> userSet = new HashSet<>();
     userSet.add("hdfs");
     expect(configHelper.getPropertyValuesWithPropertyType(
@@ -403,7 +404,7 @@ public class ClientConfigResourceProviderTest {
 
     // replay
     replay(managementController, clusters, cluster, ambariMetaInfo, stackId, 
componentInfo, commandScriptDefinition,
-            clusterConfig, host, service, serviceComponent, 
serviceComponentHost, serviceInfo, configHelper,
+            clusterConfig, host, service, serviceComponent, 
serviceComponentHost, serviceInfo, stackInfo, configHelper,
             runtime, process, configMap);
     PowerMock.replayAll();
 
@@ -413,7 +414,7 @@ public class ClientConfigResourceProviderTest {
 
     // verify
     verify(managementController, clusters, cluster, ambariMetaInfo, stackId, 
componentInfo,commandScriptDefinition,
-            clusterConfig, host, service, serviceComponent, 
serviceComponentHost, serviceInfo, configHelper,
+            clusterConfig, host, service, serviceComponent, 
serviceComponentHost, serviceInfo, stackInfo, configHelper,
             runtime, process);
     PowerMock.verifyAll();
   }
@@ -429,6 +430,7 @@ public class ClientConfigResourceProviderTest {
     AmbariMetaInfo ambariMetaInfo = createNiceMock(AmbariMetaInfo.class);
     StackId stackId = createNiceMock(StackId.class);
     ComponentInfo componentInfo = createNiceMock(ComponentInfo.class);
+    StackInfo stackInfo = createNiceMock(StackInfo.class);
     ServiceInfo serviceInfo = createNiceMock(ServiceInfo.class);
     CommandScriptDefinition commandScriptDefinition = 
createNiceMock(CommandScriptDefinition.class);
     Config clusterConfig = createNiceMock(Config.class);
@@ -437,7 +439,7 @@ public class ClientConfigResourceProviderTest {
     Service service = createNiceMock(Service.class);
     ServiceComponent serviceComponent = createNiceMock(ServiceComponent.class);
     ServiceComponentHost serviceComponentHost = 
createNiceMock(ServiceComponentHost.class);
-    ServiceOsSpecific serviceOsSpecific = 
createNiceMock(ServiceOsSpecific.class);
+    OsSpecific osSpecific = createNiceMock(OsSpecific.class);
     ConfigHelper configHelper = createNiceMock(ConfigHelper.class);
     Configuration configuration = 
PowerMock.createStrictMockAndExpectNew(Configuration.class);
     Map<String, String> configMap = createNiceMock(Map.class);
@@ -504,8 +506,8 @@ public class ClientConfigResourceProviderTest {
     serviceComponentMap.put(componentName,serviceComponent);
     HashMap<String, ServiceComponentHost> serviceComponentHosts = new 
HashMap<>();
     serviceComponentHosts.put(componentName, serviceComponentHost);
-    HashMap<String, ServiceOsSpecific> serviceOsSpecificHashMap = new 
HashMap<>();
-    serviceOsSpecificHashMap.put("key",serviceOsSpecific);
+    HashMap<String, OsSpecific> serviceOsSpecificHashMap = new HashMap<>();
+    serviceOsSpecificHashMap.put("key", osSpecific);
 
     ServiceComponentHostResponse shr1 = new ServiceComponentHostResponse(1L, 
clusterName, 1L, "CORE", 1L, serviceName, serviceName, 1L,
         componentName, displayName, hostName, publicHostName, desiredState, 
"", null, null, null,
@@ -590,8 +592,8 @@ public class ClientConfigResourceProviderTest {
     HashMap<String, String> rcaParams = new HashMap<>();
     rcaParams.put("key","value");
     
expect(managementController.getRcaParameters()).andReturn(rcaParams).anyTimes();
-    expect(ambariMetaInfo.getService(stackName, stackVersion, 
serviceName)).andReturn(serviceInfo);
     expect(serviceInfo.getOsSpecifics()).andReturn(new HashMap<>()).anyTimes();
+    expect(stackInfo.getOsSpecifics()).andReturn(new HashMap<>()).anyTimes();
     Set<String> userSet = new HashSet<>();
     userSet.add("hdfs");
     expect(configHelper.getPropertyValuesWithPropertyType(stackId, 
PropertyInfo.PropertyType.USER, cluster, desiredConfigMap)).andReturn(userSet);
@@ -620,7 +622,7 @@ public class ClientConfigResourceProviderTest {
 
     // replay
     replay(managementController, clusters, cluster, ambariMetaInfo, stackId, 
componentInfo, commandScriptDefinition,
-            clusterConfig, host, service, serviceComponent, 
serviceComponentHost, serviceInfo, configHelper,
+            clusterConfig, host, service, serviceComponent, 
serviceComponentHost, serviceInfo, stackInfo, configHelper,
             runtime, process, configMap);
     PowerMock.replayAll();
 
@@ -629,7 +631,7 @@ public class ClientConfigResourceProviderTest {
 
     // verify
     verify(managementController, clusters, cluster, ambariMetaInfo, stackId, 
componentInfo,commandScriptDefinition,
-            clusterConfig, host, service, serviceComponent, 
serviceComponentHost, serviceInfo, configHelper,
+            clusterConfig, host, service, serviceComponent, 
serviceComponentHost, serviceInfo, stackInfo, configHelper,
             runtime, process);
     PowerMock.verifyAll();
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/0b1ce86b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
index c6ea264..56f16fc 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
@@ -88,13 +88,13 @@ import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.Host;
 import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.OsSpecific;
 import org.apache.ambari.server.state.RepositoryType;
 import org.apache.ambari.server.state.RepositoryVersionState;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceComponentHost;
 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.cluster.ClusterImpl;
@@ -256,23 +256,23 @@ public class ClusterStackVersionResourceProviderTest {
     final ServiceComponentHost schDatanode = 
createMock(ServiceComponentHost.class);
     expect(schDatanode.getServiceName()).andReturn("HDFS").anyTimes();
     
expect(schDatanode.getServiceComponentName()).andReturn("DATANODE").anyTimes();
-    expect(schDatanode.getServiceType()).andReturn("DATANODE").anyTimes();
+    expect(schDatanode.getServiceType()).andReturn("HDFS").anyTimes();
     final ServiceComponentHost schNamenode = 
createMock(ServiceComponentHost.class);
     expect(schNamenode.getServiceName()).andReturn("HDFS").anyTimes();
     
expect(schNamenode.getServiceComponentName()).andReturn("NAMENODE").anyTimes();
-    expect(schNamenode.getServiceType()).andReturn("NAMENODE").anyTimes();
+    expect(schNamenode.getServiceType()).andReturn("HDFS").anyTimes();
     final ServiceComponentHost schAMS = createMock(ServiceComponentHost.class);
     expect(schAMS.getServiceName()).andReturn("AMBARI_METRICS").anyTimes();
     
expect(schAMS.getServiceComponentName()).andReturn("METRICS_COLLECTOR").anyTimes();
-    expect(schAMS.getServiceType()).andReturn("METRICS_COLLECTOR").anyTimes();
+    expect(schAMS.getServiceType()).andReturn("AMBARI_METRICS").anyTimes();
     // First host contains versionable components
     final List<ServiceComponentHost> schsH1 = Lists.newArrayList(schDatanode, 
schNamenode, schAMS);
     // Second host does not contain versionable components
     final List<ServiceComponentHost> schsH2 = Lists.newArrayList(schAMS);
 
-    ServiceOsSpecific.Package hdfsPackage = new ServiceOsSpecific.Package();
+    OsSpecific.Package hdfsPackage = new OsSpecific.Package();
     hdfsPackage.setName("hdfs");
-    List<ServiceOsSpecific.Package> packages = 
Collections.singletonList(hdfsPackage);
+    List<OsSpecific.Package> packages = Collections.singletonList(hdfsPackage);
 
     RequestStatusResponse response = 
createNiceMock(RequestStatusResponse.class);
 
@@ -284,7 +284,7 @@ public class ClusterStackVersionResourceProviderTest {
     expect(managementController.getAuthName()).andReturn("admin").anyTimes();
     
expect(managementController.getActionManager()).andReturn(actionManager).anyTimes();
     
expect(managementController.getJdkResourceUrl()).andReturn("/JdkResourceUrl").anyTimes();
-    
expect(managementController.getPackagesForServiceHost(anyObject(ServiceInfo.class),
+    
expect(managementController.getPackagesForStackServiceHost(anyObject(StackInfo.class),anyObject(ServiceInfo.class),
             EasyMock.<Map<String, String>>anyObject(), 
anyObject(String.class))).
             andReturn(packages).anyTimes();
     
expect(managementController.findConfigurationTagsWithOverrides(anyObject(Cluster.class),
 EasyMock.anyString()))
@@ -466,10 +466,10 @@ public class ClusterStackVersionResourceProviderTest {
     // Third host only has hbase
     final List<ServiceComponentHost> schsH3 = Arrays.asList(schHBM);
 
-    ServiceOsSpecific.Package hdfsPackage = new ServiceOsSpecific.Package();
+    OsSpecific.Package hdfsPackage = new OsSpecific.Package();
     hdfsPackage.setName("hdfs");
 
-    List<ServiceOsSpecific.Package> packages = 
Collections.singletonList(hdfsPackage);
+    List<OsSpecific.Package> packages = Collections.singletonList(hdfsPackage);
 
     ActionManager actionManager = createNiceMock(ActionManager.class);
 
@@ -487,7 +487,7 @@ public class ClusterStackVersionResourceProviderTest {
     expect(managementController.getAuthName()).andReturn("admin").anyTimes();
     
expect(managementController.getActionManager()).andReturn(actionManager).anyTimes();
     
expect(managementController.getJdkResourceUrl()).andReturn("/JdkResourceUrl").anyTimes();
-    
expect(managementController.getPackagesForServiceHost(anyObject(ServiceInfo.class),
+    
expect(managementController.getPackagesForStackServiceHost(anyObject(StackInfo.class),
 anyObject(ServiceInfo.class),
             EasyMock.anyObject(), anyObject(String.class))).
             andReturn(packages).times(1); // only one host has the versionable 
component
 
@@ -668,17 +668,17 @@ public class ClusterStackVersionResourceProviderTest {
     final ServiceComponentHost schDatanode = 
createMock(ServiceComponentHost.class);
     expect(schDatanode.getServiceName()).andReturn("HDFS").anyTimes();
     
expect(schDatanode.getServiceComponentName()).andReturn("DATANODE").anyTimes();
-    expect(schDatanode.getServiceType()).andReturn("DATANODE").anyTimes();
+    expect(schDatanode.getServiceType()).andReturn("HDFS").anyTimes();
 
     final ServiceComponentHost schNamenode = 
createMock(ServiceComponentHost.class);
     expect(schNamenode.getServiceName()).andReturn("HDFS").anyTimes();
     
expect(schNamenode.getServiceComponentName()).andReturn("NAMENODE").anyTimes();
-    expect(schNamenode.getServiceType()).andReturn("NAMENODE").anyTimes();
+    expect(schNamenode.getServiceType()).andReturn("HDFS").anyTimes();
 
     final ServiceComponentHost schHBM = createMock(ServiceComponentHost.class);
     expect(schHBM.getServiceName()).andReturn("HBASE").anyTimes();
     
expect(schHBM.getServiceComponentName()).andReturn("HBASE_MASTER").anyTimes();
-    expect(schHBM.getServiceType()).andReturn("HBASE_MASTER").anyTimes();
+    expect(schHBM.getServiceType()).andReturn("HBASE").anyTimes();
 
     // First host contains versionable components
     final List<ServiceComponentHost> schsH1 = Arrays.asList(schDatanode, 
schNamenode);
@@ -689,10 +689,10 @@ public class ClusterStackVersionResourceProviderTest {
     // Third host only has hbase
     final List<ServiceComponentHost> schsH3 = Arrays.asList(schHBM);
 
-    ServiceOsSpecific.Package hdfsPackage = new ServiceOsSpecific.Package();
+    OsSpecific.Package hdfsPackage = new OsSpecific.Package();
     hdfsPackage.setName("hdfs");
 
-    List<ServiceOsSpecific.Package> packages = 
Collections.singletonList(hdfsPackage);
+    List<OsSpecific.Package> packages = Collections.singletonList(hdfsPackage);
 
     ActionManager actionManager = createNiceMock(ActionManager.class);
 
@@ -710,7 +710,7 @@ public class ClusterStackVersionResourceProviderTest {
     expect(managementController.getAuthName()).andReturn("admin").anyTimes();
     
expect(managementController.getActionManager()).andReturn(actionManager).anyTimes();
     
expect(managementController.getJdkResourceUrl()).andReturn("/JdkResourceUrl").anyTimes();
-    
expect(managementController.getPackagesForServiceHost(anyObject(ServiceInfo.class),
+    
expect(managementController.getPackagesForStackServiceHost(anyObject(StackInfo.class),
 anyObject(ServiceInfo.class),
             EasyMock.anyObject(), anyObject(String.class))).
             andReturn(packages).anyTimes(); // only one host has the 
versionable component
 
@@ -907,17 +907,17 @@ public class ClusterStackVersionResourceProviderTest {
     final ServiceComponentHost schDatanode = 
createMock(ServiceComponentHost.class);
     expect(schDatanode.getServiceName()).andReturn("HDFS").anyTimes();
     
expect(schDatanode.getServiceComponentName()).andReturn("DATANODE").anyTimes();
-     expect(schDatanode.getServiceType()).andReturn("DATANODE").anyTimes();
+     expect(schDatanode.getServiceType()).andReturn("HDFS").anyTimes();
 
     final ServiceComponentHost schNamenode = 
createMock(ServiceComponentHost.class);
     expect(schNamenode.getServiceName()).andReturn("HDFS").anyTimes();
     
expect(schNamenode.getServiceComponentName()).andReturn("NAMENODE").anyTimes();
-    expect(schNamenode.getServiceType()).andReturn("NAMENODE").anyTimes();
+    expect(schNamenode.getServiceType()).andReturn("HDFS").anyTimes();
 
     final ServiceComponentHost schHBM = createMock(ServiceComponentHost.class);
     expect(schHBM.getServiceName()).andReturn("HBASE").anyTimes();
     
expect(schHBM.getServiceComponentName()).andReturn("HBASE_MASTER").anyTimes();
-    expect(schHBM.getServiceType()).andReturn("HBASE_MASTER").anyTimes();
+    expect(schHBM.getServiceType()).andReturn("HBASE").anyTimes();
 
     // First host contains versionable components
     final List<ServiceComponentHost> schsH1 = Arrays.asList(schDatanode, 
schNamenode);
@@ -928,10 +928,10 @@ public class ClusterStackVersionResourceProviderTest {
     // Third host only has hbase
     final List<ServiceComponentHost> schsH3 = Arrays.asList(schHBM);
 
-    ServiceOsSpecific.Package hdfsPackage = new ServiceOsSpecific.Package();
+    OsSpecific.Package hdfsPackage = new OsSpecific.Package();
     hdfsPackage.setName("hdfs");
 
-    List<ServiceOsSpecific.Package> packages = 
Collections.singletonList(hdfsPackage);
+    List<OsSpecific.Package> packages = Collections.singletonList(hdfsPackage);
 
     ActionManager actionManager = createNiceMock(ActionManager.class);
 
@@ -946,7 +946,7 @@ public class ClusterStackVersionResourceProviderTest {
     expect(managementController.getAuthName()).andReturn("admin").anyTimes();
     
expect(managementController.getActionManager()).andReturn(actionManager).anyTimes();
     
expect(managementController.getJdkResourceUrl()).andReturn("/JdkResourceUrl").anyTimes();
-    
expect(managementController.getPackagesForServiceHost(anyObject(ServiceInfo.class),
+    
expect(managementController.getPackagesForStackServiceHost(anyObject(StackInfo.class),
 anyObject(ServiceInfo.class),
             EasyMock.anyObject(), anyObject(String.class))).
             andReturn(packages).anyTimes(); // only one host has the 
versionable component
 
@@ -1147,9 +1147,9 @@ public class ClusterStackVersionResourceProviderTest {
     // Second host does not contain versionable components
     final List<ServiceComponentHost> schsH2 = Lists.newArrayList(schAMS);
 
-    ServiceOsSpecific.Package hdfsPackage = new ServiceOsSpecific.Package();
+    OsSpecific.Package hdfsPackage = new OsSpecific.Package();
     hdfsPackage.setName("hdfs");
-    List<ServiceOsSpecific.Package> packages = 
Collections.singletonList(hdfsPackage);
+    List<OsSpecific.Package> packages = Collections.singletonList(hdfsPackage);
 
     ActionManager actionManager = createNiceMock(ActionManager.class);
 
@@ -1163,7 +1163,7 @@ public class ClusterStackVersionResourceProviderTest {
     expect(managementController.getAuthName()).andReturn("admin").anyTimes();
     
expect(managementController.getActionManager()).andReturn(actionManager).anyTimes();
     
expect(managementController.getJdkResourceUrl()).andReturn("/JdkResourceUrl").anyTimes();
-    
expect(managementController.getPackagesForServiceHost(anyObject(ServiceInfo.class),
+    
expect(managementController.getPackagesForStackServiceHost(anyObject(StackInfo.class),
 anyObject(ServiceInfo.class),
             EasyMock.<Map<String, String>>anyObject(), 
anyObject(String.class))).
             andReturn(packages).anyTimes();
 
@@ -1360,10 +1360,10 @@ public class ClusterStackVersionResourceProviderTest {
 
     final List<ServiceComponentHost> serviceComponentHosts = 
Arrays.asList(schDatanode);
 
-    ServiceOsSpecific.Package hdfsPackage = new ServiceOsSpecific.Package();
+    OsSpecific.Package hdfsPackage = new OsSpecific.Package();
     hdfsPackage.setName("hdfs");
 
-    List<ServiceOsSpecific.Package> packages = 
Collections.singletonList(hdfsPackage);
+    List<OsSpecific.Package> packages = Collections.singletonList(hdfsPackage);
 
     RequestStatusResponse response = 
createNiceMock(RequestStatusResponse.class);
     ResourceProviderFactory resourceProviderFactory = 
createNiceMock(ResourceProviderFactory.class);
@@ -1375,7 +1375,7 @@ public class ClusterStackVersionResourceProviderTest {
     
expect(managementController.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes();
     expect(managementController.getAuthName()).andReturn("admin").anyTimes();
     
expect(managementController.getJdkResourceUrl()).andReturn("/JdkResourceUrl").anyTimes();
-    
expect(managementController.getPackagesForServiceHost(anyObject(ServiceInfo.class),
+    
expect(managementController.getPackagesForStackServiceHost(anyObject(StackInfo.class),
 anyObject(ServiceInfo.class),
         EasyMock.anyObject(), anyObject(String.class))).andReturn(
             packages).anyTimes(); // only one host has the versionable 
component
 
@@ -1513,23 +1513,23 @@ public class ClusterStackVersionResourceProviderTest {
     final ServiceComponentHost schDatanode = 
createMock(ServiceComponentHost.class);
     expect(schDatanode.getServiceName()).andReturn("HDFS").anyTimes();
     
expect(schDatanode.getServiceComponentName()).andReturn("DATANODE").anyTimes();
-    expect(schDatanode.getServiceType()).andReturn("DATANODE").anyTimes();
+    expect(schDatanode.getServiceType()).andReturn("HDFS").anyTimes();
     final ServiceComponentHost schNamenode = 
createMock(ServiceComponentHost.class);
     expect(schNamenode.getServiceName()).andReturn("HDFS").anyTimes();
     
expect(schNamenode.getServiceComponentName()).andReturn("NAMENODE").anyTimes();
-    expect(schNamenode.getServiceType()).andReturn("NAMENODE").anyTimes();
+    expect(schNamenode.getServiceType()).andReturn("HDFS").anyTimes();
     final ServiceComponentHost schAMS = createMock(ServiceComponentHost.class);
     expect(schAMS.getServiceName()).andReturn("AMBARI_METRICS").anyTimes();
     
expect(schAMS.getServiceComponentName()).andReturn("METRICS_COLLECTOR").anyTimes();
-    expect(schAMS.getServiceType()).andReturn("METRICS_COLLECTOR").anyTimes();
+    expect(schAMS.getServiceType()).andReturn("AMBARI_METRICS").anyTimes();
     // First host contains versionable components
     final List<ServiceComponentHost> schsH1 = Lists.newArrayList(schDatanode, 
schNamenode, schAMS);
     // Second host does not contain versionable components
     final List<ServiceComponentHost> schsH2 = Lists.newArrayList(schAMS);
 
-    ServiceOsSpecific.Package hdfsPackage = new ServiceOsSpecific.Package();
+    OsSpecific.Package hdfsPackage = new OsSpecific.Package();
     hdfsPackage.setName("hdfs");
-    List<ServiceOsSpecific.Package> packages = 
Collections.singletonList(hdfsPackage);
+    List<OsSpecific.Package> packages = Collections.singletonList(hdfsPackage);
 
     ActionManager actionManager = createNiceMock(ActionManager.class);
 
@@ -1547,7 +1547,7 @@ public class ClusterStackVersionResourceProviderTest {
     expect(managementController.getAuthName()).andReturn("admin").anyTimes();
     
expect(managementController.getActionManager()).andReturn(actionManager).anyTimes();
     
expect(managementController.getJdkResourceUrl()).andReturn("/JdkResourceUrl").anyTimes();
-    
expect(managementController.getPackagesForServiceHost(anyObject(ServiceInfo.class),
+    
expect(managementController.getPackagesForStackServiceHost(anyObject(StackInfo.class),
 anyObject(ServiceInfo.class),
             (Map<String, String>) anyObject(List.class), 
anyObject(String.class))).
             andReturn(packages).anyTimes();
 
@@ -2035,17 +2035,17 @@ public class ClusterStackVersionResourceProviderTest {
      final ServiceComponentHost schDatanode = 
createMock(ServiceComponentHost.class);
      expect(schDatanode.getServiceName()).andReturn("HDFS").anyTimes();
      
expect(schDatanode.getServiceComponentName()).andReturn("DATANODE").anyTimes();
-     expect(schDatanode.getServiceType()).andReturn("DATANODE").anyTimes();
+     expect(schDatanode.getServiceType()).andReturn("HDFS").anyTimes();
 
      final ServiceComponentHost schNamenode = 
createMock(ServiceComponentHost.class);
      expect(schNamenode.getServiceName()).andReturn("HDFS").anyTimes();
      
expect(schNamenode.getServiceComponentName()).andReturn("NAMENODE").anyTimes();
-     expect(schNamenode.getServiceType()).andReturn("NAMENODE").anyTimes();
+     expect(schNamenode.getServiceType()).andReturn("HDFS").anyTimes();
 
      final ServiceComponentHost schHBM = 
createMock(ServiceComponentHost.class);
      expect(schHBM.getServiceName()).andReturn("HBASE").anyTimes();
      
expect(schHBM.getServiceComponentName()).andReturn("HBASE_MASTER").anyTimes();
-     expect(schHBM.getServiceType()).andReturn("HBASE_MASTER").anyTimes();
+     expect(schHBM.getServiceType()).andReturn("HBASE").anyTimes();
 
      // First host contains versionable components
      final List<ServiceComponentHost> schsH1 = Arrays.asList(schDatanode, 
schNamenode);
@@ -2056,10 +2056,10 @@ public class ClusterStackVersionResourceProviderTest {
      // Third host only has hbase
      final List<ServiceComponentHost> schsH3 = Arrays.asList(schHBM);
 
-     ServiceOsSpecific.Package hdfsPackage = new ServiceOsSpecific.Package();
+     OsSpecific.Package hdfsPackage = new OsSpecific.Package();
      hdfsPackage.setName("hdfs");
 
-     List<ServiceOsSpecific.Package> packages = 
Collections.singletonList(hdfsPackage);
+     List<OsSpecific.Package> packages = 
Collections.singletonList(hdfsPackage);
 
      ActionManager actionManager = createNiceMock(ActionManager.class);
 
@@ -2074,7 +2074,7 @@ public class ClusterStackVersionResourceProviderTest {
      expect(managementController.getAuthName()).andReturn("admin").anyTimes();
      
expect(managementController.getActionManager()).andReturn(actionManager).anyTimes();
      
expect(managementController.getJdkResourceUrl()).andReturn("/JdkResourceUrl").anyTimes();
-     
expect(managementController.getPackagesForServiceHost(anyObject(ServiceInfo.class),
+     
expect(managementController.getPackagesForStackServiceHost(anyObject(StackInfo.class),
 anyObject(ServiceInfo.class),
          EasyMock.<Map<String, String>>anyObject(), anyObject(String.class))).
      andReturn(packages).anyTimes(); // only one host has the versionable 
component
 

Reply via email to