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

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


The following commit(s) were added to refs/heads/branch-feature-AMBARI-14714 by 
this push:
     new 953043c  [AMBARI-24467] - Report Component Instance On Agent 
Registration (#2071)
953043c is described below

commit 953043c3f3d459662435a0d32620f8a402397560
Author: Jonathan Hurley <[email protected]>
AuthorDate: Wed Aug 15 08:07:07 2018 -0400

    [AMBARI-24467] - Report Component Instance On Agent Registration (#2071)
---
 .../ambari_agent/ComponentVersionReporter.py       |  11 +-
 .../resource_management/libraries/script/script.py |  18 +-
 .../ambari/server/agent/HeartbeatProcessor.java    |  38 ++-
 .../ambari/server/agent/stomp/TopologyHolder.java  |  44 ++-
 .../agent/stomp/dto/ComponentVersionReport.java    |  32 +-
 .../server/agent/stomp/dto/TopologyComponent.java  |  52 +++-
 .../controller/AmbariManagementControllerImpl.java |   1 +
 .../DeleteHostComponentStatusMetaData.java         |  16 +-
 .../svccomphost/ServiceComponentHostImpl.java      |   1 +
 .../topology/STOMPComponentsDeleteHandler.java     |   1 +
 .../custom_actions/scripts/stack_select_set_all.py | 116 -------
 .../resources/scripts/mpack_advisor_wrapper.py     |   0
 .../custom_actions/test_stack_select_set_all.py    | 343 ---------------------
 13 files changed, 156 insertions(+), 517 deletions(-)

diff --git 
a/ambari-agent/src/main/python/ambari_agent/ComponentVersionReporter.py 
b/ambari-agent/src/main/python/ambari_agent/ComponentVersionReporter.py
index eb4358b..7e23ec8 100644
--- a/ambari-agent/src/main/python/ambari_agent/ComponentVersionReporter.py
+++ b/ambari-agent/src/main/python/ambari_agent/ComponentVersionReporter.py
@@ -58,10 +58,11 @@ class ComponentVersionReporter(threading.Thread):
           if current_host_id not in component_dict.hostIds:
             continue
 
+          service_group_name = component_dict.serviceGroupName
           service_name = component_dict.serviceName
           component_name = component_dict.componentName
 
-          result = self.check_component_version(cluster_id, service_name, 
component_name)
+          result = self.check_component_version(cluster_id, 
service_group_name, service_name, component_name)
 
           if result:
             cluster_reports[cluster_id].append(result)
@@ -70,7 +71,7 @@ class ComponentVersionReporter(threading.Thread):
     except:
       logger.exception("Exception in ComponentVersionReporter")
 
-  def check_component_version(self, cluster_id, service_name, component_name):
+  def check_component_version(self, cluster_id, service_group_name, 
service_name, component_name):
     """
     Returns components version
     """
@@ -79,6 +80,7 @@ class ComponentVersionReporter(threading.Thread):
       return None
 
     command_dict = {
+      'serviceGroupName': service_group_name,
       'serviceName': service_name,
       'role': component_name,
       'clusterId': cluster_id,
@@ -87,16 +89,17 @@ class ComponentVersionReporter(threading.Thread):
 
     version_result = 
self.customServiceOrchestrator.requestComponentStatus(command_dict, 
command_name=AgentCommand.get_version)
 
-    if version_result['exitcode'] or not 'structuredOut' in version_result or 
not 'version' in version_result['structuredOut']:
+    if version_result['exitcode'] or not 'structuredOut' in version_result or 
not 'version_reporting' in version_result['structuredOut']:
       logger.error("Could not get version for component {0} of {1} service 
cluster_id={2}. Command returned: {3}".format(component_name, service_name, 
cluster_id, version_result))
       return None
 
     # TODO: check if no strout or version if not there
 
     result = {
+      'serviceGroupName': service_group_name,
       'serviceName': service_name,
       'componentName': component_name,
-      'version': version_result['structuredOut']['version'],
+      'version_reporting': 
version_result['structuredOut']['version_reporting'],
       'clusterId': cluster_id,
     }
 
diff --git 
a/ambari-common/src/main/python/resource_management/libraries/script/script.py 
b/ambari-common/src/main/python/resource_management/libraries/script/script.py
index daf6175..275e4c5 100644
--- 
a/ambari-common/src/main/python/resource_management/libraries/script/script.py
+++ 
b/ambari-common/src/main/python/resource_management/libraries/script/script.py
@@ -25,20 +25,18 @@ import re
 import os
 import sys
 import logging
-import platform
 import inspect
 import tarfile
 import traceback
 import time
 from optparse import OptionParser
 import resource_management
-from ambari_commons import OSCheck, OSConst
+from ambari_commons import OSCheck
 from ambari_commons.constants import UPGRADE_TYPE_EXPRESS
 from ambari_commons.constants import UPGRADE_TYPE_ROLLING
 from ambari_commons.constants import UPGRADE_TYPE_HOST_ORDERED
 from ambari_commons.network import reconfigure_urllib2_opener
-from ambari_commons.inet_utils import resolve_address, 
ensure_ssl_using_protocol
-from ambari_commons.os_family_impl import OsFamilyFuncImpl, OsFamilyImpl
+from ambari_commons.inet_utils import ensure_ssl_using_protocol
 from resource_management.libraries.resources import XmlConfig
 from resource_management.libraries.resources import PropertiesFile
 from resource_management.core import sudo
@@ -54,14 +52,11 @@ from resource_management.libraries.functions import 
stack_tools
 from resource_management.libraries.functions.constants import Direction
 from resource_management.libraries.script.config_dictionary import 
ConfigDictionary, UnknownConfiguration
 from resource_management.libraries.functions.repository_util import 
CommandRepository, RepositoryUtil
-from resource_management.core.resources.system import Execute
 from contextlib import closing
 from resource_management.libraries.functions.stack_features import 
check_stack_feature
 from resource_management.libraries.functions.constants import StackFeature
 from resource_management.libraries.functions.show_logs import show_logs
-from resource_management.libraries.functions.fcntl_based_process_lock import 
FcntlBasedProcessLock
 from resource_management.libraries.execution_command.execution_command import 
ExecutionCommand
-from resource_management.libraries.execution_command.module_configs import 
ModuleConfigs
 
 import ambari_simplejson as json # simplejson is much faster comparing to 
Python 2.6 json module and has the same functions set.
 
@@ -268,6 +263,7 @@ class Script(object):
 
     return False
 
+
   def execute(self):
     """
     Sets up logging;
@@ -366,9 +362,17 @@ class Script(object):
       if self.should_expose_component_version():
         self.save_component_version_to_structured_out()
 
+
   def get_version(self, env):
+    """
+    A dummy method which is used to ask for the version of installed 
components on startup using t
+    he topology information which is sent to the agent.
+    :param env:
+    :return: nothing
+    """
     pass
 
+
   def execute_prefix_function(self, command_name, afix, env):
     """
     Execute action afix (prefix or suffix) based on command_name and afix type
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
index 205aa7f..d9099f9 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
@@ -33,8 +33,6 @@ import java.util.concurrent.TimeUnit;
 
 import javax.annotation.Nullable;
 
-import org.apache.ambari.annotations.Experimental;
-import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.RoleCommand;
@@ -81,6 +79,7 @@ import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.util.concurrent.AbstractService;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import com.google.gson.Gson;
@@ -593,9 +592,6 @@ public class HeartbeatProcessor extends AbstractService{
    * Process reports of components versions
    * @throws AmbariException
    */
-  @Experimental(
-      feature = ExperimentalFeature.VERSION_REPORTING,
-      comment = "This needs to be rewritten using the new structured output")
   public void processVersionReports(ComponentVersionReports versionReports, 
String hostname) throws AmbariException {
     Set<Cluster> clusters = clusterFsm.getClustersForHost(hostname);
     for (Cluster cl : clusters) {
@@ -604,19 +600,16 @@ public class HeartbeatProcessor extends AbstractService{
         if (Long.valueOf(status.getKey()).equals(cl.getClusterId())) {
           for (ComponentVersionReport versionReport : status.getValue()) {
             try {
-              Service svc = cl.getService(versionReport.getServiceName());
+              Service svc = cl.getService(versionReport.getServiceGroupName(), 
versionReport.getServiceName());
 
               String componentName = versionReport.getComponentName();
               if (svc.getServiceComponents().containsKey(componentName)) {
-                ServiceComponent svcComp = svc.getServiceComponent(
-                    componentName);
-                ServiceComponentHost scHost = svcComp.getServiceComponentHost(
-                    hostname);
-
-                String version = versionReport.getVersion();
+                ServiceComponent svcComp = 
svc.getServiceComponent(componentName);
+                ServiceComponentHost scHost = 
svcComp.getServiceComponentHost(hostname);
 
                 HostComponentVersionAdvertisedEvent event = new 
HostComponentVersionAdvertisedEvent(cl,
-                    scHost, null);
+                    scHost, versionReport.getVersionStructuredOutput());
+
                 versionEventPublisher.publish(event);
               }
             } catch (ServiceNotFoundException e) {
@@ -825,6 +818,16 @@ public class HeartbeatProcessor extends AbstractService{
 
     @SerializedName("version")
     public String version;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+      return MoreObjects.toStringHelper(this)
+          .add("mpackVersion", mpackVersion)
+          .add("version", version).toString();
+    }
   }
 
   /**
@@ -834,5 +837,14 @@ public class HeartbeatProcessor extends AbstractService{
   public static class UpgradeSummaryStructuredOuut {
     @SerializedName("direction")
     public String direction;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+      return MoreObjects.toStringHelper(this)
+          .add("direction", direction).toString();
+    }
   }
 }
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/TopologyHolder.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/TopologyHolder.java
index a2710231..c1a4641 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/TopologyHolder.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/TopologyHolder.java
@@ -22,6 +22,7 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.stream.Collectors;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
@@ -44,7 +45,6 @@ import org.apache.commons.collections.CollectionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Sets;
 import com.google.common.eventbus.Subscribe;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -90,15 +90,28 @@ public class TopologyHolder extends 
AgentClusterDataHolder<TopologyUpdateEvent>
       for (Service service : cl.getServices()) {
         for (ServiceComponent component : 
service.getServiceComponents().values()) {
           Map<String, ServiceComponentHost> componentsMap = 
component.getServiceComponentHosts();
-          for (ServiceComponentHost sch : componentsMap.values()) {
+          if (!componentsMap.isEmpty()) {
+
+            //TODO will be a need to change to multi-instance usage
+            ServiceComponentHost sch = 
componentsMap.entrySet().iterator().next().getValue();
+
+            Set<String> hostNames = cl.getHosts(sch.getServiceName(), 
sch.getServiceComponentName());
+            Set<Long> hostOrderIds = clusterHosts.stream()
+              .filter(h -> hostNames.contains(h.getHostName()))
+              .map(Host::getHostId)
+              .collect(Collectors.toSet());
+            String serviceGroupName = sch.getServiceGroupName();
+
             TopologyComponent topologyComponent = 
TopologyComponent.newBuilder()
-              .setComponentName(sch.getServiceComponentName())
-              .setServiceName(sch.getServiceName())
-              .setVersion(sch.getVersion())
-              .setHostIds(Sets.newHashSet(sch.getHost().getHostId()))
-              
.setComponentLevelParams(ambariManagementController.getTopologyComponentLevelParams(sch))
-              
.setCommandParams(ambariManagementController.getTopologyCommandParams(sch))
-              .build();
+                .setComponentName(sch.getServiceComponentName())
+                .setServiceName(sch.getServiceName())
+                .setServiceGroupName(serviceGroupName)
+                .setVersion(sch.getVersion())
+                .setMpackVersion(sch.getMpackVersion())
+                .setHostIds(hostOrderIds)
+                
.setComponentLevelParams(ambariManagementController.getTopologyComponentLevelParams(sch))
+                
.setCommandParams(ambariManagementController.getTopologyCommandParams(sch))
+                .build();
             topologyComponents.add(topologyComponent);
           }
         }
@@ -206,19 +219,22 @@ public class TopologyHolder extends 
AgentClusterDataHolder<TopologyUpdateEvent>
         Map<String, ServiceComponentHost> componentsMap = 
component.getServiceComponentHosts();
         if (!componentsMap.isEmpty()) {
 
-          for (ServiceComponentHost sch : componentsMap.values()) {
-            TopologyComponent topologyComponent = 
TopologyComponent.newBuilder()
+          //TODO will be a need to change to multi-instance usage
+          ServiceComponentHost sch = 
componentsMap.entrySet().iterator().next().getValue();
+
+          TopologyComponent topologyComponent = TopologyComponent.newBuilder()
               .setComponentName(sch.getServiceComponentName())
               .setServiceName(sch.getServiceName())
+              .setServiceGroupName(sch.getServiceGroupName())
               .setVersion(sch.getVersion())
+              .setMpackVersion(sch.getMpackVersion())
               
.setCommandParams(ambariManagementController.getTopologyCommandParams(sch))
               
.setComponentLevelParams(ambariManagementController.getTopologyComponentLevelParams(sch))
               .build();
-            topologyComponents.add(topologyComponent);
-          }
+          topologyComponents.add(topologyComponent);
         }
       }
     }
     return topologyComponents;
   }
-}
+}
\ No newline at end of file
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/ComponentVersionReport.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/ComponentVersionReport.java
index 6619096..1202c8d 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/ComponentVersionReport.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/ComponentVersionReport.java
@@ -18,20 +18,29 @@
 
 package org.apache.ambari.server.agent.stomp.dto;
 
+import 
org.apache.ambari.server.agent.HeartbeatProcessor.ComponentVersionStructuredOut;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 public class ComponentVersionReport {
   private String componentName;
   private String serviceName;
-  private String version;
+  private String serviceGroupName;
   private Long clusterId;
 
+  @JsonProperty("version_reporting")
+  private ComponentVersionStructuredOut componentVersionStructuredOut;
+
   public ComponentVersionReport() {
   }
 
-  public ComponentVersionReport(String componentName, String serviceName, 
String version, Long clusterId) {
+  public ComponentVersionReport(Long clusterId, String serviceGroupName, 
String serviceName, String componentName,
+      ComponentVersionStructuredOut componentVersionStructuredOut) {
     this.componentName = componentName;
     this.serviceName = serviceName;
-    this.version = version;
+    this.serviceGroupName = serviceGroupName;
     this.clusterId = clusterId;
+    this.componentVersionStructuredOut = componentVersionStructuredOut;
   }
 
   public String getComponentName() {
@@ -42,6 +51,14 @@ public class ComponentVersionReport {
     this.componentName = componentName;
   }
 
+  public String getServiceGroupName() {
+    return serviceGroupName;
+  }
+
+  public void setServiceGroupName(String serviceGroupName) {
+    this.serviceGroupName = serviceGroupName;
+  }
+
   public String getServiceName() {
     return serviceName;
   }
@@ -50,12 +67,13 @@ public class ComponentVersionReport {
     this.serviceName = serviceName;
   }
 
-  public String getVersion() {
-    return version;
+  public ComponentVersionStructuredOut getVersionStructuredOutput() {
+    return componentVersionStructuredOut;
   }
 
-  public void setVersion(String version) {
-    this.version = version;
+  public void setVersionStructuredOutput(
+      ComponentVersionStructuredOut componentVersionStructuredOut) {
+    this.componentVersionStructuredOut = componentVersionStructuredOut;
   }
 
   public Long getClusterId() {
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/TopologyComponent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/TopologyComponent.java
index b3da819..c633b63 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/TopologyComponent.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/dto/TopologyComponent.java
@@ -20,6 +20,7 @@ package org.apache.ambari.server.agent.stomp.dto;
 
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.TreeMap;
 
@@ -34,8 +35,10 @@ import com.fasterxml.jackson.annotation.JsonInclude;
 public class TopologyComponent {
   private String componentName;
   private String serviceName;
+  private String serviceGroupName;
   private String serviceType;
   private String version;
+  private String mpackVersion;
   private Set<Long> hostIds = new HashSet<>();
   private Set<String> hostNames = new HashSet<>();
   private Set<String> publicHostNames = new HashSet<>();
@@ -65,6 +68,11 @@ public class TopologyComponent {
       return this;
     }
 
+    public Builder setServiceGroupName(String serviceGroupName) {
+      TopologyComponent.this.setServiceGroupName(serviceGroupName);
+      return this;
+    }
+
     public Builder setServiceType(String serviceType) {
       TopologyComponent.this.setServiceType(serviceType);
       return this;
@@ -75,6 +83,11 @@ public class TopologyComponent {
       return this;
     }
 
+    public Builder setMpackVersion(String mpackVersion) {
+      TopologyComponent.this.setMpackVersion(mpackVersion);
+      return this;
+    }
+
     public Builder setHostIds(Set<Long> hostIds) {
       TopologyComponent.this.setHostIds(hostIds);
       return this;
@@ -187,6 +200,7 @@ public class TopologyComponent {
     return TopologyComponent.newBuilder().setComponentName(getComponentName())
         .setServiceType(getServiceType())
         .setServiceName(getServiceName())
+        .setServiceGroupName(getServiceGroupName())
         .setComponentLevelParams(getComponentLevelParams() == null ? null : 
new TreeMap<>(getComponentLevelParams()))
         .setHostIds(getHostIds() == null ? null : new HashSet<>(getHostIds()))
         .setHostNames(getHostNames() == null ? null : new 
HashSet<>(getHostNames()))
@@ -211,6 +225,14 @@ public class TopologyComponent {
     this.serviceName = serviceName;
   }
 
+  public String getServiceGroupName() {
+    return serviceGroupName;
+  }
+
+  public void setServiceGroupName(String serviceGroupName) {
+    this.serviceGroupName = serviceGroupName;
+  }
+
   public String getVersion() {
     return version;
   }
@@ -219,6 +241,14 @@ public class TopologyComponent {
     this.version = version;
   }
 
+  public String getMpackVersion() {
+    return mpackVersion;
+  }
+
+  public void setMpackVersion(String mpackVersion) {
+    this.mpackVersion = mpackVersion;
+  }
+
   public Set<Long> getHostIds() {
     return hostIds;
   }
@@ -228,11 +258,11 @@ public class TopologyComponent {
   }
 
   public void addHostId(Long hostId) {
-    this.hostIds.add(hostId);
+    hostIds.add(hostId);
   }
 
   public void addHostName(String hostName) {
-    this.hostNames.add(hostName);
+    hostNames.add(hostName);
   }
 
   public TreeMap<String, String> getComponentLevelParams() {
@@ -285,19 +315,21 @@ public class TopologyComponent {
 
   @Override
   public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
 
     TopologyComponent that = (TopologyComponent) o;
-
-    if (!componentName.equals(that.componentName)) return false;
-    return serviceName.equals(that.serviceName);
+    return Objects.equals(serviceGroupName, that.serviceGroupName)
+        && Objects.equals(serviceName, that.serviceName)
+        && Objects.equals(componentName, that.componentName);
   }
 
   @Override
   public int hashCode() {
-    int result = componentName.hashCode();
-    result = 31 * result + serviceName.hashCode();
-    return result;
+    return Objects.hash(serviceGroupName, serviceName, componentName);
   }
 }
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 ddc083e..6af49b5 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
@@ -822,6 +822,7 @@ public class AmbariManagementControllerImpl implements 
AmbariManagementControlle
       TopologyComponent newComponent = TopologyComponent.newBuilder()
           .setComponentName(sch.getServiceComponentName())
           .setServiceName(sc.getServiceName())
+          .setServiceGroupName(sc.getServiceGroupName())
           .setServiceType(sc.getServiceType())
           .setVersion(sch.getVersion())
           .setHostIds(hostIds)
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DeleteHostComponentStatusMetaData.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DeleteHostComponentStatusMetaData.java
index 7237f5b..1160ad9 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DeleteHostComponentStatusMetaData.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DeleteHostComponentStatusMetaData.java
@@ -33,9 +33,9 @@ public class DeleteHostComponentStatusMetaData extends 
DeleteStatusMetaData {
     removedHostComponents = new HashSet<>();
   }
 
-  public void addDeletedHostComponent(String componentName, String 
serviceName, String hostName, Long hostId,
+  public void addDeletedHostComponent(String componentName, String 
serviceName, String serviceGroupName, String hostName, Long hostId,
                                       String clusterId, String version, State 
lastComponentState) {
-    removedHostComponents.add(new HostComponent(componentName, serviceName, 
hostId,
+    removedHostComponents.add(new HostComponent(componentName, serviceName, 
serviceGroupName, hostId,
         hostName, clusterId, version, lastComponentState));
     addDeletedKey(componentName + "/" + hostName);
   }
@@ -55,16 +55,18 @@ public class DeleteHostComponentStatusMetaData extends 
DeleteStatusMetaData {
   public class HostComponent {
     private String componentName;
     private String serviceName;
+    private String serviceGroupName;
     private Long hostId;
     private String hostName;
     private String clusterId;
     private String version;
     private State lastComponentState;
 
-    public HostComponent(String componentName, String serviceName, Long 
hostId, String hostName,
+    public HostComponent(String componentName, String serviceName, String 
serviceGroupName, Long hostId, String hostName,
                          String clusterId, String version, State 
lastComponentState) {
       this.componentName = componentName;
       this.serviceName = serviceName;
+      this.serviceGroupName = serviceGroupName;
       this.hostId = hostId;
       this.hostName = hostName;
       this.clusterId = clusterId;
@@ -104,6 +106,14 @@ public class DeleteHostComponentStatusMetaData extends 
DeleteStatusMetaData {
       this.serviceName = serviceName;
     }
 
+    public String getServiceGroupName() {
+      return serviceGroupName;
+    }
+
+    public void setServiceGroupName(String serviceGroupName) {
+      this.serviceGroupName = serviceGroupName;
+    }
+
     public String getHostName() {
       return hostName;
     }
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index 3b29037..a8046b8 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -1461,6 +1461,7 @@ public class ServiceComponentHostImpl implements 
ServiceComponentHost {
       eventPublisher.publish(event);
       deleteMetaData.addDeletedHostComponent(componentName,
           serviceName,
+          serviceGroupName,
           hostName,
           getHost().getHostId(),
           Long.toString(clusterId),
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/topology/STOMPComponentsDeleteHandler.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/topology/STOMPComponentsDeleteHandler.java
index c48d4cf..69d7bff 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/topology/STOMPComponentsDeleteHandler.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/topology/STOMPComponentsDeleteHandler.java
@@ -119,6 +119,7 @@ public class STOMPComponentsDeleteHandler {
       TopologyComponent deletedComponent = TopologyComponent.newBuilder()
           .setComponentName(hostComponent.getComponentName())
           .setServiceName(hostComponent.getServiceName())
+          .setServiceGroupName(hostComponent.getServiceGroupName())
           .setVersion(hostComponent.getVersion())
           .setHostIds(new HashSet<>(Arrays.asList(hostComponent.getHostId())))
           .setHostNames(new 
HashSet<>(Arrays.asList(hostComponent.getHostName())))
diff --git 
a/ambari-server/src/main/resources/custom_actions/scripts/stack_select_set_all.py
 
b/ambari-server/src/main/resources/custom_actions/scripts/stack_select_set_all.py
deleted file mode 100644
index 9ae27ba..0000000
--- 
a/ambari-server/src/main/resources/custom_actions/scripts/stack_select_set_all.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env python
-"""
-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.
-
-Ambari Agent
-
-"""
-
-import os
-import socket
-from ambari_commons.os_check import OSCheck
-from resource_management.libraries.script import Script
-from resource_management.libraries.functions import stack_tools
-from resource_management.libraries.functions import upgrade_summary
-from resource_management.libraries.functions.constants import Direction
-from resource_management.core import shell
-from resource_management.core.logger import Logger
-from resource_management.libraries.functions.decorator import experimental
-
-class UpgradeSetAll(Script):
-  """
-  This script is a part of stack upgrade workflow and is used to set the
-  all of the component versions as a final step in the upgrade process
-  """
-  @experimental(feature="PATCH_UPGRADES", disable = False, comment = "The 
stack-select tool will only be invoked if this is a standard upgrade which 
cannot be downgraded.")
-  def actionexecute(self, env):
-    summary = upgrade_summary.get_upgrade_summary()
-    if summary is None:
-      Logger.warning("There is no upgrade in progress")
-      return
-
-    if summary.associated_version is None:
-      Logger.warning("There is no version associated with the upgrade in 
progress")
-      return
-
-    if summary.orchestration != "STANDARD":
-      Logger.warning("The 'stack-select set all' command can only be invoked 
during STANDARD upgrades")
-      return
-
-    if summary.direction.lower() != Direction.UPGRADE or 
summary.is_downgrade_allowed or summary.is_revert:
-      Logger.warning("The 'stack-select set all' command can only be invoked 
during an UPGRADE which cannot be downgraded")
-      return
-
-    # other os?
-    if OSCheck.is_redhat_family():
-      cmd = ('/usr/bin/yum', 'clean', 'all')
-      code, out = shell.call(cmd, sudo=True)
-
-    stack_selector_path = 
stack_tools.get_stack_tool_path(stack_tools.STACK_SELECTOR_NAME)
-
-    # this script runs on all hosts; if this host doesn't have stack 
components,
-    # then don't invoke the stack tool
-    # (no need to log that it's skipped - the function will do that)
-    if is_host_skippable(stack_selector_path, summary.associated_version):
-      return
-
-    # invoke "set all"
-    cmd = ('ambari-python-wrap', stack_selector_path, 'set', 'all', 
summary.associated_version)
-    code, out = shell.call(cmd, sudo=True)
-    if code != 0:
-      raise Exception("Command '{0}' exit code is nonzero".format(cmd))
-
-
-def is_host_skippable(stack_selector_path, associated_version):
-  """
-  Gets whether this host should not have the stack select tool called.
-  :param stack_selector_path  the path to the stack selector tool.
-  :param associated_version: the version to use with the stack selector tool.
-  :return: True if this host should be skipped, False otherwise.
-  """
-  if not os.path.exists(stack_selector_path):
-    Logger.info("{0} does not have any stack components installed and will not 
invoke {1}".format(
-      socket.gethostname(), stack_selector_path))
-
-    return True
-
-  # invoke the tool, checking its output
-  cmd = ('ambari-python-wrap', stack_selector_path, "versions")
-  code, out = shell.call(cmd, sudo=True)
-
-  if code != 0:
-    Logger.info("{0} is unable to determine which stack versions are available 
using {1}".format(
-        socket.gethostname(), stack_selector_path))
-
-    return True
-
-  # check to see if the output is empty, indicating no versions installed
-  if not out.strip():
-    Logger.info("{0} has no stack versions 
installed".format(socket.gethostname()))
-    return True
-
-  # some pre-prepped systems may have a version, so there may be a version, so
-  # add the extra check if it is available
-  if not associated_version in out:
-    Logger.info("{0} is not found in the list of versions 
{1}".format(associated_version, out))
-    return True
-
-  return False
-
-
-if __name__ == "__main__":
-  UpgradeSetAll().execute()
diff --git a/ambari-server/src/main/resources/scripts/mpack_advisor_wrapper.py 
b/ambari-server/src/main/resources/scripts/mpack_advisor_wrapper.py
old mode 100644
new mode 100755
diff --git 
a/ambari-server/src/test/python/custom_actions/test_stack_select_set_all.py 
b/ambari-server/src/test/python/custom_actions/test_stack_select_set_all.py
deleted file mode 100644
index 3bcd0bb..0000000
--- a/ambari-server/src/test/python/custom_actions/test_stack_select_set_all.py
+++ /dev/null
@@ -1,343 +0,0 @@
-# !/usr/bin/env python
-
-'''
-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.
-'''
-
-# Python Imports
-import os
-import json
-
-from mock.mock import patch
-from mock.mock import MagicMock
-
-from stacks.utils.RMFTestCase import experimental_mock
-patch('resource_management.libraries.functions.decorator.experimental', 
experimental_mock).start()
-
-# Module imports
-from stacks.utils.RMFTestCase import *
-from resource_management import Script, ConfigDictionary
-from resource_management.libraries.functions.default import default
-from resource_management.core.logger import Logger
-from ambari_commons.os_check import OSCheck
-from resource_management.core.environment import Environment
-import pprint
-
-
-def fake_call(command, **kwargs):
-  """
-  Instead of shell.call, call a command whose output equals the command.
-  :param command: Command that will be echoed.
-  :return: Returns a tuple of (process output code, output)
-  """
-  return (0, str(command))
-
-class TestStackSelectSetAll(RMFTestCase):
-  def get_custom_actions_dir(self):
-    return os.path.join(self.get_src_folder(), 
"test/resources/custom_actions/")
-
-  @patch.object(Logger, "info")
-  @patch.object(Logger, "error")
-  def setUp(self, error_mock, info_mock):
-
-    Logger.logger = MagicMock()
-
-    # Import the class under test. This is done here as opposed to the rest of 
the imports because the get_os_type()
-    # method needs to be patched first.
-    from stack_select_set_all import UpgradeSetAll
-    global UpgradeSetAll
-
-  def tearDown(self):
-    Logger.logger = None
-
-  @patch("os.path.exists")
-  @patch("resource_management.core.shell.call")
-  @patch.object(Script, 'get_config')
-  @patch.object(OSCheck, 'is_redhat_family')
-  def test_execution(self, family_mock, get_config_mock, call_mock, 
exists_mock):
-    # Mock the config objects
-    json_file_path = os.path.join(self.get_custom_actions_dir(), 
"ru_execute_tasks_namenode_prepare.json")
-    self.assertTrue(os.path.isfile(json_file_path))
-    
-    with open(json_file_path, "r") as json_file:
-      json_payload = json.load(json_file)
-
-    json_payload["configurations"]["cluster-env"]["stack_tools"] = 
self.get_stack_tools()
-    json_payload["configurations"]["cluster-env"]["stack_features"] = 
self.get_stack_features()
-    json_payload["upgradeSummary"] = 
TestStackSelectSetAll._get_upgrade_summary_no_downgrade()["upgradeSummary"]
-
-    config_dict = ConfigDictionary(json_payload)
-
-    def hdp_select_call(command, **kwargs):
-      # return no versions
-      if "versions" in command:
-        return (0,"2.5.9.9-9999")
-
-      return (0,command)
-
-    family_mock.return_value = True
-    get_config_mock.return_value = config_dict
-    call_mock.side_effect = hdp_select_call
-    exists_mock.return_value = True
-
-    # Ensure that the json file was actually read.
-    stack_name = default("/clusterLevelParams/stack_name", None)
-    stack_version = default("/clusterLevelParams/stack_version", None)
-    service_package_folder = default('/roleParams/service_package_folder', 
None)
-
-    self.assertEqual(stack_name, "HDP")
-    self.assertEqual(stack_version, '2.2')
-    self.assertEqual(service_package_folder, 
"common-services/HDFS/2.1.0.2.0/package")
-
-    # Begin the test
-    ru_execute = UpgradeSetAll()
-    ru_execute.actionexecute(None)
-
-    call_mock.assert_called_with(('ambari-python-wrap', '/usr/bin/hdp-select', 
'set', 'all', u'2.5.9.9-9999'), sudo=True)
-
-
-  @patch("os.path.exists")
-  @patch("resource_management.core.shell.call")
-  @patch.object(Script, 'get_config')
-  @patch.object(OSCheck, 'is_redhat_family')
-  def test_skippable_hosts(self, family_mock, get_config_mock, call_mock, 
exists_mock):
-    """
-    Tests that hosts are skippable if they don't have stack components 
installed
-    :return:
-    """
-    # Mock the config objects
-    json_file_path = os.path.join(self.get_custom_actions_dir(),
-      "ru_execute_tasks_namenode_prepare.json")
-    self.assertTrue(os.path.isfile(json_file_path))
-
-    with open(json_file_path, "r") as json_file:
-      json_payload = json.load(json_file)
-
-    json_payload["configurations"]["cluster-env"]["stack_tools"] = 
self.get_stack_tools()
-    json_payload["configurations"]["cluster-env"]["stack_features"] = 
self.get_stack_features()
-    json_payload["upgradeSummary"] = 
TestStackSelectSetAll._get_upgrade_summary_no_downgrade()["upgradeSummary"]
-
-    config_dict = ConfigDictionary(json_payload)
-
-    family_mock.return_value = False
-    get_config_mock.return_value = config_dict
-    exists_mock.return_value = True
-
-    def hdp_select_call(command, **kwargs):
-      # return no versions
-      if "versions" in command:
-        return (0,"")
-
-      return (0,command)
-
-    call_mock.side_effect = hdp_select_call
-
-    # Ensure that the json file was actually read.
-    stack_name = default("/clusterLevelParams/stack_name", None)
-    stack_version = default("/clusterLevelParams/stack_version", None)
-    service_package_folder = default('/roleParams/service_package_folder', 
None)
-
-    self.assertEqual(stack_name, "HDP")
-    self.assertEqual(stack_version, '2.2')
-    self.assertEqual(service_package_folder, 
"common-services/HDFS/2.1.0.2.0/package")
-
-    # Begin the test
-    ru_execute = UpgradeSetAll()
-    ru_execute.actionexecute(None)
-
-    call_mock.assert_called_with(('ambari-python-wrap', 
u'/usr/bin/hdp-select', 'versions'), sudo = True)
-    self.assertEqual(call_mock.call_count, 1)
-
-  @patch("os.path.exists")
-  @patch("resource_management.core.shell.call")
-  @patch.object(Script, 'get_config')
-  @patch.object(OSCheck, 'is_redhat_family')
-  def test_skippable_by_list(self, family_mock, get_config_mock, call_mock, 
exists_mock):
-    """
-    Tests that hosts are skippable if they don't have stack components 
installed
-    :return:
-    """
-    # Mock the config objects
-    json_file_path = os.path.join(self.get_custom_actions_dir(),
-      "ru_execute_tasks_namenode_prepare.json")
-    self.assertTrue(os.path.isfile(json_file_path))
-
-    with open(json_file_path, "r") as json_file:
-      json_payload = json.load(json_file)
-
-    json_payload["configurations"]["cluster-env"]["stack_tools"] = 
self.get_stack_tools()
-    json_payload["configurations"]["cluster-env"]["stack_features"] = 
self.get_stack_features()
-    json_payload["upgradeSummary"] = 
TestStackSelectSetAll._get_upgrade_summary_no_downgrade()["upgradeSummary"]
-
-    config_dict = ConfigDictionary(json_payload)
-
-    family_mock.return_value = False
-    get_config_mock.return_value = config_dict
-    exists_mock.return_value = True
-
-    def hdp_select_call(command, **kwargs):
-      # return no versions
-      if "versions" in command:
-        return (0,"2.6.7-123")
-
-      return (0,command)
-
-    call_mock.side_effect = hdp_select_call
-
-    # Ensure that the json file was actually read.
-    stack_name = default("/clusterLevelParams/stack_name", None)
-    stack_version = default("/clusterLevelParams/stack_version", None)
-    service_package_folder = default('/roleParams/service_package_folder', 
None)
-
-    self.assertEqual(stack_name, "HDP")
-    self.assertEqual(stack_version, '2.2')
-    self.assertEqual(service_package_folder, 
"common-services/HDFS/2.1.0.2.0/package")
-
-    # Begin the test
-    ru_execute = UpgradeSetAll()
-    ru_execute.actionexecute(None)
-
-    call_mock.assert_called_with(('ambari-python-wrap', 
u'/usr/bin/hdp-select', 'versions'), sudo = True)
-    self.assertEqual(call_mock.call_count, 1)
-
-  @patch("os.path.exists")
-  @patch("resource_management.core.shell.call")
-  @patch.object(Script, 'get_config')
-  @patch.object(OSCheck, 'is_redhat_family')
-  def test_execution_with_downgrade_allowed(self, family_mock, 
get_config_mock, call_mock, exists_mock):
-    # Mock the config objects
-    json_file_path = os.path.join(self.get_custom_actions_dir(), 
"ru_execute_tasks_namenode_prepare.json")
-    self.assertTrue(os.path.isfile(json_file_path))
-
-    with open(json_file_path, "r") as json_file:
-      json_payload = json.load(json_file)
-
-    json_payload["configurations"]["cluster-env"]["stack_tools"] = 
self.get_stack_tools()
-    json_payload["configurations"]["cluster-env"]["stack_features"] = 
self.get_stack_features()
-    json_payload["upgradeSummary"] = 
TestStackSelectSetAll._get_upgrade_summary_downgrade_allowed()["upgradeSummary"]
-
-    config_dict = ConfigDictionary(json_payload)
-
-    family_mock.return_value = True
-    get_config_mock.return_value = config_dict
-    call_mock.side_effect = fake_call  # echo the command
-    exists_mock.return_value = True
-
-    # Ensure that the json file was actually read.
-    stack_name = default("/clusterLevelParams/stack_name", None)
-    stack_version = default("/clusterLevelParams/stack_version", None)
-    service_package_folder = default('/roleParams/service_package_folder', 
None)
-
-    self.assertEqual(stack_name, "HDP")
-    self.assertEqual(stack_version, '2.2')
-    self.assertEqual(service_package_folder, 
"common-services/HDFS/2.1.0.2.0/package")
-
-    # Begin the test
-    ru_execute = UpgradeSetAll()
-    ru_execute.actionexecute(None)
-
-    call_mock.assert_not_called()
-
-
-  @patch("os.path.exists")
-  @patch("resource_management.core.shell.call")
-  @patch.object(Script, 'get_config')
-  @patch.object(OSCheck, 'is_redhat_family')
-  def test_execution_with_patch_upgrade(self, family_mock, get_config_mock, 
call_mock, exists_mock):
-    # Mock the config objects
-    json_file_path = os.path.join(self.get_custom_actions_dir(), 
"ru_execute_tasks_namenode_prepare.json")
-    self.assertTrue(os.path.isfile(json_file_path))
-
-    with open(json_file_path, "r") as json_file:
-      json_payload = json.load(json_file)
-
-    json_payload["configurations"]["cluster-env"]["stack_tools"] = 
self.get_stack_tools()
-    json_payload["configurations"]["cluster-env"]["stack_features"] = 
self.get_stack_features()
-    json_payload["upgradeSummary"] = 
TestStackSelectSetAll._get_upgrade_summary_patch_upgrade()["upgradeSummary"]
-
-    config_dict = ConfigDictionary(json_payload)
-
-    family_mock.return_value = True
-    get_config_mock.return_value = config_dict
-    call_mock.side_effect = fake_call  # echo the command
-    exists_mock.return_value = True
-
-    # Ensure that the json file was actually read.
-    stack_name = default("/clusterLevelParams/stack_name", None)
-    stack_version = default("/clusterLevelParams/stack_version", None)
-    service_package_folder = default('/roleParams/service_package_folder', 
None)
-
-    self.assertEqual(stack_name, "HDP")
-    self.assertEqual(stack_version, '2.2')
-    self.assertEqual(service_package_folder, 
"common-services/HDFS/2.1.0.2.0/package")
-
-    # Begin the test
-    ru_execute = UpgradeSetAll()
-    ru_execute.actionexecute(None)
-
-    call_mock.assert_not_called()
-
-
-  @staticmethod
-  def _get_upgrade_summary_no_downgrade():
-    """
-    A STANDARD UPGRADE that cannot be downgraded
-    :return:
-    """
-    return {
-      "upgradeSummary": {
-        "services":{
-          "HDFS":{
-            "sourceRepositoryId":1,
-            "sourceStackId":"HDP-2.4",
-            "sourceVersion":"2.4.0.0-1234",
-            "targetRepositoryId":2,
-            "targetStackId":"HDP-2.5",
-            "targetVersion":"2.5.9.9-9999"
-          }
-        },
-        "direction":"UPGRADE",
-        "type":"rolling_upgrade",
-        "isRevert":False,
-        "orchestration":"STANDARD",
-        "associatedStack": "HDP-2.5",
-        "associatedVersion":"2.5.9.9-9999",
-        "isDowngradeAllowed": False,
-        "isSwitchBits": False
-      }
-    }
-
-  @staticmethod
-  def _get_upgrade_summary_downgrade_allowed():
-    """
-    A STANDARD UPGRADE that can be downgraded
-    :return:
-    """
-    upgrade_summary = TestStackSelectSetAll._get_upgrade_summary_no_downgrade()
-    upgrade_summary["upgradeSummary"]["isDowngradeAllowed"] = True
-    return upgrade_summary
-
-
-  @staticmethod
-  def _get_upgrade_summary_patch_upgrade():
-    """
-    A STANDARD UPGRADE that can be downgraded
-    :return:
-    """
-    upgrade_summary = TestStackSelectSetAll._get_upgrade_summary_no_downgrade()
-    upgrade_summary["upgradeSummary"]["orchestration"] = "PATCH"
-    return upgrade_summary
\ No newline at end of file

Reply via email to