Repository: ambari Updated Branches: refs/heads/trunk eb4eb8a02 -> 5567b34ee
AMBARI-8271. Create DAO and Unit Tests for HostVersion (alejandro) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5567b34e Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5567b34e Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5567b34e Branch: refs/heads/trunk Commit: 5567b34ee2d4c08742d899941df833f6a30a94c0 Parents: eb4eb8a Author: Alejandro Fernandez <afernan...@hortonworks.com> Authored: Wed Nov 12 11:07:57 2014 -0800 Committer: Alejandro Fernandez <afernan...@hortonworks.com> Committed: Wed Nov 12 11:08:17 2014 -0800 ---------------------------------------------------------------------- .../ambari/server/orm/dao/HostVersionDAO.java | 161 +++++++++++ .../server/orm/entities/ClusterEntity.java | 8 + .../orm/entities/ClusterVersionEntity.java | 4 - .../ambari/server/orm/entities/HostEntity.java | 7 +- .../server/orm/entities/HostVersionEntity.java | 53 +++- .../ambari/server/state/HostVersionState.java | 49 ---- .../server/orm/dao/HostVersionDAOTest.java | 289 +++++++++++++++++++ 7 files changed, 512 insertions(+), 59 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/5567b34e/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java new file mode 100644 index 0000000..8d147a1 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostVersionDAO.java @@ -0,0 +1,161 @@ +/** + * 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.orm.dao; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; +import com.google.inject.persist.Transactional; +import org.apache.ambari.server.orm.RequiresSession; +import org.apache.ambari.server.orm.entities.HostVersionEntity; +import org.apache.ambari.server.state.UpgradeState; + +import javax.persistence.EntityManager; +import javax.persistence.TypedQuery; +import java.util.List; + +/** + * The {@link org.apache.ambari.server.orm.dao.HostVersionDAO} class manages the {@link org.apache.ambari.server.orm.entities.HostVersionEntity} + * instances associated with a host. Each host can have multiple stack versions in {@link org.apache.ambari.server.state.UpgradeState#NONE} + * which are installed, exactly one stack version that is either {@link org.apache.ambari.server.state.UpgradeState#PENDING} or + * {@link org.apache.ambari.server.state.UpgradeState#IN_PROGRESS}. + */ +@Singleton +public class HostVersionDAO { + @Inject + Provider<EntityManager> entityManagerProvider; + @Inject + DaoUtils daoUtils; + + /** + * Get the object with the given id. + * + * @param id Primary key id + * @return Return the object with the given primary key + */ + @RequiresSession + public HostVersionEntity findByPK(long id) { + return entityManagerProvider.get().find(HostVersionEntity.class, id); + } + + /** + * Retrieve all of the host versions for the given cluster name, stack name, and stack version. + * + * @param clusterName Cluster name + * @param stack Stack name (e.g., HDP) + * @param version Stack version (e.g., 2.2.0.1-995) + * @return Return all of the host versions that match the criteria. + */ + @RequiresSession + public List<HostVersionEntity> findByClusterStackAndVersion(String clusterName, String stack, String version) { + final TypedQuery<HostVersionEntity> query = entityManagerProvider.get().createNamedQuery("hostVersionByClusterAndStackAndVersion", HostVersionEntity.class); + query.setParameter("clusterName", clusterName); + query.setParameter("stack", stack); + query.setParameter("version", version); + + return daoUtils.selectList(query); + } + + /** + * Retrieve all of the host versions for the given cluster name and host name. + * + * @param clusterName Cluster name + * @param hostName FQDN of host + * @return Return all of the host versions that match the criteria. + */ + @RequiresSession + public List<HostVersionEntity> findByClusterAndHost(String clusterName, String hostName) { + final TypedQuery<HostVersionEntity> query = entityManagerProvider.get() + .createNamedQuery("hostVersionByClusterAndHostname", HostVersionEntity.class); + query.setParameter("clusterName", clusterName); + query.setParameter("hostName", hostName); + + return daoUtils.selectList(query); + } + + /** + * Retrieve all of the host versions for the given cluster name, host name, and state. + * + * @param clusterName Cluster name + * @param hostName FQDN of host + * @param state Upgrade state + * @return Return all of the host versions that match the criteria. + */ + @RequiresSession + public List<HostVersionEntity> findByClusterHostAndState(String clusterName, String hostName, UpgradeState state) { + final TypedQuery<HostVersionEntity> query = entityManagerProvider.get() + .createNamedQuery("hostVersionByClusterHostnameAndState", HostVersionEntity.class); + query.setParameter("clusterName", clusterName); + query.setParameter("hostName", hostName); + query.setParameter("state", state); + + return daoUtils.selectList(query); + } + + /** + * Retrieve the single host version for the given cluster, stack name, stack version, and host name. + * + * @param clusterName Cluster name + * @param stack Stack name (e.g., HDP) + * @param version Stack version (e.g., 2.2.0.1-995) + * @param hostName FQDN of host + * @return Returns the single host version that matches the criteria. + */ + @RequiresSession + public HostVersionEntity findByClusterStackVersionAndHost(String clusterName, String stack, String version, String hostName) { + final TypedQuery<HostVersionEntity> query = entityManagerProvider.get() + .createNamedQuery("hostVersionByClusterStackVersionAndHostname", HostVersionEntity.class); + query.setParameter("clusterName", clusterName); + query.setParameter("stack", stack); + query.setParameter("version", version); + query.setParameter("hostName", hostName); + + return daoUtils.selectSingle(query); + } + + @RequiresSession + public List<HostVersionEntity> findAll() { + return daoUtils.selectAll(entityManagerProvider.get(), HostVersionEntity.class); + } + + @Transactional + public void refresh(HostVersionEntity hostVersionEntity) { + entityManagerProvider.get().refresh(hostVersionEntity); + } + + @Transactional + public void create(HostVersionEntity hostVersionEntity) { + entityManagerProvider.get().persist(hostVersionEntity); + } + + @Transactional + public HostVersionEntity merge(HostVersionEntity hostVersionEntity) { + return entityManagerProvider.get().merge(hostVersionEntity); + } + + @Transactional + public void remove(HostVersionEntity hostVersionEntity) { + entityManagerProvider.get().remove(merge(hostVersionEntity)); + } + + @Transactional + public void removeByPK(long id) { + remove(findByPK(id)); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/5567b34e/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java index 69a2a9d..889a775 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java @@ -20,6 +20,7 @@ package org.apache.ambari.server.orm.entities; import static org.apache.commons.lang.StringUtils.defaultString; +import java.util.ArrayList; import java.util.Collection; import javax.persistence.Basic; @@ -294,6 +295,13 @@ public class ClusterEntity { public void setClusterVersionEntities(Collection<ClusterVersionEntity> clusterVersionEntities) { this.clusterVersionEntities = clusterVersionEntities; } + public void addClusterVersionEntity(ClusterVersionEntity clusterVersionEntity) { + if (this.clusterVersionEntities == null) { + this.clusterVersionEntities = new ArrayList<ClusterVersionEntity>(); + } + this.clusterVersionEntities.add(clusterVersionEntity); + } + /** * Get the admin resource entity. * http://git-wip-us.apache.org/repos/asf/ambari/blob/5567b34e/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java index 46476da..a7d9ab1 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterVersionEntity.java @@ -34,10 +34,6 @@ import javax.persistence.NamedQuery; import javax.persistence.NamedQueries; import javax.persistence.TableGenerator; import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import java.util.Date; import static org.apache.commons.lang.StringUtils.defaultString; http://git-wip-us.apache.org/repos/asf/ambari/blob/5567b34e/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java index 8f850e0..df22de1 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostEntity.java @@ -36,7 +36,7 @@ import static org.apache.commons.lang.StringUtils.defaultString; @javax.persistence.Table(name = "hosts") @Entity -public class HostEntity { +public class HostEntity implements Comparable<HostEntity> { @Id @Column(name = "host_name", nullable = false, insertable = true, updatable = true) @@ -261,6 +261,11 @@ public class HostEntity { return hostName.hashCode(); } + @Override + public int compareTo(HostEntity other) { + return this.hostName.compareTo(other.hostName); + } + public Collection<HostComponentDesiredStateEntity> getHostComponentDesiredStateEntities() { return hostComponentDesiredStateEntities; } http://git-wip-us.apache.org/repos/asf/ambari/blob/5567b34e/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 6bad11b..5b1b4f8 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 @@ -18,7 +18,7 @@ package org.apache.ambari.server.orm.entities; -import org.apache.ambari.server.state.HostVersionState; +import org.apache.ambari.server.state.UpgradeState; import javax.persistence.Basic; import javax.persistence.Column; @@ -30,8 +30,10 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; -import javax.persistence.Table; +import javax.persistence.NamedQuery; +import javax.persistence.NamedQueries; import javax.persistence.TableGenerator; +import javax.persistence.Table; import static org.apache.commons.lang.StringUtils.defaultString; @@ -43,6 +45,24 @@ import static org.apache.commons.lang.StringUtils.defaultString; , initialValue = 0 , allocationSize = 1 ) +@NamedQueries({ + @NamedQuery(name = "hostVersionByClusterAndStackAndVersion", query = + "SELECT hostVersion FROM HostVersionEntity hostVersion JOIN hostVersion.hostEntity host JOIN ClusterEntity cluster " + + "WHERE cluster.clusterName=:clusterName AND hostVersion.stack=:stack AND hostVersion.version=:version"), + + @NamedQuery(name = "hostVersionByClusterAndHostname", query = + "SELECT hostVersion FROM HostVersionEntity hostVersion JOIN hostVersion.hostEntity host JOIN ClusterEntity cluster " + + "WHERE cluster.clusterName=:clusterName AND hostVersion.hostName=:hostName"), + + @NamedQuery(name = "hostVersionByClusterHostnameAndState", query = + "SELECT hostVersion FROM HostVersionEntity hostVersion JOIN hostVersion.hostEntity host JOIN ClusterEntity cluster " + + "WHERE cluster.clusterName=:clusterName AND hostVersion.hostName=:hostName AND hostVersion.state=:state"), + + @NamedQuery(name = "hostVersionByClusterStackVersionAndHostname", query = + "SELECT hostVersion FROM HostVersionEntity hostVersion JOIN hostVersion.hostEntity host JOIN ClusterEntity cluster " + + "WHERE cluster.clusterName=:clusterName AND hostVersion.stack=:stack AND hostVersion.version=:version AND " + + "hostVersion.hostName=:hostName"), +}) public class HostVersionEntity { @Id @@ -67,7 +87,30 @@ public class HostVersionEntity { @Column(name = "state", nullable = false, insertable = true, updatable = true) @Enumerated(value = EnumType.STRING) - private HostVersionState state = HostVersionState.CURRENT; + private UpgradeState state = UpgradeState.NONE; + + /** + * Empty constructor is needed by unit tests. + */ + public HostVersionEntity() { + } + + public HostVersionEntity(String hostName, String stack, String version, UpgradeState state) { + this.hostName = hostName; + this.stack = stack; + this.version = version; + this.state = state; + } + + /** + * This constructor is mainly used by the unit tests in order to construct an object without the id. + */ + public HostVersionEntity(HostVersionEntity other) { + this.hostName = other.hostName; + this.stack = other.stack; + this.version = other.version; + this.state = other.state; + } public Long getId() { return id; @@ -109,11 +152,11 @@ public class HostVersionEntity { this.version = version; } - public HostVersionState getState() { + public UpgradeState getState() { return state; } - public void setState(HostVersionState state) { + public void setState(UpgradeState state) { this.state = state; } http://git-wip-us.apache.org/repos/asf/ambari/blob/5567b34e/ambari-server/src/main/java/org/apache/ambari/server/state/HostVersionState.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/HostVersionState.java b/ambari-server/src/main/java/org/apache/ambari/server/state/HostVersionState.java deleted file mode 100644 index b0a0ee2..0000000 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/HostVersionState.java +++ /dev/null @@ -1,49 +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; - -/** - * There must be exactly one stack version that is in the CURRENT state. - * There may be 0 or more stack versions in an INSTALLED state. - * Installing a new stack version on a host transitions from NOT_INSTALLED to CURRENT once the upgrade finishes. - * The operation to transition a new stack version on the host from the NOT_INSTALLED state to CURRENT must be atomic - * and change the existing stack version on the host from CURRENT to INSTALLED. - * - * <pre> - * Start states: CURRENT, NOT_INSTALLED - * Allowed Transitions: - * NOT_INSTALLED -> CURRENT - * CURRENT -> INSTALLED - * INSTALLED -> CURRENT - * </pre> - */ -public enum HostVersionState { - /** - * Stack version that is installed on this host for all of its components but is not the active stack version on the host. - */ - INSTALLED, - /** - * Stack version that is installed on this host for all of its components and is the active stack version on the host. - */ - CURRENT, - /** - * Stack version that remains to be installed on this host, potentially because it is in the process of being installed. - */ - NOT_INSTALLED; -} http://git-wip-us.apache.org/repos/asf/ambari/blob/5567b34e/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostVersionDAOTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostVersionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostVersionDAOTest.java new file mode 100644 index 0000000..93f78b2 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/HostVersionDAOTest.java @@ -0,0 +1,289 @@ +/** + * 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.orm.dao; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.persist.PersistService; +import org.apache.ambari.server.orm.GuiceJpaInitializer; +import org.apache.ambari.server.orm.InMemoryDefaultTestModule; +import org.apache.ambari.server.orm.entities.*; +import org.apache.ambari.server.state.ClusterVersionState; +import org.apache.ambari.server.state.UpgradeState; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + + +/** + * {@link org.apache.ambari.server.orm.dao.HostVersionDAO} unit tests. + */ +public class HostVersionDAOTest { + + private static Injector injector; + private ResourceTypeDAO resourceTypeDAO; + private ClusterDAO clusterDAO; + private ClusterVersionDAO clusterVersionDAO; + private HostDAO hostDAO; + private HostVersionDAO hostVersionDAO; + + @Before + public void before() { + injector = Guice.createInjector(new InMemoryDefaultTestModule()); + injector.getInstance(GuiceJpaInitializer.class); + + resourceTypeDAO = injector.getInstance(ResourceTypeDAO.class); + clusterDAO = injector.getInstance(ClusterDAO.class); + clusterVersionDAO = injector.getInstance(ClusterVersionDAO.class); + hostDAO = injector.getInstance(HostDAO.class); + hostVersionDAO = injector.getInstance(HostVersionDAO.class); + + createDefaultData(); + } + + /** + * Helper function to bootstrap some basic data about clusters, cluster version, host, and host versions. + */ + private void createDefaultData() { + // Create the cluster + ResourceTypeEntity resourceTypeEntity = new ResourceTypeEntity(); + resourceTypeEntity.setId(ResourceTypeEntity.CLUSTER_RESOURCE_TYPE); + resourceTypeEntity.setName(ResourceTypeEntity.CLUSTER_RESOURCE_TYPE_NAME); + resourceTypeEntity = resourceTypeDAO.merge(resourceTypeEntity); + + ResourceEntity resourceEntity = new ResourceEntity(); + resourceEntity.setResourceType(resourceTypeEntity); + + ClusterEntity clusterEntity = new ClusterEntity(); + clusterEntity.setClusterName("test_cluster1"); + clusterEntity.setClusterInfo("test_cluster_info1"); + clusterEntity.setResource(resourceEntity); + clusterDAO.create(clusterEntity); + + // Create the Cluster Version and link it to the cluster + ClusterVersionEntity clusterVersionEntity = new ClusterVersionEntity(clusterEntity, "HDP", "2.2.0.0-995", ClusterVersionState.CURRENT, System.currentTimeMillis(), System.currentTimeMillis(), "admin"); + List<ClusterVersionEntity> clusterVersionEntities = new ArrayList<ClusterVersionEntity>(); + clusterVersionEntities.add(clusterVersionEntity); + clusterEntity.setClusterVersionEntities(clusterVersionEntities); + + clusterVersionDAO.create(clusterVersionEntity); + clusterDAO.merge(clusterEntity); + + // Create the hosts + HostEntity host1 = new HostEntity(); + HostEntity host2 = new HostEntity(); + HostEntity host3 = new HostEntity(); + + host1.setHostName("test_host1"); + host2.setHostName("test_host2"); + host3.setHostName("test_host3"); + host1.setIpv4("192.168.0.1"); + host2.setIpv4("192.168.0.2"); + host3.setIpv4("192.168.0.3"); + + List<HostEntity> hostEntities = new ArrayList<HostEntity>(); + hostEntities.add(host1); + hostEntities.add(host2); + hostEntities.add(host3); + + clusterEntity.setHostEntities(hostEntities); + // Both sides of relation should be set when modifying in runtime + host1.setClusterEntities(Arrays.asList(clusterEntity)); + host2.setClusterEntities(Arrays.asList(clusterEntity)); + host2.setClusterEntities(Arrays.asList(clusterEntity)); + + hostDAO.create(host1); + hostDAO.create(host2); + hostDAO.create(host3); + clusterDAO.merge(clusterEntity); + + // Create the Host Versions + HostVersionEntity hostVersionEntity1 = new HostVersionEntity(host1.getHostName(), clusterVersionEntity.getStack(), clusterVersionEntity.getVersion(), UpgradeState.NONE); + HostVersionEntity hostVersionEntity2 = new HostVersionEntity(host2.getHostName(), clusterVersionEntity.getStack(), clusterVersionEntity.getVersion(), UpgradeState.NONE); + HostVersionEntity hostVersionEntity3 = new HostVersionEntity(host3.getHostName(), clusterVersionEntity.getStack(), clusterVersionEntity.getVersion(), UpgradeState.NONE); + hostVersionEntity1.setHostEntity(host1); + hostVersionEntity2.setHostEntity(host2); + hostVersionEntity3.setHostEntity(host3); + + hostVersionDAO.create(hostVersionEntity1); + hostVersionDAO.create(hostVersionEntity2); + hostVersionDAO.create(hostVersionEntity3); + } + + /** + * Helper function to bootstrap additional data on top of the default data. + */ + private void addMoreVersions() { + ClusterEntity clusterEntity = clusterDAO.findByName("test_cluster1"); + + // Create another Cluster Version and mark the old one as INSTALLED + if (clusterEntity.getClusterVersionEntities() != null && clusterEntity.getClusterVersionEntities().size() > 0) { + ClusterVersionEntity installedClusterVersion = clusterVersionDAO.findByClusterAndStateCurrent(clusterEntity.getClusterName()); + installedClusterVersion.setState(ClusterVersionState.INSTALLED); + clusterVersionDAO.merge(installedClusterVersion); + } else { + Assert.fail("Cluster is expected to have at least one cluster version"); + } + + ClusterVersionEntity newClusterVersionEntity = new ClusterVersionEntity(clusterEntity, "HDP", "2.2.0.1-996", ClusterVersionState.CURRENT, System.currentTimeMillis(), System.currentTimeMillis(), "admin"); + clusterEntity.addClusterVersionEntity(newClusterVersionEntity); + clusterVersionDAO.create(newClusterVersionEntity); + + HostEntity[] hostEntities = clusterEntity.getHostEntities().toArray(new HostEntity[clusterEntity.getHostEntities().size()]); + // Must sort by host name in ascending order to ensure that state is accurately set later on. + Arrays.sort(hostEntities); + + // For each of the hosts, add a host version + for (HostEntity host : hostEntities) { + HostVersionEntity hostVersionEntity = new HostVersionEntity(host.getHostName(), "HDP", "2.2.0.1-996", UpgradeState.NONE); + hostVersionEntity.setHostEntity(host); + hostVersionDAO.create(hostVersionEntity); + } + + // For each of the hosts, add one more host version + for (int i = 0; i < hostEntities.length; i++) { + UpgradeState desiredState = UpgradeState.NONE; + if (i % 3 == 0) { + desiredState = UpgradeState.PENDING; + } + if (i % 3 == 1) { + desiredState = UpgradeState.IN_PROGRESS; + } + if (i % 3 == 2) { + desiredState = UpgradeState.FAILED; + } + + HostVersionEntity hostVersionEntity = new HostVersionEntity(hostEntities[i].getHostName(), "HDP", "2.2.1.0-500", desiredState); + hostVersionEntity.setHostEntity(hostEntities[i]); + hostVersionDAO.create(hostVersionEntity); + } + } + + /** + * Test the {@link HostVersionDAO#findAll()} method. + */ + @Test + public void testFindAll() { + Assert.assertEquals(3, hostVersionDAO.findAll().size()); + } + + /** + * Test the {@link HostVersionDAO#findByClusterStackAndVersion(String, String, String)} method. + */ + @Test + public void testFindByClusterStackAndVersion() { + Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", "HDP", "2.2.0.0-995").size()); + Assert.assertEquals(3, hostVersionDAO.findAll().size()); + + addMoreVersions(); + + Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", "HDP", "2.2.0.1-996").size()); + Assert.assertEquals(3, hostVersionDAO.findByClusterStackAndVersion("test_cluster1", "HDP", "2.2.1.0-500").size()); + Assert.assertEquals(9, hostVersionDAO.findAll().size()); + } + + /** + * Test the {@link HostVersionDAO#findByClusterAndHost(String, String)} method. + */ + @Test + public void testFindByClusterAndHost() { + Assert.assertEquals(1, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host1").size()); + Assert.assertEquals(1, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host2").size()); + Assert.assertEquals(1, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host3").size()); + + addMoreVersions(); + + Assert.assertEquals(3, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host1").size()); + Assert.assertEquals(3, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host2").size()); + Assert.assertEquals(3, hostVersionDAO.findByClusterAndHost("test_cluster1", "test_host3").size()); + } + + /** + * Test the {@link HostVersionDAO#findByClusterHostAndState(String, String, org.apache.ambari.server.state.UpgradeState)} method. + */ + @Test + public void testFindByClusterHostAndState() { + Assert.assertEquals(1, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host1", UpgradeState.NONE).size()); + Assert.assertEquals(0, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host1", UpgradeState.PENDING).size()); + Assert.assertEquals(0, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host2", UpgradeState.IN_PROGRESS).size()); + Assert.assertEquals(0, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host3", UpgradeState.FAILED).size()); + + addMoreVersions(); + + Assert.assertEquals(2, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host1", UpgradeState.NONE).size()); + Assert.assertEquals(2, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host2", UpgradeState.NONE).size()); + Assert.assertEquals(2, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host3", UpgradeState.NONE).size()); + + Assert.assertEquals(1, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host1", UpgradeState.PENDING).size()); + Assert.assertEquals(1, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host2", UpgradeState.IN_PROGRESS).size()); + Assert.assertEquals(1, hostVersionDAO.findByClusterHostAndState("test_cluster1", "test_host3", UpgradeState.FAILED).size()); + } + + /** + * Test the {@link HostVersionDAO#findByClusterStackVersionAndHost(String, String, String, String)} method. + */ + @Test + public void testFindByClusterStackVersionAndHost() { + HostVersionEntity hostVersionEntity1 = new HostVersionEntity("test_host1", "HDP", "2.2.0.0-995", UpgradeState.NONE); + hostVersionEntity1.setId(1L); + HostVersionEntity hostVersionEntity2 = new HostVersionEntity("test_host2", "HDP", "2.2.0.0-995", UpgradeState.NONE); + hostVersionEntity2.setId(2L); + HostVersionEntity hostVersionEntity3 = new HostVersionEntity("test_host3", "HDP", "2.2.0.0-995", UpgradeState.NONE); + hostVersionEntity3.setId(3L); + + Assert.assertEquals(hostVersionEntity1, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", "HDP", "2.2.0.0-995", "test_host1")); + Assert.assertEquals(hostVersionEntity2, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", "HDP", "2.2.0.0-995", "test_host2")); + Assert.assertEquals(hostVersionEntity3, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", "HDP", "2.2.0.0-995", "test_host3")); + + // Test non-existent objects + Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("non_existent_cluster", "HDP", "2.2.0.0-995", "test_host3")); + Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", "non_existent_stack", "2.2.0.0-995", "test_host3")); + Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", "HDP", "non_existent_version", "test_host3")); + Assert.assertEquals(null, hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", "HDP", "non_existent_version", "non_existent_host")); + + addMoreVersions(); + + // Expected + HostVersionEntity hostVersionEntity1LastExpected = new HostVersionEntity("test_host1", "HDP", "2.2.1.0-500", UpgradeState.PENDING); + HostVersionEntity hostVersionEntity2LastExpected = new HostVersionEntity("test_host2", "HDP", "2.2.1.0-500", UpgradeState.IN_PROGRESS); + HostVersionEntity hostVersionEntity3LastExpected = new HostVersionEntity("test_host3", "HDP", "2.2.1.0-500", UpgradeState.FAILED); + + // Actual + HostVersionEntity hostVersionEntity1LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", "HDP", "2.2.1.0-500", "test_host1"); + HostVersionEntity hostVersionEntity2LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", "HDP", "2.2.1.0-500", "test_host2"); + HostVersionEntity hostVersionEntity3LastActual = hostVersionDAO.findByClusterStackVersionAndHost("test_cluster1", "HDP", "2.2.1.0-500", "test_host3"); + + // Trying to Mock the actual objects to override the getId() method will not work because the class that mockito creates + // is still a Mockito wrapper. Instead, take advantage of an overloaded constructor that ignores the Id. + Assert.assertEquals(hostVersionEntity1LastExpected, new HostVersionEntity(hostVersionEntity1LastActual)); + Assert.assertEquals(hostVersionEntity2LastExpected, new HostVersionEntity(hostVersionEntity2LastActual)); + Assert.assertEquals(hostVersionEntity3LastExpected, new HostVersionEntity(hostVersionEntity3LastActual)); + } + + @After + public void after() { + injector.getInstance(PersistService.class).stop(); + injector = null; + } +} \ No newline at end of file