AMBARI-22105 - Upgrades Do Not Finalize If Other Host Versions Are Out of Sync (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6d51e01f Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6d51e01f Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6d51e01f Branch: refs/heads/branch-feature-AMBARI-20859 Commit: 6d51e01f48d5a588c41b47a15c88fe100d2dbf58 Parents: 6062014 Author: Jonathan Hurley <[email protected]> Authored: Sun Oct 1 19:41:50 2017 -0400 Committer: Jonathan Hurley <[email protected]> Committed: Mon Oct 2 14:56:12 2017 -0400 ---------------------------------------------------------------------- .../upgrade/HostVersionOutOfSyncListener.java | 4 + .../orm/entities/RepositoryVersionEntity.java | 34 ++--- .../org/apache/ambari/server/state/Host.java | 17 +++ .../ambari/server/state/host/HostImpl.java | 43 +++++++ .../svccomphost/ServiceComponentHostImpl.java | 9 +- .../ServiceComponentHostSummary.java | 123 ------------------- .../upgrade/StackVersionListenerTest.java | 1 - .../apache/ambari/server/orm/OrmTestHelper.java | 2 +- .../svccomphost/ServiceComponentHostTest.java | 102 ++++++++++++++- 9 files changed, 185 insertions(+), 150 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/6d51e01f/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java index d4c79db..0be036e 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListener.java @@ -301,6 +301,10 @@ public class HostVersionOutOfSyncListener { missingHostVersion.getRepositoryVersion().getVersion(), missingHostVersion.getRepositoryVersion().getId()); hostVersionDAO.get().create(missingHostVersion); + hostDAO.get().merge(hostEntity); + + hostEntity.getHostVersionEntities().add(missingHostVersion); + hostEntity = hostDAO.get().merge(hostEntity); } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/6d51e01f/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java index 2b56b11..b4f59dc 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java @@ -52,7 +52,6 @@ import org.apache.ambari.server.state.repository.Release; import org.apache.ambari.server.state.repository.VersionDefinitionXml; import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.builder.EqualsBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -378,26 +377,31 @@ public class RepositoryVersionEntity { * {@inheritDoc} */ @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - RepositoryVersionEntity that = (RepositoryVersionEntity) o; - return new EqualsBuilder().append(id, that.id).append(stack, that.stack).append(version, - that.version).append(displayName, that.displayName).isEquals(); + public int hashCode() { + return java.util.Objects.hash(stack, version, displayName, operatingSystems); } /** * {@inheritDoc} */ @Override - public int hashCode() { - return Objects.hashCode(id, stack, version, displayName); + public boolean equals(Object object) { + if (null == object) { + return false; + } + + if (this == object) { + return true; + } + + if (object.getClass() != getClass()) { + return false; + } + + RepositoryVersionEntity that = (RepositoryVersionEntity) object; + return Objects.equal(stack, that.stack) && Objects.equal(version, that.version) + && Objects.equal(displayName, that.displayName) + && Objects.equal(operatingSystems, that.operatingSystems); } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/6d51e01f/ambari-server/src/main/java/org/apache/ambari/server/state/Host.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Host.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Host.java index 7f0be86..3a78824 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/Host.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Host.java @@ -29,6 +29,7 @@ import org.apache.ambari.server.agent.RecoveryReport; import org.apache.ambari.server.controller.HostResponse; import org.apache.ambari.server.orm.entities.HostEntity; import org.apache.ambari.server.orm.entities.HostVersionEntity; +import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; import org.apache.ambari.server.state.fsm.InvalidStateTransitionException; public interface Host extends Comparable { @@ -407,4 +408,20 @@ public interface Host extends Comparable { * @see ComponentInfo#isVersionAdvertised() */ boolean hasComponentsAdvertisingVersions(StackId stackId) throws AmbariException; + + /** + * Gets whether all host components whose desired repository version matches + * the repository version specified have reported the correct version and are + * no longer upgrading. + * + * @param repositoryVersion + * the repository version to check for (not {@code null}). + * @return {@code true} if all components on this host have checked in with + * the correct version if their desired repository matches the one + * specified. + * + * @throws AmbariException + */ + boolean isRepositoryVersionCorrect(RepositoryVersionEntity repositoryVersion) + throws AmbariException; } http://git-wip-us.apache.org/repos/asf/ambari/blob/6d51e01f/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java index 274a425..4af83ef 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java @@ -18,6 +18,7 @@ package org.apache.ambari.server.state.host; import java.lang.reflect.Type; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -50,6 +51,8 @@ import org.apache.ambari.server.orm.entities.HostComponentStateEntity; import org.apache.ambari.server.orm.entities.HostEntity; import org.apache.ambari.server.orm.entities.HostStateEntity; import org.apache.ambari.server.orm.entities.HostVersionEntity; +import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; +import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity; import org.apache.ambari.server.state.AgentVersion; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; @@ -65,6 +68,7 @@ import org.apache.ambari.server.state.HostHealthStatus.HealthStatus; import org.apache.ambari.server.state.HostState; import org.apache.ambari.server.state.MaintenanceState; import org.apache.ambari.server.state.StackId; +import org.apache.ambari.server.state.UpgradeState; import org.apache.ambari.server.state.configgroup.ConfigGroup; import org.apache.ambari.server.state.fsm.InvalidStateTransitionException; import org.apache.ambari.server.state.fsm.SingleArcTransition; @@ -1168,6 +1172,45 @@ public class HostImpl implements Host { return false; } + + /** + * {@inheritDoc} + */ + @Override + public boolean isRepositoryVersionCorrect(RepositoryVersionEntity repositoryVersion) + throws AmbariException { + HostEntity hostEntity = getHostEntity(); + Collection<HostComponentStateEntity> hostComponentStates = hostEntity.getHostComponentStateEntities(); + + // for every host component, if it matches the desired repo and has reported + // the correct version then we're good + for (HostComponentStateEntity hostComponentState : hostComponentStates) { + ServiceComponentDesiredStateEntity desiredComponmentState = hostComponentState.getServiceComponentDesiredStateEntity(); + RepositoryVersionEntity desiredRepositoryVersion = desiredComponmentState.getDesiredRepositoryVersion(); + + ComponentInfo componentInfo = ambariMetaInfo.getComponent( + desiredRepositoryVersion.getStackName(), desiredRepositoryVersion.getStackVersion(), + hostComponentState.getServiceName(), hostComponentState.getComponentName()); + + // skip components which don't advertise a version + if (!componentInfo.isVersionAdvertised()) { + continue; + } + + // we only care about checking the specified repo version for this host + if (!repositoryVersion.equals(desiredRepositoryVersion)) { + continue; + } + + String versionAdvertised = hostComponentState.getVersion(); + if (hostComponentState.getUpgradeState() == UpgradeState.IN_PROGRESS + || !StringUtils.equals(versionAdvertised, repositoryVersion.getVersion())) { + return false; + } + } + + return true; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/6d51e01f/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java ---------------------------------------------------------------------- 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 230b031..f490ff0 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 @@ -1440,8 +1440,8 @@ public class ServiceComponentHostImpl implements ServiceComponentHost { @Override @Transactional public HostVersionEntity recalculateHostVersionState() throws AmbariException { - RepositoryVersionEntity repositoryVersion = serviceComponent.getDesiredRepositoryVersion(); HostEntity hostEntity = host.getHostEntity(); + RepositoryVersionEntity repositoryVersion = serviceComponent.getDesiredRepositoryVersion(); HostVersionEntity hostVersionEntity = hostVersionDAO.findHostVersionByHostAndRepository( hostEntity, repositoryVersion); @@ -1462,11 +1462,8 @@ public class ServiceComponentHostImpl implements ServiceComponentHost { hostVersionDAO.create(hostVersionEntity); } - final ServiceComponentHostSummary hostSummary = new ServiceComponentHostSummary( - ambariMetaInfo, hostEntity, repositoryVersion); - - if (hostSummary.isVersionCorrectForAllHosts(repositoryVersion)) { - if (hostVersionEntity.getState() != RepositoryVersionState.CURRENT) { + if (hostVersionEntity.getState() != RepositoryVersionState.CURRENT) { + if (host.isRepositoryVersionCorrect(repositoryVersion)) { hostVersionEntity.setState(RepositoryVersionState.CURRENT); hostVersionEntity = hostVersionDAO.merge(hostVersionEntity); } http://git-wip-us.apache.org/repos/asf/ambari/blob/6d51e01f/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostSummary.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostSummary.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostSummary.java deleted file mode 100644 index e9359ef..0000000 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostSummary.java +++ /dev/null @@ -1,123 +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.svccomphost; - - -import java.util.Collection; -import java.util.HashSet; - -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.RepositoryVersionEntity; -import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity; -import org.apache.ambari.server.state.ComponentInfo; -import org.apache.ambari.server.state.State; -import org.apache.ambari.server.state.UpgradeState; -import org.apache.commons.lang.StringUtils; - - -/** - * 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; - - /** - * Constructor. - * - * @param ambariMetaInfo - * used to lookup whether a component advertises a version (not - * {@code null}). - * @param host - * the host to generate a component summary for (not {@code null}). - * @param repositoryVersion - * the repository to generate a summary for (not {@code null}). - * @throws AmbariException - */ - public ServiceComponentHostSummary(AmbariMetaInfo ambariMetaInfo, HostEntity host, - RepositoryVersionEntity repositoryVersion) throws AmbariException { - allHostComponents = host.getHostComponentStateEntities(); - haveAdvertisedVersion = new HashSet<>(); - waitingToAdvertiseVersion = new HashSet<>(); - noVersionToAdvertise = new HashSet<>(); - - String stackName = repositoryVersion.getStackName(); - String stackVersion = repositoryVersion.getStackVersion(); - - 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); - continue; - } - - String versionAdvertised = hostComponentStateEntity.getVersion(); - if (hostComponentStateEntity.getUpgradeState() == UpgradeState.IN_PROGRESS - || StringUtils.equals(versionAdvertised, State.UNKNOWN.name())) { - waitingToAdvertiseVersion.add(hostComponentStateEntity); - continue; - } - - haveAdvertisedVersion.add(hostComponentStateEntity); - } - } - - /** - * Gets whether all hosts for a service component have reported the correct - * version. - * - * @param repositoryVersion - * the version to report (not {@code null}). - * @return {@code true} if all hosts for this service component have reported - * the correct version, {@code false} othwerise. - */ - public boolean isVersionCorrectForAllHosts(RepositoryVersionEntity repositoryVersion) { - if (!waitingToAdvertiseVersion.isEmpty()) { - return false; - } - - for (HostComponentStateEntity hostComponent : haveAdvertisedVersion) { - if (UpgradeState.VERSION_NON_ADVERTISED_STATES.contains(hostComponent.getUpgradeState())) { - return false; - } - - ServiceComponentDesiredStateEntity desiredState = hostComponent.getServiceComponentDesiredStateEntity(); - RepositoryVersionEntity desiredRepositoryVersion = desiredState.getDesiredRepositoryVersion(); - if (!desiredRepositoryVersion.equals(repositoryVersion)) { - continue; - } - - if (!StringUtils.equals(hostComponent.getVersion(), desiredRepositoryVersion.getVersion())) { - return false; - } - } - - return true; - } -} http://git-wip-us.apache.org/repos/asf/ambari/blob/6d51e01f/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListenerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListenerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListenerTest.java index 5e12cdf..7387867 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListenerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/StackVersionListenerTest.java @@ -62,7 +62,6 @@ public class StackVersionListenerTest extends EasyMockSupport { private static final Long CLUSTER_ID = 1L; private static final String UNKNOWN_VERSION = "UNKNOWN"; private static final String VALID_PREVIOUS_VERSION = "2.2.0.0"; - private static final RepositoryVersionEntity DUMMY_REPOSITORY_VERSION_ENTITY = new RepositoryVersionEntity(); private static final HostVersionEntity DUMMY_HOST_VERSION_ENTITY = new HostVersionEntity(); private static final UpgradeEntity DUMMY_UPGRADE_ENTITY = new UpgradeEntity(); public static final String STACK_NAME = "HDP"; http://git-wip-us.apache.org/repos/asf/ambari/blob/6d51e01f/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java index 2c6c096..bd8be3b 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java @@ -674,7 +674,7 @@ public class OrmTestHelper { String.valueOf(System.currentTimeMillis()) + uniqueCounter.incrementAndGet(), ""); } catch (Exception ex) { LOG.error("Caught exception", ex); - ex.printStackTrace(); + Assert.fail(MessageFormat.format("Unable to create Repo Version for Stack {0} and version {1}", stackEntity.getStackName() + "-" + stackEntity.getStackVersion(), version)); } http://git-wip-us.apache.org/repos/asf/ambari/blob/6d51e01f/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java index a989738..48864cc 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java @@ -20,6 +20,7 @@ package org.apache.ambari.server.state.svccomphost; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -41,7 +42,9 @@ import org.apache.ambari.server.orm.dao.HostComponentStateDAO; import org.apache.ambari.server.orm.dao.HostDAO; import org.apache.ambari.server.orm.entities.ClusterEntity; import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity; +import org.apache.ambari.server.orm.entities.HostComponentStateEntity; import org.apache.ambari.server.orm.entities.HostEntity; +import org.apache.ambari.server.orm.entities.HostVersionEntity; import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; @@ -50,6 +53,7 @@ import org.apache.ambari.server.state.ConfigFactory; import org.apache.ambari.server.state.Host; import org.apache.ambari.server.state.HostConfig; import org.apache.ambari.server.state.MaintenanceState; +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.ServiceComponentFactory; @@ -60,9 +64,12 @@ import org.apache.ambari.server.state.ServiceComponentHostFactory; import org.apache.ambari.server.state.ServiceFactory; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.State; +import org.apache.ambari.server.state.UpgradeState; import org.apache.ambari.server.state.configgroup.ConfigGroup; import org.apache.ambari.server.state.configgroup.ConfigGroupFactory; import org.apache.ambari.server.state.fsm.InvalidStateTransitionException; +import org.apache.ambari.server.utils.EventBusSynchronizer; +import org.apache.commons.lang3.StringUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -114,16 +121,19 @@ public class ServiceComponentHostTest { injector.getInstance(GuiceJpaInitializer.class); injector.injectMembers(this); + EventBusSynchronizer.synchronizeAmbariEventPublisher(injector); + StackId stackId = new StackId("HDP-2.0.6"); createCluster(stackId, clusterName); + + repositoryVersion = helper.getOrCreateRepositoryVersion(stackId, stackId.getStackVersion()); + hostAttributes.put("os_family", "redhat"); hostAttributes.put("os_release_version", "5.9"); - Set<String> hostNames = new HashSet<>(); hostNames.add(hostName1); - addHostsToCluster(clusterName, hostAttributes, hostNames); - repositoryVersion = helper.getOrCreateRepositoryVersion(stackId, stackId.getStackVersion()); + addHostsToCluster(clusterName, hostAttributes, hostNames); } @After @@ -1050,4 +1060,88 @@ public class ServiceComponentHostTest { ); Assert.assertEquals(MaintenanceState.ON, entity.getMaintenanceState()); } -} + + /** + * Tests that the host version for a repository can transition properly to + * CURRENT even if other components on that host have not reported in correct + * for their own repo versions. This assures that the host version logic is + * scoped to the repo that is transitioning and is not affected by other + * components. + * + * @throws Exception + */ + @Test + public void testHostVersionTransitionIsScopedByRepository() throws Exception { + // put the existing host versions OUT_OF_SYNC + HostEntity hostEntity = hostDAO.findByName(hostName1); + Collection<HostVersionEntity> hostVersions = hostEntity.getHostVersionEntities(); + Assert.assertEquals(1, hostVersions.size()); + hostVersions.iterator().next().setState(RepositoryVersionState.OUT_OF_SYNC); + hostDAO.merge(hostEntity); + + ServiceComponentHost namenode = createNewServiceComponentHost(clusterName, "HDFS", "NAMENODE", hostName1, false); + namenode.setDesiredState(State.STARTED); + namenode.setState(State.STARTED); + + ServiceComponentHost datanode = createNewServiceComponentHost(clusterName, "HDFS", "DATANODE", hostName1, false); + datanode.setDesiredState(State.STARTED); + datanode.setState(State.STARTED); + + ServiceComponentHost zkServer = createNewServiceComponentHost(clusterName, "ZOOKEEPER", "ZOOKEEPER_SERVER", hostName1, false); + zkServer.setDesiredState(State.STARTED); + zkServer.setState(State.STARTED); + + ServiceComponentHost zkClient = createNewServiceComponentHost(clusterName, "ZOOKEEPER", "ZOOKEEPER_CLIENT", hostName1, true); + zkClient.setDesiredState(State.STARTED); + zkClient.setState(State.STARTED); + + // put some host components into a bad state + hostEntity = hostDAO.findByName(hostName1); + Collection<HostComponentStateEntity> hostComponentStates = hostEntity.getHostComponentStateEntities(); + for( HostComponentStateEntity hostComponentState : hostComponentStates ) { + if( StringUtils.equals("HDFS", hostComponentState.getServiceName() ) ) { + hostComponentState.setVersion(State.UNKNOWN.name()); + hostComponentStateDAO.merge(hostComponentState); + } + } + + // create the repo just for ZK + StackId stackId = new StackId("HDP-2.2.0"); + RepositoryVersionEntity patchRepositoryVersion = helper.getOrCreateRepositoryVersion(stackId, "2.2.0.0-1"); + + // create the new host version + zkServer.getServiceComponent().setDesiredRepositoryVersion(patchRepositoryVersion); + zkClient.getServiceComponent().setDesiredRepositoryVersion(patchRepositoryVersion); + + helper.createHostVersion(hostName1, patchRepositoryVersion, RepositoryVersionState.INSTALLED); + + //Â move ZK components to UPGRADED and reporting the new version + hostEntity = hostDAO.findByName(hostName1); + hostComponentStates = hostEntity.getHostComponentStateEntities(); + for( HostComponentStateEntity hostComponentState : hostComponentStates ) { + if( StringUtils.equals("ZOOKEEPER", hostComponentState.getServiceName() ) ) { + hostComponentState.setVersion(patchRepositoryVersion.getVersion()); + hostComponentState.setUpgradeState(UpgradeState.COMPLETE); + hostComponentStateDAO.merge(hostComponentState); + } + } + + hostEntity = hostDAO.merge(hostEntity); + + zkServer.recalculateHostVersionState(); + + // very transition to CURRENT + hostVersions = hostEntity.getHostVersionEntities(); + Assert.assertEquals(2, hostVersions.size()); + + for (HostVersionEntity hostVersion : hostVersions) { + if (hostVersion.getRepositoryVersion().equals(repositoryVersion)) { + Assert.assertEquals(RepositoryVersionState.OUT_OF_SYNC, hostVersion.getState()); + } else if (hostVersion.getRepositoryVersion().equals(patchRepositoryVersion)) { + Assert.assertEquals(RepositoryVersionState.CURRENT, hostVersion.getState()); + } else { + Assert.fail("Unexpected repository version"); + } + } + } +} \ No newline at end of file
