Repository: ambari Updated Branches: refs/heads/trunk d6c389c11 -> 354998beb
AMBARI-9464. Adding new host after version distribution does not contain 2 host versions (dlysnichenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/354998be Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/354998be Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/354998be Branch: refs/heads/trunk Commit: 354998beb8cc7682b879803404f0eb9b40f11deb Parents: d6c389c Author: Lisnichenko Dmitro <dlysniche...@hortonworks.com> Authored: Wed Feb 4 11:48:29 2015 +0200 Committer: Lisnichenko Dmitro <dlysniche...@hortonworks.com> Committed: Wed Feb 4 11:49:20 2015 +0200 ---------------------------------------------------------------------- .../upgrade/HostVersionOutOfSyncListener.java | 35 ++++ .../server/orm/entities/HostVersionEntity.java | 4 + .../HostVersionOutOfSyncListenerTest.java | 167 +++++++++++++++++++ 3 files changed, 206 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/354998be/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 c2748df..f64272f 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 @@ -24,10 +24,13 @@ import com.google.inject.Singleton; import com.google.inject.persist.Transactional; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.EagerSingleton; +import org.apache.ambari.server.events.HostAddedEvent; import org.apache.ambari.server.events.ServiceComponentInstalledEvent; import org.apache.ambari.server.events.ServiceInstalledEvent; import org.apache.ambari.server.events.publishers.AmbariEventPublisher; +import org.apache.ambari.server.orm.dao.HostDAO; import org.apache.ambari.server.orm.dao.HostVersionDAO; +import org.apache.ambari.server.orm.entities.ClusterVersionEntity; import org.apache.ambari.server.orm.entities.HostVersionEntity; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; @@ -36,6 +39,7 @@ import org.apache.ambari.server.state.StackId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -60,6 +64,9 @@ public class HostVersionOutOfSyncListener { private Provider<HostVersionDAO> hostVersionDAO; @Inject + private Provider<HostDAO> hostDAO; + + @Inject private Provider<Clusters> clusters; private AmbariEventPublisher ambariEventPublisher; @@ -123,4 +130,32 @@ public class HostVersionOutOfSyncListener { LOG.error("Can not update hosts about out of sync", e); } } + + @Subscribe + @Transactional + public void onHostEvent(HostAddedEvent event) { + if (LOG.isDebugEnabled()) { + LOG.debug(event.toString()); + } + try { + Cluster cluster = clusters.get().getClusterById(event.getClusterId()); + Set<String> changedRepositoryVersions = new HashSet<String>(); + Collection<ClusterVersionEntity> allClusterVersions = cluster.getAllClusterVersions(); + for (ClusterVersionEntity clusterVersion : allClusterVersions) { + if (clusterVersion.getState() != RepositoryVersionState.CURRENT) { // Current version is taken care of automatically + String hostName = event.getHostName(); + HostVersionEntity missingHostVersion = new HostVersionEntity(hostName, + clusterVersion.getRepositoryVersion(), RepositoryVersionState.OUT_OF_SYNC); + missingHostVersion.setHostEntity(hostDAO.get().findByName(hostName)); + hostVersionDAO.get().create(missingHostVersion); + changedRepositoryVersions.add(clusterVersion.getRepositoryVersion().getVersion()); + } + } + for (String version : changedRepositoryVersions) { + cluster.recalculateClusterVersionState(version); + } + } catch (AmbariException e) { + LOG.error("Can not update hosts about out of sync", e); + } + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/354998be/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java index 4d8f3be..1427b4b 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostVersionEntity.java @@ -92,6 +92,10 @@ public class HostVersionEntity { public HostVersionEntity() { } + /** + * When using this constructor, you should also call setHostEntity(). Otherwise + * you will have persistence errors when persisting the instance. + */ public HostVersionEntity(String hostName, RepositoryVersionEntity repositoryVersion, RepositoryVersionState state) { this.hostName = hostName; this.repositoryVersion = repositoryVersion; http://git-wip-us.apache.org/repos/asf/ambari/blob/354998be/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java new file mode 100644 index 0000000..632a2b8 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java @@ -0,0 +1,167 @@ +/** + * 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.events.listeners.upgrade; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.RollbackException; + +import com.google.inject.AbstractModule; +import com.google.inject.Singleton; +import com.google.inject.persist.Transactional; +import com.google.inject.util.Modules; + +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.api.services.AmbariMetaInfo; +import org.apache.ambari.server.events.HostAddedEvent; +import org.apache.ambari.server.orm.GuiceJpaInitializer; +import org.apache.ambari.server.orm.InMemoryDefaultTestModule; +import org.apache.ambari.server.orm.OrmTestHelper; +import org.apache.ambari.server.orm.dao.HostVersionDAO; +import org.apache.ambari.server.orm.entities.ClusterVersionEntity; +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.RepositoryVersionState; +import org.apache.ambari.server.state.Clusters; +import org.apache.ambari.server.state.Host; +import org.apache.ambari.server.state.HostState; +import org.apache.ambari.server.state.StackId; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.persist.PersistService; + +public class HostVersionOutOfSyncListenerTest { + private static final Logger LOG = LoggerFactory.getLogger(HostVersionOutOfSyncListenerTest.class); + + private Clusters clusters; + private Cluster c1; + private Injector injector; + private OrmTestHelper helper; + private HostVersionDAO hostVersionDAO; + private AmbariMetaInfo metaInfo; + + + @Before + public void setup() throws Exception { + injector = Guice.createInjector(new InMemoryDefaultTestModule()); + injector.getInstance(GuiceJpaInitializer.class); + clusters = injector.getInstance(Clusters.class); + metaInfo = injector.getInstance(AmbariMetaInfo.class); + helper = injector.getInstance(OrmTestHelper.class); + hostVersionDAO = injector.getInstance(HostVersionDAO.class); + metaInfo.init(); + clusters.addCluster("c1"); + c1 = clusters.getCluster("c1"); + addHost("h1"); + + StackId stackId = new StackId("HDP-0.1"); + c1.setDesiredStackVersion(stackId); + helper.getOrCreateRepositoryVersion(stackId.getStackName(), stackId.getStackVersion()); + c1.createClusterVersion(stackId.getStackName(), stackId.getStackVersion(), "admin", RepositoryVersionState.UPGRADING); + c1.transitionClusterVersion(stackId.getStackName(), stackId.getStackVersion(), RepositoryVersionState.CURRENT); + clusters.mapHostToCluster("h1", "c1"); + } + + @After + public void teardown() { + injector.getInstance(PersistService.class).stop(); + } + + /** + * When a host is added to a cluster that has non-CURRENT cluster_version records, + * then Ambari needs to insert host_verion record for each one of + * those stack versions with a state of OUT_OF_SYNC + */ + @Test + public void testOnHostEvent() throws AmbariException { + // Configuring single-node cluster with 2 repo versions + Host h1 = clusters.getHost("h1"); + h1.setState(HostState.HEALTHY); + + StackId stackId = new StackId("HDP-0.1"); + RepositoryVersionEntity repositoryVersionEntity = helper.getOrCreateRepositoryVersion(stackId.getStackId(), + "1.0-1000"); + c1.createClusterVersion(stackId.getStackId(), "1.0-1000", "admin", RepositoryVersionState.INSTALLING); + c1.setCurrentStackVersion(stackId); + c1.recalculateAllClusterVersionStates(); + checkStackVersionState(stackId.getStackId(), "1.0-1000", RepositoryVersionState.INSTALLING); + checkStackVersionState(stackId.getStackId(), "1.0-2086", RepositoryVersionState.CURRENT); + + HostVersionEntity hv1 = helper.createHostVersion("h1", repositoryVersionEntity, RepositoryVersionState.INSTALLED); + c1.recalculateAllClusterVersionStates(); + checkStackVersionState(stackId.getStackId(), "1.0-1000", RepositoryVersionState.INSTALLED); + checkStackVersionState(stackId.getStackId(), "1.0-2086", RepositoryVersionState.CURRENT); + + // Add new host and verify that it has all host versions present + addHost("h2"); + clusters.mapHostToCluster("h2", "c1"); + + List<HostVersionEntity> h2Versions = hostVersionDAO.findByHost("h2"); + + for (HostVersionEntity hostVersionEntity : h2Versions) { + if (hostVersionEntity.getRepositoryVersion().toString().equals("1.0-2086")) { + assertEquals(hostVersionEntity.getState(), RepositoryVersionState.CURRENT); + } else { + assertEquals(hostVersionEntity.getState(), RepositoryVersionState.OUT_OF_SYNC); + } + } + + } + + private void addHost(String hostname) throws AmbariException{ + clusters.addHost(hostname); + + Host host1 = clusters.getHost(hostname); + host1.setIPv4("ipv4"); + host1.setIPv6("ipv6"); + + Map<String, String> hostAttributes = new HashMap<String, String>(); + hostAttributes.put("os_family", "redhat"); + hostAttributes.put("os_release_version", "5.9"); + host1.setHostAttributes(hostAttributes); + + host1.persist(); + } + + private void checkStackVersionState(String stack, String version, RepositoryVersionState state) { + Collection<ClusterVersionEntity> allClusterVersions = c1.getAllClusterVersions(); + for (ClusterVersionEntity entity : allClusterVersions) { + if (entity.getRepositoryVersion().getStack().equals(stack) + && entity.getRepositoryVersion().getVersion().equals(version)) { + assertEquals(state, entity.getState()); + } + } + } +}