/** * 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.svccomphost; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.orm.entities.HostComponentStateEntity; import org.apache.ambari.server.orm.entities.HostEntity; import org.apache.ambari.server.orm.entities.UpgradeEntity; import org.apache.ambari.server.state.ComponentInfo; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.State; import org.apache.ambari.server.state.UpgradeState; /** * Represents a summary of the versions of the components installed on a host. */ public class ServiceComponentHostSummary { private Collection<HostComponentStateEntity> allHostComponents; private Collection<HostComponentStateEntity> haveAdvertisedVersion; private Collection<HostComponentStateEntity> waitingToAdvertiseVersion; private Collection<HostComponentStateEntity> noVersionToAdvertise; private Set<String> versions; public ServiceComponentHostSummary(AmbariMetaInfo ambariMetaInfo, HostEntity host, String stackName, String stackVersion) throws AmbariException { allHostComponents = host.getHostComponentStateEntities(); haveAdvertisedVersion = new HashSet<>(); waitingToAdvertiseVersion = new HashSet<>(); noVersionToAdvertise = new HashSet<>(); versions = new HashSet<>(); for (HostComponentStateEntity hostComponentStateEntity : allHostComponents) { ComponentInfo compInfo = ambariMetaInfo.getComponent( stackName, stackVersion, hostComponentStateEntity.getServiceName(), hostComponentStateEntity.getComponentName()); if (!compInfo.isVersionAdvertised()) { // Some Components cannot advertise a version. E.g., ZKF, AMBARI_METRICS, Kerberos noVersionToAdvertise.add(hostComponentStateEntity); } else { if (hostComponentStateEntity.getUpgradeState().equals(UpgradeState.IN_PROGRESS) || hostComponentStateEntity.getVersion().equalsIgnoreCase(State.UNKNOWN.toString())) { waitingToAdvertiseVersion.add(hostComponentStateEntity); } else { haveAdvertisedVersion.add(hostComponentStateEntity); versions.add(hostComponentStateEntity.getVersion()); } // TODO: what if component reported wrong version? } } } public ServiceComponentHostSummary(AmbariMetaInfo ambariMetaInfo, HostEntity host, StackId stackId) throws AmbariException { this(ambariMetaInfo, host, stackId.getStackName(), stackId.getStackVersion()); } public Collection<HostComponentStateEntity> getHaveAdvertisedVersion() { return haveAdvertisedVersion; } public boolean isUpgradeFinished() { return haveAllComponentsFinishedAdvertisingVersion() && noComponentVersionMismatches(getHaveAdvertisedVersion()); } /** * @param upgradeEntity Upgrade info about update on given host * @return Return true if multiple component versions are found for this host, or if it does not coincide with the * CURRENT repo version. */ public boolean isUpgradeInProgress(UpgradeEntity upgradeEntity) { // Exactly one CURRENT version must exist // We can only detect an upgrade if the Host has at least one component that advertises a version and has done so already // If distinct versions have been advertises, then an upgrade is in progress. // If exactly one version has been advertises, but it doesn't coincide with the CURRENT HostVersion, then an upgrade is in progress. return upgradeEntity != null; } /** * Determine if all of the components on that need to advertise a version have finished doing so. * @return Return a bool indicating if all components that can report a version have done so. */ public boolean haveAllComponentsFinishedAdvertisingVersion() { return waitingToAdvertiseVersion.isEmpty(); } /** * Checks that every component has really advertised version (in other words, we are not waiting * for version advertising), and that no version mismatch occurred * * @param hostComponents host components * @return true if components have advertised the same version, or collection is empty, false otherwise. */ public static boolean noComponentVersionMismatches(Collection<HostComponentStateEntity> hostComponents) { for (HostComponentStateEntity hostComponent : hostComponents) { if (UpgradeState.VERSION_NON_ADVERTISED_STATES.contains(hostComponent.getUpgradeState())) { return false; } } return true; } }