package com.sequenceiq.cloudbreak.service.cluster.flow.status; import java.util.Arrays; import java.util.Collections; import javax.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import com.sequenceiq.ambari.client.AmbariClient; import com.sequenceiq.cloudbreak.api.model.Status; import com.sequenceiq.cloudbreak.client.HttpClientConfig; import com.sequenceiq.cloudbreak.core.CloudbreakSecuritySetupException; import com.sequenceiq.cloudbreak.domain.Cluster; import com.sequenceiq.cloudbreak.domain.Stack; import com.sequenceiq.cloudbreak.service.TlsSecurityService; import com.sequenceiq.cloudbreak.service.cluster.AmbariClientProvider; import com.sequenceiq.cloudbreak.service.cluster.ClusterService; import com.sequenceiq.cloudbreak.service.events.CloudbreakEventService; import com.sequenceiq.cloudbreak.service.messages.CloudbreakMessagesService; @Component public class AmbariClusterStatusUpdater { private static final Logger LOGGER = LoggerFactory.getLogger(AmbariClusterStatusUpdater.class); @Inject private ClusterService clusterService; @Inject private AmbariClientProvider ambariClientProvider; @Inject private CloudbreakEventService cloudbreakEventService; @Inject private AmbariClusterStatusFactory clusterStatusFactory; @Inject private TlsSecurityService tlsSecurityService; @Inject private CloudbreakMessagesService cloudbreakMessagesService; public void updateClusterStatus(Stack stack, Cluster cluster) throws CloudbreakSecuritySetupException { if (isStackOrClusterStatusInvalid(stack, cluster)) { String msg = cloudbreakMessagesService.getMessage(Msg.AMBARI_CLUSTER_COULD_NOT_SYNC.code(), Arrays.asList(stack.getStatus(), cluster == null ? "" : cluster.getStatus())); LOGGER.warn(msg); cloudbreakEventService.fireCloudbreakEvent(stack.getId(), stack.getStatus().name(), msg); } else if (cluster != null && cluster.getAmbariIp() != null) { Long stackId = stack.getId(); clusterService.updateClusterMetadata(stackId); String blueprintName = cluster.getBlueprint().getBlueprintName(); HttpClientConfig clientConfig = tlsSecurityService.buildTLSClientConfigForPrimaryGateway(stackId, cluster.getAmbariIp()); AmbariClient ambariClient = ambariClientProvider.getAmbariClient(clientConfig, stack.getGatewayPort(), cluster); ClusterStatus clusterStatus = clusterStatusFactory.createClusterStatus(ambariClient, blueprintName); updateClusterStatus(stackId, stack.getStatus(), cluster, clusterStatus); } } private boolean isStackOrClusterStatusInvalid(Stack stack, Cluster cluster) { return stack.isStackInDeletionPhase() || stack.isStackInStopPhase() || stack.isModificationInProgress() || cluster == null || cluster.isModificationInProgress(); } private void updateClusterStatus(Long stackId, Status stackStatus, Cluster cluster, ClusterStatus ambariClusterStatus) { Status statusInEvent = stackStatus; String statusReason = ambariClusterStatus.getStatusReason(); if (isUpdateEnabled(ambariClusterStatus)) { if (updateClusterStatus(stackId, cluster, ambariClusterStatus.getClusterStatus())) { statusInEvent = ambariClusterStatus.getStackStatus(); statusReason = ambariClusterStatus.getStatusReason(); } else { statusReason = "The cluster's state is up to date."; } } cloudbreakEventService.fireCloudbreakEvent(stackId, statusInEvent.name(), cloudbreakMessagesService.getMessage(Msg.AMBARI_CLUSTER_SYNCHRONIZED.code(), Collections.singletonList(statusReason))); } private boolean isUpdateEnabled(ClusterStatus clusterStatus) { return clusterStatus == ClusterStatus.STARTED || clusterStatus == ClusterStatus.INSTALLED; } private boolean updateClusterStatus(Long stackId, Cluster cluster, Status newClusterStatus) { boolean result = false; if (cluster.getStatus() != newClusterStatus) { LOGGER.info("Cluster {} status is updated from {} to {}", cluster.getId(), cluster.getStatus(), newClusterStatus); clusterService.updateClusterStatusByStackId(stackId, newClusterStatus); result = true; } else { LOGGER.info("Cluster {} status hasn't changed: {}", cluster.getId(), cluster.getStatus()); } return result; } private enum Msg { AMBARI_CLUSTER_COULD_NOT_SYNC("ambari.cluster.could.not.sync"), AMBARI_CLUSTER_SYNCHRONIZED("ambari.cluster.synchronized"); private String code; Msg(String msgCode) { code = msgCode; } public String code() { return code; } } }