You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2015/03/02 20:07:04 UTC
[1/2] ambari git commit: AMBARI-9805. RU - Bug fixes for Host Version
transition and Finalize (alejandro)
Repository: ambari
Updated Branches:
refs/heads/branch-2.0.0 01e6dd3b9 -> f5c7ac418
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/resources/stacks/HDP/2.2.0/role_command_order.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/role_command_order.json b/ambari-server/src/test/resources/stacks/HDP/2.2.0/role_command_order.json
new file mode 100644
index 0000000..656bb63
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/role_command_order.json
@@ -0,0 +1,81 @@
+{
+ "_comment" : "Record format:",
+ "_comment" : "blockedRole-blockedCommand: [blockerRole1-blockerCommand1, blockerRole2-blockerCommand2, ...]",
+ "general_deps" : {
+ "_comment" : "dependencies for all cases",
+ "HBASE_MASTER-START": ["ZOOKEEPER_SERVER-START, ZOOKEEPER_SERVER-START"],
+ "OOZIE_SERVER-START": ["JOBTRACKER-START", "TASKTRACKER-START"],
+ "WEBHCAT_SERVER-START": ["TASKTRACKER-START", "HIVE_SERVER-START"],
+ "HIVE_METASTORE-START": ["MYSQL_SERVER-START"],
+ "HIVE_SERVER-START": ["TASKTRACKER-START", "MYSQL_SERVER-START"],
+ "HUE_SERVER-START": ["HIVE_SERVER-START", "HCAT-START", "OOZIE_SERVER-START"],
+ "FLUME_HANDLER-START": ["OOZIE_SERVER-START"],
+ "MAPREDUCE_SERVICE_CHECK-SERVICE_CHECK": ["JOBTRACKER-START", "TASKTRACKER-START"],
+ "OOZIE_SERVICE_CHECK-SERVICE_CHECK": ["OOZIE_SERVER-START"],
+ "WEBHCAT_SERVICE_CHECK-SERVICE_CHECK": ["WEBHCAT_SERVER-START"],
+ "HBASE_SERVICE_CHECK-SERVICE_CHECK": ["HBASE_MASTER-START", "HBASE_REGIONSERVER-START"],
+ "HIVE_SERVICE_CHECK-SERVICE_CHECK": ["HIVE_SERVER-START", "HIVE_METASTORE-START"],
+ "HCAT_SERVICE_CHECK-SERVICE_CHECK": ["HIVE_SERVER-START"],
+ "PIG_SERVICE_CHECK-SERVICE_CHECK": ["JOBTRACKER-START", "TASKTRACKER-START"],
+ "SQOOP_SERVICE_CHECK-SERVICE_CHECK": ["JOBTRACKER-START", "TASKTRACKER-START"],
+ "ZOOKEEPER_SERVICE_CHECK-SERVICE_CHECK": ["ZOOKEEPER_SERVER-START"],
+ "ZOOKEEPER_QUORUM_SERVICE_CHECK-SERVICE_CHECK": ["ZOOKEEPER_SERVER-START"],
+ "ZOOKEEPER_SERVER-STOP" : ["HBASE_MASTER-STOP", "HBASE_REGIONSERVER-STOP"],
+ "HBASE_MASTER-STOP": ["HBASE_REGIONSERVER-STOP"],
+ "TASKTRACKER-UPGRADE": ["JOBTRACKER-UPGRADE"],
+ "MAPREDUCE_CLIENT-UPGRADE": ["TASKTRACKER-UPGRADE", "JOBTRACKER-UPGRADE"],
+ "ZOOKEEPER_SERVER-UPGRADE": ["MAPREDUCE_CLIENT-UPGRADE"],
+ "ZOOKEEPER_CLIENT-UPGRADE": ["ZOOKEEPER_SERVER-UPGRADE"],
+ "HBASE_MASTER-UPGRADE": ["ZOOKEEPER_CLIENT-UPGRADE"],
+ "HBASE_REGIONSERVER-UPGRADE": ["HBASE_MASTER-UPGRADE"],
+ "HBASE_CLIENT-UPGRADE": ["HBASE_REGIONSERVER-UPGRADE"],
+ "HIVE_SERVER-UPGRADE" : ["HBASE_CLIENT-UPGRADE"],
+ "HIVE_METASTORE-UPGRADE" : ["HIVE_SERVER-UPGRADE"],
+ "MYSQL_SERVER-UPGRADE": ["HIVE_METASTORE-UPGRADE"],
+ "HIVE_CLIENT-UPGRADE": ["MYSQL_SERVER-UPGRADE"],
+ "HCAT-UPGRADE": ["HIVE_CLIENT-UPGRADE"],
+ "OOZIE_SERVER-UPGRADE" : ["HCAT-UPGRADE"],
+ "OOZIE_CLIENT-UPGRADE" : ["OOZIE_SERVER-UPGRADE"],
+ "WEBHCAT_SERVER-UPGRADE" : ["OOZIE_CLIENT-UPGRADE"],
+ "PIG-UPGRADE" : ["WEBHCAT_SERVER-UPGRADE"],
+ "SQOOP-UPGRADE" : ["PIG-UPGRADE"],
+ "GANGLIA_SERVER-UPGRADE" : ["SQOOP-UPGRADE"],
+ "GANGLIA_MONITOR-UPGRADE" : ["GANGLIA_SERVER-UPGRADE"]
+ },
+ "_comment" : "GLUSTERFS-specific dependencies",
+ "optional_glusterfs": {
+ "HBASE_MASTER-START": ["PEERSTATUS-START"],
+ "JOBTRACKER-START": ["PEERSTATUS-START"],
+ "TASKTRACKER-START": ["PEERSTATUS-START"],
+ "GLUSTERFS_SERVICE_CHECK-SERVICE_CHECK": ["PEERSTATUS-START"],
+ "JOBTRACKER-UPGRADE": ["GLUSTERFS_CLIENT-UPGRADE"]
+ },
+ "_comment" : "Dependencies that are used when GLUSTERFS is not present in cluster",
+ "optional_no_glusterfs": {
+ "SECONDARY_NAMENODE-START": ["NAMENODE-START"],
+ "RESOURCEMANAGER-START": ["NAMENODE-START", "DATANODE-START"],
+ "NODEMANAGER-START": ["NAMENODE-START", "DATANODE-START", "RESOURCEMANAGER-START"],
+ "HISTORYSERVER-START": ["NAMENODE-START", "DATANODE-START"],
+ "HBASE_MASTER-START": ["NAMENODE-START", "DATANODE-START"],
+ "JOBTRACKER-START": ["NAMENODE-START", "DATANODE-START"],
+ "TASKTRACKER-START": ["NAMENODE-START", "DATANODE-START"],
+ "HIVE_SERVER-START": ["DATANODE-START"],
+ "WEBHCAT_SERVER-START": ["DATANODE-START"],
+ "HDFS_SERVICE_CHECK-SERVICE_CHECK": ["NAMENODE-START", "DATANODE-START",
+ "SECONDARY_NAMENODE-START"],
+ "MAPREDUCE2_SERVICE_CHECK-SERVICE_CHECK": ["NODEMANAGER-START",
+ "RESOURCEMANAGER-START", "HISTORYSERVER-START", "YARN_SERVICE_CHECK-SERVICE_CHECK"],
+ "YARN_SERVICE_CHECK-SERVICE_CHECK": ["NODEMANAGER-START", "RESOURCEMANAGER-START"],
+ "RESOURCEMANAGER_SERVICE_CHECK-SERVICE_CHECK": ["RESOURCEMANAGER-START"],
+ "PIG_SERVICE_CHECK-SERVICE_CHECK": ["RESOURCEMANAGER-START", "NODEMANAGER-START"],
+ "NAMENODE-STOP": ["JOBTRACKER-STOP", "TASKTRACKER-STOP", "RESOURCEMANAGER-STOP",
+ "NODEMANAGER-STOP", "HISTORYSERVER-STOP", "HBASE_MASTER-STOP"],
+ "DATANODE-STOP": ["JOBTRACKER-STOP", "TASKTRACKER-STOP", "RESOURCEMANAGER-STOP",
+ "NODEMANAGER-STOP", "HISTORYSERVER-STOP", "HBASE_MASTER-STOP"],
+ "SECONDARY_NAMENODE-UPGRADE": ["NAMENODE-UPGRADE"],
+ "DATANODE-UPGRADE": ["SECONDARY_NAMENODE-UPGRADE"],
+ "HDFS_CLIENT-UPGRADE": ["DATANODE-UPGRADE"],
+ "JOBTRACKER-UPGRADE": ["HDFS_CLIENT-UPGRADE"]
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/GANGLIA/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/GANGLIA/metainfo.xml b/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/GANGLIA/metainfo.xml
new file mode 100644
index 0000000..1fe4aec
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/GANGLIA/metainfo.xml
@@ -0,0 +1,39 @@
+<?xml version="1.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.
+-->
+<metainfo>
+ <schemaVersion>2.0</schemaVersion>
+ <services>
+ <service>
+ <name>GANGLIA</name>
+ <comment>Ganglia Metrics Collection system (<a href="http://oss.oetiker.ch/rrdtool/" target="_blank">RRDTool</a> will be installed too)</comment>
+ <version>3.5.0</version>
+
+ <components>
+ <component>
+ <name>GANGLIA_SERVER</name>
+ <versionAdvertised>false</versionAdvertised>
+ </component>
+
+ <component>
+ <name>GANGLIA_MONITOR</name>
+ <versionAdvertised>false</versionAdvertised>
+ </component>
+ </components>
+ </service>
+ </services>
+</metainfo>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/HDFS/metainfo.xml b/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/HDFS/metainfo.xml
new file mode 100644
index 0000000..2bd1f99
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/HDFS/metainfo.xml
@@ -0,0 +1,59 @@
+<?xml version="1.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.
+-->
+<metainfo>
+ <schemaVersion>2.0</schemaVersion>
+ <services>
+ <service>
+ <name>HDFS</name>
+ <comment>Apache Hadoop Distributed File System</comment>
+ <version>2.1.0.2.0.6.0</version>
+
+ <components>
+ <component>
+ <name>NAMENODE</name>
+ <versionAdvertised>true</versionAdvertised>
+ </component>
+
+ <component>
+ <name>DATANODE</name>
+ <versionAdvertised>false</versionAdvertised>
+ </component>
+
+ <component>
+ <name>SECONDARY_NAMENODE</name>
+ <versionAdvertised>false</versionAdvertised>
+ </component>
+
+ <component>
+ <name>HDFS_CLIENT</name>
+ <versionAdvertised>true</versionAdvertised>
+ </component>
+
+ <component>
+ <name>JOURNALNODE</name>
+ <versionAdvertised>true</versionAdvertised>
+ </component>
+
+ <component>
+ <name>ZKFC</name>
+ <versionAdvertised>false</versionAdvertised>
+ </component>
+ </components>
+ </service>
+ </services>
+</metainfo>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/ZOOKEEPER/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/ZOOKEEPER/metainfo.xml b/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/ZOOKEEPER/metainfo.xml
new file mode 100644
index 0000000..ed0a132
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/services/ZOOKEEPER/metainfo.xml
@@ -0,0 +1,40 @@
+<?xml version="1.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.
+-->
+<metainfo>
+ <schemaVersion>2.0</schemaVersion>
+ <services>
+ <service>
+ <name>ZOOKEEPER</name>
+ <displayName>ZooKeeper</displayName>
+ <comment>Centralized service which provides highly reliable distributed coordination</comment>
+ <version>3.4.5.2.0</version>
+
+ <components>
+ <component>
+ <name>ZOOKEEPER_SERVER</name>
+ <versionAdvertised>true</versionAdvertised>
+ </component>
+
+ <component>
+ <name>ZOOKEEPER_CLIENT</name>
+ <versionAdvertised>true</versionAdvertised>
+ </component>
+ </components>
+ </service>
+ </services>
+</metainfo>
[2/2] ambari git commit: AMBARI-9805. RU - Bug fixes for Host Version
transition and Finalize (alejandro)
Posted by al...@apache.org.
AMBARI-9805. RU - Bug fixes for Host Version transition and Finalize (alejandro)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f5c7ac41
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f5c7ac41
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f5c7ac41
Branch: refs/heads/branch-2.0.0
Commit: f5c7ac418ee5566dbee7dc2f06365b80a46fa2c0
Parents: 01e6dd3
Author: Alejandro Fernandez <af...@hortonworks.com>
Authored: Mon Mar 2 11:06:13 2015 -0800
Committer: Alejandro Fernandez <af...@hortonworks.com>
Committed: Mon Mar 2 11:06:13 2015 -0800
----------------------------------------------------------------------
.../upgrades/FinalizeUpgradeAction.java | 13 +-
.../org/apache/ambari/server/state/Cluster.java | 28 +-
.../server/state/cluster/ClusterImpl.java | 160 ++---
.../svccomphost/ServiceComponentHostImpl.java | 19 +-
.../ServiceComponentHostSummary.java | 62 +-
.../AmbariManagementControllerTest.java | 2 +-
.../ambari/server/stack/StackManagerTest.java | 4 +-
.../server/state/cluster/ClusterTest.java | 715 +++++++++++++++----
.../HDP/2.0.5/services/GANGLIA/metainfo.xml | 2 +
.../stacks/HDP/2.0.5/services/HDFS/metainfo.xml | 6 +
.../HDP/2.0.5/services/ZOOKEEPER/metainfo.xml | 1 +
.../resources/stacks/HDP/2.2.0/metainfo.xml | 24 +
.../resources/stacks/HDP/2.2.0/repos/hdp.json | 10 +
.../stacks/HDP/2.2.0/repos/repoinfo.xml | 62 ++
.../stacks/HDP/2.2.0/role_command_order.json | 81 +++
.../HDP/2.2.0/services/GANGLIA/metainfo.xml | 39 +
.../stacks/HDP/2.2.0/services/HDFS/metainfo.xml | 59 ++
.../HDP/2.2.0/services/ZOOKEEPER/metainfo.xml | 40 ++
18 files changed, 1037 insertions(+), 290 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
index 4dcdc94..d8e5e92 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FinalizeUpgradeAction.java
@@ -125,7 +125,7 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
List<HostVersionEntity> hostVersions = hostVersionDAO.findByClusterStackAndVersion(clusterName, stackId, version);
// Will include hosts whose state is UPGRADED, and potentially INSTALLED
- Set<HostVersionEntity> hostsWithAllowedVersion = new HashSet<HostVersionEntity>();
+ Set<HostVersionEntity> hostVersionsAllowed = new HashSet<HostVersionEntity>();
Set<String> hostsWithoutCorrectVersionState = new HashSet<String>();
Set<String> hostsToUpdate = new HashSet<String>();
// If true, then the cluster version is still in UPGRADING and allowed to transition to UPGRADED, and then CURRENT
@@ -152,7 +152,7 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
}
if (isStateCorrect) {
- hostsWithAllowedVersion.add(hostVersion);
+ hostVersionsAllowed.add(hostVersion);
hostsToUpdate.add(hostVersion.getHostName());
} else {
hostsWithoutCorrectVersionState.add(hostVersion.getHostName());
@@ -169,7 +169,7 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
throw new AmbariException(message);
}
- // Allow the cluster version to transition from UPGRADING to CURRENT
+ // May need to first transition to UPGRADED
if (atLeastOneHostInInstalledState) {
cluster.transitionClusterVersion(stackId, version, RepositoryVersionState.UPGRADED);
upgradingClusterVersion = clusterVersionDAO.findByClusterAndStackAndVersion(clusterName,
@@ -181,9 +181,10 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
upgradingClusterVersion.getState(), RepositoryVersionState.CURRENT.toString()));
}
- outSB.append(String.format("Will finalize the upgraded state of host components in %d host(s).\n", hostsWithAllowedVersion.size()));
+ outSB.append(String.format("Will finalize the upgraded state of host components in %d host(s).\n", hostVersionsAllowed.size()));
- for (HostVersionEntity hostVersion : hostsWithAllowedVersion) {
+ // Reset the upgrade state
+ for (HostVersionEntity hostVersion : hostVersionsAllowed) {
Collection<HostComponentStateEntity> hostComponentStates = hostComponentStateDAO.findByHost(hostVersion.getHostName());
for (HostComponentStateEntity hostComponentStateEntity: hostComponentStates) {
hostComponentStateEntity.setUpgradeState(UpgradeState.NONE);
@@ -191,7 +192,7 @@ public class FinalizeUpgradeAction extends AbstractServerAction {
}
}
- outSB.append(String.format("Will finalize the version for %d host(s).\n", hostsWithAllowedVersion.size()));
+ outSB.append(String.format("Will finalize the version for %d host(s).\n", hostVersionsAllowed.size()));
// Impacts all hosts that have a version
cluster.mapHostVersions(hostsToUpdate, upgradingClusterVersion, RepositoryVersionState.CURRENT);
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
index 6b8a917..9b424b8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
@@ -152,23 +152,10 @@ public interface Cluster {
* @throws AmbariException
*/
public void inferHostVersions(ClusterVersionEntity sourceClusterVersion) throws AmbariException;
-
- /**
- * Update state of a cluster stack version for cluster based on states of host versions.
- * May be called multiple times.
- * As of now, only transition from INSTALLING to INSTALLING/INSTALLED/INSTALL_FAILED/OUT_OF_SYNC
- * is supported
- *
- * @param repositoryVersion repository version (e.g. 2.2.1.0-100)
- *
- * @throws AmbariException
- */
- void recalculateClusterVersionState(String repositoryVersion) throws AmbariException;
-
+
/**
* For a given host, will either either update an existing Host Version Entity for the given version, or create
- * one if it doesn't exist. The object will be created with a state of
- * {@link org.apache.ambari.server.state.RepositoryVersionState#UPGRADING}
+ * one if it doesn't exist
*
* @param host Host Entity object
* @param repositoryVersion Repository Version that the host is transitioning to
@@ -179,10 +166,14 @@ public interface Cluster {
public HostVersionEntity transitionHostVersionState(HostEntity host, final RepositoryVersionEntity repositoryVersion, final StackId stack) throws AmbariException;
/**
+ * Update state of a cluster stack version for cluster based on states of host versions.
+ * @param repositoryVersion repository version (e.g. 2.2.1.0-100)
+ * @throws AmbariException
+ */
+ void recalculateClusterVersionState(String repositoryVersion) throws AmbariException;
+
+ /**
* Update state of all cluster stack versions for cluster based on states of host versions.
- * May be called multiple times.
- * As of now, only transition from INSTALLING to INSTALLING/INSTALLED/INSTALL_FAILED/OUT_OF_SYNC
- * is supported
* @throws AmbariException
*/
public void recalculateAllClusterVersionStates() throws AmbariException;
@@ -199,7 +190,6 @@ public interface Cluster {
*/
public void createClusterVersion(String stack, String version, String userName, RepositoryVersionState state) throws AmbariException;
-
/**
* Transition an existing cluster version from one state to another.
* @param stack Stack name
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index 13d986d..638e4da 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -30,6 +30,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -172,6 +173,10 @@ public class ClusterImpl implements Cluster {
private final ReadWriteLock clusterGlobalLock = new ReentrantReadWriteLock();
+ // This is a lock for operations that do not need to be cluster global
+ private final ReentrantReadWriteLock hostTransitionStateLock = new ReentrantReadWriteLock();
+ private final Lock hostTransitionStateWriteLock = hostTransitionStateLock.writeLock();
+
private ClusterEntity clusterEntity;
private final ConfigVersionHelper configVersionHelper;
@@ -1176,6 +1181,11 @@ public class ClusterImpl implements Cluster {
return RepositoryVersionState.OUT_OF_SYNC;
}
+ /**
+ * Recalculate what the Cluster Version state should be, depending on the individual Host Versions.
+ * @param repositoryVersion Repository version (e.g., 2.2.0.0-1234)
+ * @throws AmbariException
+ */
@Override
public void recalculateClusterVersionState(String repositoryVersion) throws AmbariException {
if (repositoryVersion == null) {
@@ -1196,6 +1206,9 @@ public class ClusterImpl implements Cluster {
if (clusterVersionDAO.findByCluster(getClusterName()).isEmpty()) {
// During an Ambari Upgrade from 1.7.0 -> 2.0.0, the Cluster Version
// will not exist, so bootstrap it.
+ // This can still fail if the Repository Version has not yet been created,
+ // which can happen if the first HostComponentState to trigger this method
+ // cannot advertise a version.
createClusterVersionInternal(
stackId.getStackId(),
repositoryVersion,
@@ -1203,10 +1216,18 @@ public class ClusterImpl implements Cluster {
RepositoryVersionState.UPGRADING);
clusterVersion = clusterVersionDAO.findByClusterAndStackAndVersion(
getClusterName(), stackId.getStackId(), repositoryVersion);
+
+ if (clusterVersion == null) {
+ LOG.warn(String.format(
+ "Could not create a cluster version for cluster %s and stack %s using repo version %s",
+ getClusterName(), stackId.getStackId(), repositoryVersion));
+ return;
+ }
} else {
- throw new AmbariException(String.format(
+ LOG.warn(String.format(
"Repository version %s not found for cluster %s",
repositoryVersion, getClusterName()));
+ return;
}
}
@@ -1292,77 +1313,52 @@ public class ClusterImpl implements Cluster {
/**
* Transition the Host Version across states.
- * If a Host Component has a valid version, then create a Host Version if it does not already exist.
- * Pre-req is for a Repository Version to exist.
- * If no no cluster version exists, or exactly one, then potentially transition to CURRENT when no more work is needed.
- * If in the middle of an upgrade and no more work exists, transition to UPGRADED.
- * Otherwise, if a mismatch of versions exist, transition to UPGRADING since in the middle of an upgrade.
- * @param host
- * @param repositoryVersion
- * @param stack
+ * @param host Host object
+ * @param repositoryVersion Repository Version with stack and version information
+ * @param stack Stack information
* @throws AmbariException
*/
- @Override
@Transactional
public HostVersionEntity transitionHostVersionState(HostEntity host, final RepositoryVersionEntity repositoryVersion, final StackId stack) throws AmbariException {
- List<HostVersionEntity> hostVersions = hostVersionDAO.findByHost(host.getHostName());
-
- // Check if there is a CURRENT version for host
- boolean currentHostVerExists = false;
- if (hostVersions != null && ! hostVersions.isEmpty()) {
- for (HostVersionEntity hostVersion : hostVersions) {
- if (hostVersion.getState() == RepositoryVersionState.CURRENT) {
- currentHostVerExists = true;
- }
+ HostVersionEntity hostVersionEntity = hostVersionDAO.findByClusterStackVersionAndHost(getClusterName(), repositoryVersion.getStack(), repositoryVersion.getVersion(), host.getHostName());
+
+ hostTransitionStateWriteLock.lock();
+ try {
+ // Create one if it doesn't already exist. It will be possible to make further transitions below.
+ if (hostVersionEntity == null) {
+ hostVersionEntity = new HostVersionEntity(host.getHostName(), repositoryVersion, RepositoryVersionState.UPGRADING);
+ hostVersionEntity.setHostEntity(host);
+ hostVersionDAO.create(hostVersionEntity);
}
- }
- HostVersionEntity hostVersionEntity = hostVersionDAO.findByClusterStackVersionAndHost(getClusterName(),
- repositoryVersion.getStack(), repositoryVersion.getVersion(), host.getHostName());
- if (hostVersionEntity == null) {
- // Since the host has no version, allow bootstrapping a version
- hostVersionEntity = new HostVersionEntity(host.getHostName(), repositoryVersion, RepositoryVersionState.UPGRADING);
- hostVersionEntity.setHostEntity(host);
- hostVersionDAO.create(hostVersionEntity);
- }
+ HostVersionEntity currentVersionEntity = hostVersionDAO.findByHostAndStateCurrent(getClusterName(), host.getHostName());
+ boolean isCurrentPresent = (currentVersionEntity != null);
+ final ServiceComponentHostSummary hostSummary = new ServiceComponentHostSummary(ambariMetaInfo, host, stack);
- final ServiceComponentHostSummary hostSummary = new ServiceComponentHostSummary(ambariMetaInfo, host, stack);
- final Collection<HostComponentStateEntity> versionedHostComponents = hostSummary.getVersionedHostComponents();
+ if (!isCurrentPresent) {
+ // Transition from UPGRADING -> CURRENT. This is allowed because Host Version Entity is bootstrapped in an UPGRADING state.
+ if (hostSummary.isUpgradeFinished() && hostVersionEntity.getState().equals(RepositoryVersionState.UPGRADING)) {
+ hostVersionEntity.setState(RepositoryVersionState.CURRENT);
+ hostVersionDAO.merge(hostVersionEntity);
+ }
+ } else {
+ // Handle transitions during a Rolling Upgrade
- // If 0 or 1 cluster version exists, then a brand new cluster permits the host to transition from UPGRADING->CURRENT
- // If multiple cluster versions exist, then it means that the change in versions is happening due to an Upgrade,
- // so should only allow transitioning to UPGRADED or UPGRADING, depending on further circumstances.
- List<ClusterVersionEntity> clusterVersions = clusterVersionDAO.findByCluster(getClusterName());
- if (clusterVersions.size() <= 1 || ! currentHostVerExists) {
- // Transition from UPGRADING -> CURRENT. This is allowed because Host Version Entity is bootstrapped in an UPGRADING state.
- // This also covers hosts that do not advertise a version when the cluster was created, and then have another component added
- // that does advertise a version.
- if (hostSummary.haveAllComponentsFinishedAdvertisingVersion() &&
- (hostVersionEntity.getState().equals(RepositoryVersionState.UPGRADING) || hostVersionEntity.getState().equals(RepositoryVersionState.UPGRADED)) &&
- ServiceComponentHostSummary.haveSameVersion(versionedHostComponents)) {
- hostVersionEntity.setState(RepositoryVersionState.CURRENT);
- hostVersionDAO.merge(hostVersionEntity);
- }
- } else {
- // Transition from UPGRADING -> UPGRADED.
- // We should never transition directly from INSTALLED -> UPGRADED without first going to UPGRADING because
- // they belong in different phases (1. distribute bits 2. perform upgrade).
- if (hostSummary.haveAllComponentsFinishedAdvertisingVersion() &&
- hostVersionEntity.getState().equals(RepositoryVersionState.UPGRADING) &&
- ServiceComponentHostSummary.haveSameVersion(versionedHostComponents)) {
- hostVersionEntity.setState(RepositoryVersionState.UPGRADED);
- hostVersionDAO.merge(hostVersionEntity);
- } else{
- // HostVersion is INSTALLED and an upgrade is in-progress because at least 2 components have different versions,
- // Or the host has no components that advertise a version, so still consider it as UPGRADING.
- if (hostVersionEntity.getState().equals(RepositoryVersionState.INSTALLED) && versionedHostComponents.size() > 0 &&
- !ServiceComponentHostSummary.haveSameVersion(versionedHostComponents)) {
+ // If a host only has one Component to update, that single report can still transition the host version from
+ // INSTALLED->UPGRADING->UPGRADED in one shot.
+ if (hostSummary.isUpgradeInProgress(currentVersionEntity.getRepositoryVersion().getVersion()) && hostVersionEntity.getState().equals(RepositoryVersionState.INSTALLED)) {
hostVersionEntity.setState(RepositoryVersionState.UPGRADING);
hostVersionDAO.merge(hostVersionEntity);
}
+
+ if (hostSummary.isUpgradeFinished() && hostVersionEntity.getState().equals(RepositoryVersionState.UPGRADING)) {
+ hostVersionEntity.setState(RepositoryVersionState.UPGRADED);
+ hostVersionDAO.merge(hostVersionEntity);
+ }
}
+ } finally {
+ hostTransitionStateWriteLock.unlock();
}
-
return hostVersionEntity;
}
@@ -1420,7 +1416,8 @@ public class ClusterImpl implements Cluster {
RepositoryVersionEntity repositoryVersionEntity = repositoryVersionDAO.findByStackAndVersion(stack, version);
if (repositoryVersionEntity == null) {
- throw new AmbariException("Could not find repository version for stack=" + stack + ", version=" + version );
+ LOG.warn("Could not find repository version for stack=" + stack + ", version=" + version);
+ return;
}
ClusterVersionEntity clusterVersionEntity = new ClusterVersionEntity(clusterEntity, repositoryVersionEntity, state, System.currentTimeMillis(), System.currentTimeMillis(), userName);
@@ -1517,43 +1514,31 @@ public class ClusterImpl implements Cluster {
Collection<HostVersionEntity> versions = hostVersionDAO.findByHost(
he.getHostName());
- if (null == versions || versions.isEmpty()) {
- // no versions whatsoever
- HostVersionEntity hve = new HostVersionEntity();
- hve.setHostEntity(he);
- hve.setHostName(he.getHostName());
- hve.setRepositoryVersion(existingClusterVersion.getRepositoryVersion());
- hve.setState(state);
- hostVersionDAO.create(hve);
- } else {
- HostVersionEntity target = null;
- // set anything that is marked current as installed
+ HostVersionEntity target = null;
+ if (null != versions) {
+ // Set anything that was previously marked CURRENT as INSTALLED, and the matching version as CURRENT
for (HostVersionEntity entity : versions) {
- if (entity.getRepositoryVersion().getId().equals(
- existingClusterVersion.getRepositoryVersion().getId())) {
+ if (entity.getRepositoryVersion().getId().equals(existingClusterVersion.getRepositoryVersion().getId())) {
target = entity;
target.setState(state);
hostVersionDAO.merge(target);
- } else if (entity.getState() == state) {
+ } else if (entity.getState() == RepositoryVersionState.CURRENT) {
entity.setState(RepositoryVersionState.INSTALLED);
hostVersionDAO.merge(entity);
}
}
- if (null == target) {
- // not found in existing list, make one
- HostVersionEntity hve = new HostVersionEntity();
- hve.setHostEntity(he);
- hve.setHostName(he.getHostName());
- hve.setRepositoryVersion(existingClusterVersion.getRepositoryVersion());
- hve.setState(state);
- hostVersionDAO.create(hve);
- }
-
+ }
+ if (null == target) {
+ // If no matching version was found, create one with the desired state
+ HostVersionEntity hve = new HostVersionEntity();
+ hve.setHostEntity(he);
+ hve.setHostName(he.getHostName());
+ hve.setRepositoryVersion(existingClusterVersion.getRepositoryVersion());
+ hve.setState(state);
+ hostVersionDAO.create(hve);
}
}
}
-
-
}
} catch (RollbackException e) {
String message = "Unable to transition stack " + stack + " at version "
@@ -1586,12 +1571,9 @@ public class ClusterImpl implements Cluster {
return true;
}
}
-
-
return false;
}
-
@Override
public void setCurrentStackVersion(StackId stackVersion)
throws AmbariException {
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/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 6d7455e..fe5397b 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
@@ -1501,15 +1501,18 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
final StackId stackId = cluster.getDesiredStackVersion();
final StackInfo stackInfo = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion());
- RepositoryVersionEntity repositoryVersion = repositoryVersionDAO.findByStackAndVersion(stackId.getStackId(), version);
- if (repositoryVersion == null) {
- repositoryVersion = createRepositoryVersion(version, stackId, stackInfo);
- }
+ writeLock.lock();
+ try {
+ RepositoryVersionEntity repositoryVersion = repositoryVersionDAO.findByStackAndVersion(stackId.getStackId(), version);
+ if (repositoryVersion == null) {
+ repositoryVersion = createRepositoryVersion(version, stackId, stackInfo);
+ }
- final HostEntity host = hostDAO.findByName(hostName);
- cluster.transitionHostVersionState(host, repositoryVersion, stackId);
+ final HostEntity host = hostDAO.findByName(hostName);
+ cluster.transitionHostVersionState(host, repositoryVersion, stackId);
+ } finally {
+ writeLock.unlock();
+ }
return version;
}
-
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/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
index ef14f0b..1c36143 100644
--- 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
@@ -19,7 +19,6 @@
package org.apache.ambari.server.state.svccomphost;
-import com.google.inject.Inject;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
@@ -31,6 +30,7 @@ import org.apache.commons.lang.StringUtils;
import java.util.Collection;
import java.util.HashSet;
+import java.util.Set;
/**
@@ -39,26 +39,33 @@ import java.util.HashSet;
public class ServiceComponentHostSummary {
private Collection<HostComponentStateEntity> allHostComponents;
- private Collection<HostComponentStateEntity> versionedHostComponents;
- private Collection<HostComponentStateEntity> noVersionNeededComponents;
+ 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();
- versionedHostComponents = new HashSet<HostComponentStateEntity>();
- noVersionNeededComponents = new HashSet<HostComponentStateEntity>();
+ haveAdvertisedVersion = new HashSet<HostComponentStateEntity>();
+ waitingToAdvertiseVersion = new HashSet<HostComponentStateEntity>();
+ noVersionToAdvertise = new HashSet<HostComponentStateEntity>();
+ versions = new HashSet<String>();
for (HostComponentStateEntity hostComponentStateEntity: allHostComponents) {
- if (!hostComponentStateEntity.getVersion().equalsIgnoreCase(State.UNKNOWN.toString())) {
- versionedHostComponents.add(hostComponentStateEntity);
- } else {
- // Some Components cannot advertise a version. E.g., ZKF, AMBARI_METRICS, Kerberos
- ComponentInfo compInfo = ambariMetaInfo.getComponent(
- stackName, stackVersion, hostComponentStateEntity.getServiceName(),
- hostComponentStateEntity.getComponentName());
+ ComponentInfo compInfo = ambariMetaInfo.getComponent(
+ stackName, stackVersion, hostComponentStateEntity.getServiceName(),
+ hostComponentStateEntity.getComponentName());
- if (!compInfo.isVersionAdvertised()) {
- noVersionNeededComponents.add(hostComponentStateEntity);
+ if (!compInfo.isVersionAdvertised()) {
+ // Some Components cannot advertise a version. E.g., ZKF, AMBARI_METRICS, Kerberos
+ noVersionToAdvertise.add(hostComponentStateEntity);
+ } else {
+ if (hostComponentStateEntity.getVersion() == null || hostComponentStateEntity.getVersion().isEmpty() || hostComponentStateEntity.getVersion().equalsIgnoreCase(State.UNKNOWN.toString())) {
+ waitingToAdvertiseVersion.add(hostComponentStateEntity);
+ } else {
+ haveAdvertisedVersion.add(hostComponentStateEntity);
+ versions.add(hostComponentStateEntity.getVersion());
}
}
}
@@ -68,26 +75,33 @@ public class ServiceComponentHostSummary {
this(ambariMetaInfo, host, stackId.getStackName(), stackId.getStackVersion());
}
- public Collection<HostComponentStateEntity> getAllHostComponents() {
- return allHostComponents;
+ public Collection<HostComponentStateEntity> getHaveAdvertisedVersion() {
+ return haveAdvertisedVersion;
}
- public Collection<HostComponentStateEntity> getVersionedHostComponents() {
- return versionedHostComponents;
+ public boolean isUpgradeFinished() {
+ return haveAllComponentsFinishedAdvertisingVersion() && haveSameVersion(getHaveAdvertisedVersion());
}
- public Collection<HostComponentStateEntity> getNoVersionNeededComponents() {
- return noVersionNeededComponents;
+ /**
+ * @param currentRepoVersion Repo Version that is CURRENT for this 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(String currentRepoVersion) {
+ // 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 currentRepoVersion != null && (versions.size() > 1 || (versions.size() == 1 && !versions.iterator().next().equals(currentRepoVersion)));
}
/**
- * Determine if all of the components on this host have finished advertising a version, which occurs when all of the
- * components that advertise a version, plus the components that do not advertise a version, equal the total number
- * of components.
+ * 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 allHostComponents.size() == versionedHostComponents.size() + noVersionNeededComponents.size();
+ return waitingToAdvertiseVersion.size() == 0;
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index 1d13717..adf562b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -162,7 +162,7 @@ public class AmbariManagementControllerTest {
private static final String PROPERTY_NAME = "hbase.regionserver.msginterval";
private static final String SERVICE_NAME = "HDFS";
private static final String FAKE_SERVICE_NAME = "FAKENAGIOS";
- private static final int STACK_VERSIONS_CNT = 13;
+ private static final int STACK_VERSIONS_CNT = 14;
private static final int REPOS_CNT = 3;
private static final int STACKS_CNT = 3;
private static final int STACK_PROPERTIES_CNT = 103;
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java
index c21215a..f9e81af 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerTest.java
@@ -92,13 +92,13 @@ public class StackManagerTest {
@Test
public void testGetStacks_count() throws Exception {
Collection<StackInfo> stacks = stackManager.getStacks();
- assertEquals(17, stacks.size());
+ assertEquals(18, stacks.size());
}
@Test
public void testGetStack_name__count() {
Collection<StackInfo> stacks = stackManager.getStacks("HDP");
- assertEquals(13, stacks.size());
+ assertEquals(14, stacks.size());
stacks = stackManager.getStacks("OTHER");
assertEquals(2, stacks.size());
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
index a8b64f8..e444828 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/ClusterTest.java
@@ -56,11 +56,15 @@ 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.ClusterVersionDAO;
+import org.apache.ambari.server.orm.dao.HostComponentStateDAO;
+import org.apache.ambari.server.orm.dao.HostDAO;
import org.apache.ambari.server.orm.dao.HostVersionDAO;
+import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
import org.apache.ambari.server.orm.entities.ClusterEntity;
import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
import org.apache.ambari.server.orm.entities.ClusterStateEntity;
import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+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;
@@ -69,6 +73,7 @@ import org.apache.ambari.server.orm.entities.ServiceDesiredStateEntity;
import org.apache.ambari.server.state.AgentVersion;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ComponentInfo;
import org.apache.ambari.server.state.Config;
import org.apache.ambari.server.state.ConfigFactory;
import org.apache.ambari.server.state.ConfigImpl;
@@ -116,7 +121,11 @@ public class ClusterTest {
private ConfigFactory configFactory;
private ConfigGroupFactory configGroupFactory;
private OrmTestHelper helper;
+ private HostDAO hostDAO;
+ private ClusterVersionDAO clusterVersionDAO;
private HostVersionDAO hostVersionDAO;
+ private HostComponentStateDAO hostComponentStateDAO;
+ private RepositoryVersionDAO repositoryVersionDAO;
@Singleton
static class ClusterVersionDAOMock extends ClusterVersionDAO {
@@ -165,8 +174,20 @@ public class ClusterTest {
configFactory = injector.getInstance(ConfigFactory.class);
metaInfo = injector.getInstance(AmbariMetaInfo.class);
helper = injector.getInstance(OrmTestHelper.class);
+ hostDAO = injector.getInstance(HostDAO.class);
+ clusterVersionDAO = injector.getInstance(ClusterVersionDAO.class);
hostVersionDAO = injector.getInstance(HostVersionDAO.class);
+ hostComponentStateDAO = injector.getInstance(HostComponentStateDAO.class);
+ repositoryVersionDAO = injector.getInstance(RepositoryVersionDAO.class);
metaInfo.init();
+ }
+
+ @After
+ public void teardown() {
+ injector.getInstance(PersistService.class).stop();
+ }
+
+ private void createDefaultCluster() throws Exception {
clusters.addCluster("c1");
c1 = clusters.getCluster("c1");
Assert.assertEquals("c1", c1.getClusterName());
@@ -201,13 +222,282 @@ public class ClusterTest {
ClusterVersionDAOMock.failOnCurrentVersionState = false;
}
- @After
- public void teardown() {
- injector.getInstance(PersistService.class).stop();
+ public ClusterEntity createDummyData() {
+ ClusterEntity clusterEntity = new ClusterEntity();
+ clusterEntity.setClusterId(1L);
+ clusterEntity.setClusterName("test_cluster1");
+ clusterEntity.setClusterInfo("test_cluster_info1");
+
+ 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);
+
+ clusterEntity.setHostEntities(hostEntities);
+ clusterEntity.setClusterConfigEntities(Collections.EMPTY_LIST);
+ //both sides of relation should be set when modifying in runtime
+ host1.setClusterEntities(Arrays.asList(clusterEntity));
+ host2.setClusterEntities(Arrays.asList(clusterEntity));
+
+ HostStateEntity hostStateEntity1 = new HostStateEntity();
+ hostStateEntity1.setCurrentState(HostState.HEARTBEAT_LOST);
+ hostStateEntity1.setHostEntity(host1);
+ HostStateEntity hostStateEntity2 = new HostStateEntity();
+ hostStateEntity2.setCurrentState(HostState.HEALTHY);
+ hostStateEntity2.setHostEntity(host2);
+ host1.setHostStateEntity(hostStateEntity1);
+ host2.setHostStateEntity(hostStateEntity2);
+
+ ClusterServiceEntity clusterServiceEntity = new ClusterServiceEntity();
+ clusterServiceEntity.setServiceName("HDFS");
+ clusterServiceEntity.setClusterEntity(clusterEntity);
+ clusterServiceEntity.setServiceComponentDesiredStateEntities(
+ Collections.EMPTY_LIST);
+ ServiceDesiredStateEntity stateEntity = mock(ServiceDesiredStateEntity.class);
+ Gson gson = new Gson();
+ when(stateEntity.getDesiredStackVersion()).thenReturn(gson.toJson(new StackId("HDP-0.1"),
+ StackId.class));
+ clusterServiceEntity.setServiceDesiredStateEntity(stateEntity);
+ List<ClusterServiceEntity> clusterServiceEntities = new ArrayList<ClusterServiceEntity>();
+ clusterServiceEntities.add(clusterServiceEntity);
+ clusterEntity.setClusterServiceEntities(clusterServiceEntities);
+ return clusterEntity;
+ }
+
+ 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());
+ }
+ }
+ }
+
+ private void assertStateException(String stack, String version, RepositoryVersionState transitionState,
+ RepositoryVersionState stateAfter) {
+ try {
+ c1.transitionClusterVersion(stack, version, transitionState);
+ Assert.fail();
+ } catch (AmbariException e) {}
+ checkStackVersionState(stack, version, stateAfter);
+ assertNotNull(c1.getCurrentClusterVersion());
+ }
+
+ /**
+ * For Rolling Upgrades, create a cluster with the following components
+ * HDFS: NameNode, DataNode, HDFS Client
+ * ZK: Zookeeper Server, Zookeeper Monitor
+ * Ganglia: Ganglia Server, Ganglia Monitor
+ *
+ * Further, 3 hosts will be added.
+ * Finally, verify that only the Ganglia components do not need to advertise a version.
+ * @param clusterName Cluster Name
+ * @param stackId Stack to set for the cluster
+ * @param hostAttributes Host attributes to use for 3 hosts (h-1, h-2, h-3)
+ * @throws Exception
+ * @return Cluster that was created
+ */
+ private Cluster createClusterForRU(String clusterName, StackId stackId, Map<String, String> hostAttributes) throws Exception {
+ clusters.addCluster(clusterName);
+ Cluster cluster = clusters.getCluster(clusterName);
+ Assert.assertEquals(clusterName, cluster.getClusterName());
+ Assert.assertEquals(1, cluster.getClusterId());
+
+ // Add Hosts
+ List<String> hostNames = new ArrayList<String>() {{ add("h-1"); add("h-2"); add("h-3"); }};
+ for(String hostName : hostNames) {
+ addHost(hostName, hostAttributes);
+ }
+
+ // Add stack and map Hosts to cluster
+ cluster.setDesiredStackVersion(stackId);
+ cluster.setCurrentStackVersion(stackId);
+ for(String hostName : hostNames) {
+ clusters.mapHostToCluster(hostName, clusterName);
+ }
+
+ // Add Services
+ Service s1 = serviceFactory.createNew(cluster, "HDFS");
+ Service s2 = serviceFactory.createNew(cluster, "ZOOKEEPER");
+ Service s3 = serviceFactory.createNew(cluster, "GANGLIA");
+ cluster.addService(s1);
+ cluster.addService(s2);
+ cluster.addService(s3);
+ s1.persist();
+ s2.persist();
+ s3.persist();
+
+ // Add HDFS components
+ ServiceComponent sc1CompA = serviceComponentFactory.createNew(s1, "NAMENODE");
+ ServiceComponent sc1CompB = serviceComponentFactory.createNew(s1, "DATANODE");
+ ServiceComponent sc1CompC = serviceComponentFactory.createNew(s1, "HDFS_CLIENT");
+ s1.addServiceComponent(sc1CompA);
+ s1.addServiceComponent(sc1CompB);
+ s1.addServiceComponent(sc1CompC);
+ sc1CompA.persist();
+ sc1CompB.persist();
+ sc1CompC.persist();
+
+ // Add ZK
+ ServiceComponent sc2CompA = serviceComponentFactory.createNew(s2, "ZOOKEEPER_SERVER");
+ ServiceComponent sc2CompB = serviceComponentFactory.createNew(s2, "ZOOKEEPER_CLIENT");
+ s2.addServiceComponent(sc2CompA);
+ s2.addServiceComponent(sc2CompB);
+ sc2CompA.persist();
+ sc2CompB.persist();
+
+ // Add Ganglia
+ ServiceComponent sc3CompA = serviceComponentFactory.createNew(s3, "GANGLIA_SERVER");
+ ServiceComponent sc3CompB = serviceComponentFactory.createNew(s3, "GANGLIA_MONITOR");
+ s3.addServiceComponent(sc3CompA);
+ s3.addServiceComponent(sc3CompB);
+ sc3CompA.persist();
+ sc3CompB.persist();
+
+ // Host 1 will have all components
+ ServiceComponentHost schHost1Serv1CompA = serviceComponentHostFactory.createNew(sc1CompA, "h-1");
+ ServiceComponentHost schHost1Serv1CompB = serviceComponentHostFactory.createNew(sc1CompB, "h-1");
+ ServiceComponentHost schHost1Serv1CompC = serviceComponentHostFactory.createNew(sc1CompC, "h-1");
+ ServiceComponentHost schHost1Serv2CompA = serviceComponentHostFactory.createNew(sc2CompA, "h-1");
+ ServiceComponentHost schHost1Serv2CompB = serviceComponentHostFactory.createNew(sc2CompB, "h-1");
+ ServiceComponentHost schHost1Serv3CompA = serviceComponentHostFactory.createNew(sc3CompA, "h-1");
+ ServiceComponentHost schHost1Serv3CompB = serviceComponentHostFactory.createNew(sc3CompB, "h-1");
+ sc1CompA.addServiceComponentHost(schHost1Serv1CompA);
+ sc1CompB.addServiceComponentHost(schHost1Serv1CompB);
+ sc1CompC.addServiceComponentHost(schHost1Serv1CompC);
+ sc2CompA.addServiceComponentHost(schHost1Serv2CompA);
+ sc2CompB.addServiceComponentHost(schHost1Serv2CompB);
+ sc3CompA.addServiceComponentHost(schHost1Serv3CompA);
+ sc3CompB.addServiceComponentHost(schHost1Serv3CompB);
+ schHost1Serv1CompA.persist();
+ schHost1Serv1CompB.persist();
+ schHost1Serv1CompC.persist();
+ schHost1Serv2CompA.persist();
+ schHost1Serv2CompB.persist();
+ schHost1Serv3CompA.persist();
+ schHost1Serv3CompB.persist();
+
+ // Host 2 will have ZK_CLIENT and GANGLIA_MONITOR
+ ServiceComponentHost schHost2Serv2CompB = serviceComponentHostFactory.createNew(sc2CompB, "h-2");
+ ServiceComponentHost schHost2Serv3CompB = serviceComponentHostFactory.createNew(sc3CompB, "h-2");
+ sc2CompB.addServiceComponentHost(schHost2Serv2CompB);
+ sc3CompB.addServiceComponentHost(schHost2Serv3CompB);
+ schHost2Serv2CompB.persist();
+ schHost2Serv3CompB.persist();
+
+ // Host 3 will have GANGLIA_MONITOR
+ ServiceComponentHost schHost3Serv3CompB = serviceComponentHostFactory.createNew(sc3CompB, "h-3");
+ sc3CompB.addServiceComponentHost(schHost3Serv3CompB);
+ schHost3Serv3CompB.persist();
+
+ // Verify count of components
+ List<ServiceComponentHost> scHost1 = cluster.getServiceComponentHosts("h-1");
+ Assert.assertEquals(7, scHost1.size());
+
+ List<ServiceComponentHost> scHost2 = cluster.getServiceComponentHosts("h-2");
+ Assert.assertEquals(2, scHost2.size());
+
+ List<ServiceComponentHost> scHost3 = cluster.getServiceComponentHosts("h-3");
+ Assert.assertEquals(1, scHost3.size());
+
+ //<editor-fold desc="Validate Version Advertised">
+ /*
+ For some reason this still uses the metainfo.xml files for these services
+ from HDP-2.0.5 stack instead of the provided Stack Id
+ */
+ HashMap<String, Set<String>> componentsThatAdvertiseVersion = new HashMap<String, Set<String>>();
+ HashMap<String, Set<String>> componentsThatDontAdvertiseVersion = new HashMap<String, Set<String>>();
+
+ Set<String> hdfsComponents = new HashSet<String>() {{ add("NAMENODE"); add("DATANODE"); add("HDFS_CLIENT"); }};
+ Set<String> zkComponents = new HashSet<String>() {{ add("ZOOKEEPER_SERVER"); add("ZOOKEEPER_CLIENT"); }};
+ Set<String> gangliaComponents = new HashSet<String>() {{ add("GANGLIA_SERVER"); add("GANGLIA_MONITOR"); }};
+
+ componentsThatAdvertiseVersion.put("HDFS", hdfsComponents);
+ componentsThatAdvertiseVersion.put("ZOOKEEPER", zkComponents);
+ componentsThatDontAdvertiseVersion.put("GANGLIA", gangliaComponents);
+
+ for(String service : componentsThatAdvertiseVersion.keySet()) {
+ Set<String> components = componentsThatAdvertiseVersion.get(service);
+ for(String componentName : components) {
+ ComponentInfo component = metaInfo.getComponent(stackId.getStackName(), stackId.getStackVersion(), service, componentName);
+ Assert.assertTrue(component.isVersionAdvertised());
+ }
+ }
+
+ for(String service : componentsThatDontAdvertiseVersion.keySet()) {
+ Set<String> components = componentsThatDontAdvertiseVersion.get(service);
+ for(String componentName : components) {
+ ComponentInfo component = metaInfo.getComponent(stackId.getStackName(), stackId.getStackVersion(), service, componentName);
+ Assert.assertFalse(component.isVersionAdvertised());
+ }
+ }
+ //</editor-fold>
+
+ return cluster;
+ }
+
+ /**
+ * Add a host to the system with the provided attributes.
+ * @param hostName Host Name
+ * @param hostAttributes Host Attributes
+ * @throws Exception
+ */
+ private void addHost(String hostName, Map<String, String> hostAttributes) throws Exception {
+ clusters.addHost(hostName);
+ Host host = clusters.getHost(hostName);
+ host.setIPv4("ipv4");
+ host.setIPv6("ipv6");
+ host.setHostAttributes(hostAttributes);
+ host.persist();
+ }
+
+ /**
+ * For the provided collection of HostComponentStates, set the version to {@paramref version} if the Component
+ * can advertise a version. Then, simulate the {@link org.apache.ambari.server.events.listeners.upgrade.StackVersionListener}
+ * by calling methods to transition the HostVersion, and recalculate the ClusterVersion.
+ * @param stackId Stack ID to retrieve the ComponentInfo
+ * @param version Version to set
+ * @param cluster Cluster to retrieve services from
+ * @param hostComponentStates Collection to set the version for
+ * @throws Exception
+ */
+ private void simulateStackVersionListener(StackId stackId, String version, Cluster cluster, List<HostComponentStateEntity> hostComponentStates) throws Exception {
+ for(int i = 0; i < hostComponentStates.size(); i++) {
+ HostComponentStateEntity hce = hostComponentStates.get(i);
+ ComponentInfo compInfo = metaInfo.getComponent(
+ stackId.getStackName(), stackId.getStackVersion(),
+ hce.getServiceName(),
+ hce.getComponentName());
+
+ if (compInfo.isVersionAdvertised()) {
+ hce.setVersion(version);
+ hostComponentStateDAO.merge(hce);
+ }
+
+ // Simulate the StackVersionListener during the installation
+ Service svc = cluster.getService(hce.getServiceName());
+ ServiceComponent svcComp = svc.getServiceComponent(hce.getComponentName());
+ ServiceComponentHost scHost = svcComp.getServiceComponentHost(hce.getHostName());
+
+ scHost.recalculateHostVersionState();
+ cluster.recalculateClusterVersionState(version);
+ }
}
@Test
- public void testAddHost() throws AmbariException {
+ public void testAddHost() throws Exception {
+ createDefaultCluster();
clusters.addHost("h3");
try {
@@ -217,25 +507,29 @@ public class ClusterTest {
catch (AmbariException e) {
// Expected
}
-
}
-
@Test
- public void testGetHostState() throws AmbariException {
+ public void testGetHostState() throws Exception {
+ createDefaultCluster();
+
Assert.assertEquals(HostState.INIT, clusters.getHost("h1").getState());
}
@Test
- public void testSetHostState() throws AmbariException {
+ public void testSetHostState() throws Exception {
+ createDefaultCluster();
+
clusters.getHost("h1").setState(HostState.HEARTBEAT_LOST);
Assert.assertEquals(HostState.HEARTBEAT_LOST,
clusters.getHost("h1").getState());
}
@Test
- public void testHostEvent() throws AmbariException,
+ public void testHostEvent() throws Exception,
InvalidStateTransitionException {
+ createDefaultCluster();
+
HostInfo hostInfo = new HostInfo();
hostInfo.setHostName("h1");
hostInfo.setInterfaces("fip_4");
@@ -282,7 +576,9 @@ public class ClusterTest {
}
@Test
- public void testBasicClusterSetup() throws AmbariException {
+ public void testBasicClusterSetup() throws Exception {
+ createDefaultCluster();
+
String clusterName = "c2";
try {
@@ -311,7 +607,9 @@ public class ClusterTest {
}
@Test
- public void testAddAndGetServices() throws AmbariException {
+ public void testAddAndGetServices() throws Exception {
+ createDefaultCluster();
+
// TODO write unit tests for
// public void addService(Service service) throws AmbariException;
// public Service getService(String serviceName) throws AmbariException;
@@ -353,9 +651,10 @@ public class ClusterTest {
Assert.assertTrue(services.containsKey("MAPREDUCE"));
}
-
@Test
- public void testGetServiceComponentHosts() throws AmbariException {
+ public void testGetServiceComponentHosts() throws Exception {
+ createDefaultCluster();
+
// TODO write unit tests
// public List<ServiceComponentHost> getServiceComponentHosts(String hostname);
@@ -397,9 +696,9 @@ public class ClusterTest {
Assert.assertEquals(2, scHosts.size());
}
-
@Test
- public void testGetAndSetConfigs() {
+ public void testGetAndSetConfigs() throws Exception {
+ createDefaultCluster();
Map<String, Map<String, String>> c1PropAttributes = new HashMap<String, Map<String,String>>();
c1PropAttributes.put("final", new HashMap<String, String>());
@@ -439,6 +738,8 @@ public class ClusterTest {
@Test
public void testDesiredConfigs() throws Exception {
+ createDefaultCluster();
+
Config config1 = configFactory.createNew(c1, "global",
new HashMap<String, String>() {{ put("a", "b"); }}, new HashMap<String, Map<String,String>>());
config1.setTag("version1");
@@ -494,58 +795,6 @@ public class ClusterTest {
Assert.assertEquals("Expect one host-level override", 1, dc.getHostOverrides().size());
}
- public ClusterEntity createDummyData() {
- ClusterEntity clusterEntity = new ClusterEntity();
- clusterEntity.setClusterId(1L);
- clusterEntity.setClusterName("test_cluster1");
- clusterEntity.setClusterInfo("test_cluster_info1");
-
- 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);
-
- clusterEntity.setHostEntities(hostEntities);
- clusterEntity.setClusterConfigEntities(Collections.EMPTY_LIST);
- //both sides of relation should be set when modifying in runtime
- host1.setClusterEntities(Arrays.asList(clusterEntity));
- host2.setClusterEntities(Arrays.asList(clusterEntity));
-
- HostStateEntity hostStateEntity1 = new HostStateEntity();
- hostStateEntity1.setCurrentState(HostState.HEARTBEAT_LOST);
- hostStateEntity1.setHostEntity(host1);
- HostStateEntity hostStateEntity2 = new HostStateEntity();
- hostStateEntity2.setCurrentState(HostState.HEALTHY);
- hostStateEntity2.setHostEntity(host2);
- host1.setHostStateEntity(hostStateEntity1);
- host2.setHostStateEntity(hostStateEntity2);
-
- ClusterServiceEntity clusterServiceEntity = new ClusterServiceEntity();
- clusterServiceEntity.setServiceName("HDFS");
- clusterServiceEntity.setClusterEntity(clusterEntity);
- clusterServiceEntity.setServiceComponentDesiredStateEntities(
- Collections.EMPTY_LIST);
- ServiceDesiredStateEntity stateEntity = mock(ServiceDesiredStateEntity.class);
- Gson gson = new Gson();
- when(stateEntity.getDesiredStackVersion()).thenReturn(gson.toJson(new StackId("HDP-0.1"),
- StackId.class));
- clusterServiceEntity.setServiceDesiredStateEntity(stateEntity);
- List<ClusterServiceEntity> clusterServiceEntities = new ArrayList<ClusterServiceEntity>();
- clusterServiceEntities.add(clusterServiceEntity);
- clusterEntity.setClusterServiceEntities(clusterServiceEntities);
- return clusterEntity;
- }
-
@Test
public void testClusterRecovery() throws AmbariException {
ClusterEntity entity = createDummyData();
@@ -560,9 +809,10 @@ public class ClusterTest {
Assert.assertNotNull(services.get("HDFS"));
}
-
@Test
- public void testConvertToResponse() throws AmbariException {
+ public void testConvertToResponse() throws Exception {
+ createDefaultCluster();
+
ClusterResponse r = c1.convertToResponse();
Assert.assertEquals(c1.getClusterId(), r.getClusterId().longValue());
Assert.assertEquals(c1.getClusterName(), r.getClusterName());
@@ -615,6 +865,8 @@ public class ClusterTest {
@Test
public void testDeleteService() throws Exception {
+ createDefaultCluster();
+
c1.addService("MAPREDUCE").persist();
Service hdfs = c1.addService("HDFS");
@@ -636,6 +888,8 @@ public class ClusterTest {
@Test
public void testGetHostsDesiredConfigs() throws Exception {
+ createDefaultCluster();
+
Host host1 = clusters.getHost("h1");
Map<String, Map<String, String>> propAttributes = new HashMap<String, Map<String,String>>();
@@ -663,7 +917,9 @@ public class ClusterTest {
}
@Test
- public void testProvisioningState() throws AmbariException {
+ public void testProvisioningState() throws Exception {
+ createDefaultCluster();
+
c1.setProvisioningState(State.INIT);
Assert.assertEquals(State.INIT,
c1.getProvisioningState());
@@ -674,7 +930,9 @@ public class ClusterTest {
}
@Test
- public void testServiceConfigVersions() throws AmbariException {
+ public void testServiceConfigVersions() throws Exception {
+ createDefaultCluster();
+
Config config1 = configFactory.createNew(c1, "hdfs-site",
new HashMap<String, String>() {{ put("a", "b"); }}, new HashMap<String, Map<String,String>>());
config1.setTag("version1");
@@ -730,12 +988,12 @@ public class ClusterTest {
Assert.assertEquals("c1", hdfsResponse.getClusterName());
Assert.assertEquals("admin", hdfsResponse.getUserName());
assertEquals(Long.valueOf(3), hdfsResponse.getVersion());
-
-
}
@Test
- public void testSingleServiceVersionForMultipleConfigs() {
+ public void testSingleServiceVersionForMultipleConfigs() throws Exception {
+ createDefaultCluster();
+
Config config1 = configFactory.createNew(c1, "hdfs-site",
new HashMap<String, String>() {{ put("a", "b"); }}, new HashMap<String, Map<String,String>>());
config1.setTag("version1");
@@ -765,12 +1023,12 @@ public class ClusterTest {
Map<String, Collection<ServiceConfigVersionResponse>> activeServiceConfigVersions =
c1.getActiveServiceConfigVersions();
Assert.assertEquals(1, activeServiceConfigVersions.size());
-
-
}
@Test
- public void testServiceConfigVersionsForGroups() throws AmbariException {
+ public void testServiceConfigVersionsForGroups() throws Exception {
+ createDefaultCluster();
+
Config config1 = configFactory.createNew(c1, "hdfs-site",
new HashMap<String, String>() {{ put("a", "b"); }}, new HashMap<String, Map<String,String>>());
config1.setTag("version1");
@@ -862,31 +1120,12 @@ public class ClusterTest {
Assert.assertEquals("Three service config versions should be active, for default and test groups",
3, activeServiceConfigVersions.get("HDFS").size());
assertEquals("Five total scvs", 5, c1.getServiceConfigVersions().size());
-
- }
-
- 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());
- }
- }
- }
-
- private void assertStateException(String stack, String version, RepositoryVersionState transitionState,
- RepositoryVersionState stateAfter) {
- try {
- c1.transitionClusterVersion(stack, version, transitionState);
- Assert.fail();
- } catch (AmbariException e) {}
- checkStackVersionState(stack, version, stateAfter);
- assertNotNull(c1.getCurrentClusterVersion());
}
@Test
- public void testTransitionClusterVersion() throws AmbariException {
+ public void testTransitionClusterVersion() throws Exception {
+ createDefaultCluster();
+
String stack = "HDP";
String version = "0.2";
@@ -972,7 +1211,9 @@ public class ClusterTest {
}
@Test
- public void testTransitionClusterVersionTransactionFail() throws AmbariException {
+ public void testTransitionClusterVersionTransactionFail() throws Exception {
+ createDefaultCluster();
+
helper.getOrCreateRepositoryVersion("HDP", "0.2");
c1.createClusterVersion("HDP", "0.2", "admin", RepositoryVersionState.INSTALLING);
c1.transitionClusterVersion("HDP", "0.2", RepositoryVersionState.INSTALLED);
@@ -993,7 +1234,9 @@ public class ClusterTest {
}
@Test
- public void testInferHostVersions() throws AmbariException {
+ public void testInferHostVersions() throws Exception {
+ createDefaultCluster();
+
helper.getOrCreateRepositoryVersion("HDP", "0.2");
c1.createClusterVersion("HDP", "0.2", "admin", RepositoryVersionState.INSTALLING);
ClusterVersionEntity entityHDP2 = null;
@@ -1044,7 +1287,9 @@ public class ClusterTest {
}
@Test
- public void testRecalculateClusterVersionState() throws AmbariException {
+ public void testRecalculateClusterVersionState() throws Exception {
+ createDefaultCluster();
+
Host h1 = clusters.getHost("h1");
h1.setState(HostState.HEALTHY);
@@ -1134,7 +1379,9 @@ public class ClusterTest {
}
@Test
- public void testRecalculateAllClusterVersionStates() throws AmbariException {
+ public void testRecalculateAllClusterVersionStates() throws Exception {
+ createDefaultCluster();
+
Host h1 = clusters.getHost("h1");
h1.setState(HostState.HEALTHY);
@@ -1172,13 +1419,201 @@ public class ClusterTest {
checkStackVersionState(stackId.getStackId(), "1.0-2086", RepositoryVersionState.CURRENT);
}
+ /**
+ * Comprehensive test for transitionHostVersion and recalculateClusterVersion.
+ * It creates a cluster with 3 hosts and 3 services, one of which does not advertise a version.
+ * It then verifies that all 3 hosts have a version of CURRENT, and so does the cluster.
+ * It then adds one more host with a component, so its HostVersion will initialize in CURRENT.
+ * Next, it distributes a repo so that it is INSTALLED on the 4 hosts.
+ * It then adds one more host, whose HostVersion will be OUT_OF_SYNC for the new repo.
+ * After redistributing bits again, it simulates an RU.
+ * Finally, some of the hosts will end up with a HostVersion in UPGRADED, and others still in INSTALLED.
+ * @throws Exception
+ */
+ @Test
+ public void testTransitionHostVersionAdvanced() throws Exception {
+ String clusterName = "c1";
+ String v1 = "2.2.0-123";
+ StackId stackId = new StackId("HDP-2.2.0");
+
+ Map<String, String> hostAttributes = new HashMap<String, String>();
+ hostAttributes.put("os_family", "redhat");
+ hostAttributes.put("os_release_version", "5.9");
+
+ Cluster cluster = createClusterForRU(clusterName, stackId, hostAttributes);
+
+ // Begin install by starting to advertise versions
+ // Set the version for the HostComponentState objects
+ int versionedComponentCount = 0;
+ List<HostComponentStateEntity> hostComponentStates = hostComponentStateDAO.findAll();
+ for(int i = 0; i < hostComponentStates.size(); i++) {
+ HostComponentStateEntity hce = hostComponentStates.get(i);
+ ComponentInfo compInfo = metaInfo.getComponent(
+ stackId.getStackName(), stackId.getStackVersion(),
+ hce.getServiceName(),
+ hce.getComponentName());
+
+ if (compInfo.isVersionAdvertised()) {
+ hce.setVersion(v1);
+ hostComponentStateDAO.merge(hce);
+ versionedComponentCount++;
+ }
+
+ // Simulate the StackVersionListener during the installation of the first Stack Version
+ Service svc = cluster.getService(hce.getServiceName());
+ ServiceComponent svcComp = svc.getServiceComponent(hce.getComponentName());
+ ServiceComponentHost scHost = svcComp.getServiceComponentHost(hce.getHostName());
+
+ scHost.recalculateHostVersionState();
+ cluster.recalculateClusterVersionState(v1);
+
+ Collection<ClusterVersionEntity> clusterVersions = cluster.getAllClusterVersions();
+
+ if (versionedComponentCount > 0) {
+ // On the first component with a version, a RepoVersion should have been created
+ RepositoryVersionEntity repositoryVersion = repositoryVersionDAO.findByStackAndVersion(stackId.getStackId(), v1);
+ Assert.assertNotNull(repositoryVersion);
+ Assert.assertTrue(clusterVersions != null && clusterVersions.size() == 1);
+
+ // First component to report a version should cause the ClusterVersion to go to UPGRADING
+ if (versionedComponentCount == 1 && i < (hostComponentStates.size() - 1)) {
+ Assert.assertEquals(clusterVersions.iterator().next().getState(), RepositoryVersionState.UPGRADING);
+ }
+
+ // Last component to report a version should cause the ClusterVersion to go to CURRENT
+ if (i == hostComponentStates.size() - 1) {
+ Assert.assertEquals(clusterVersions.iterator().next().getState(), RepositoryVersionState.CURRENT);
+ }
+ }
+ }
+
+ // Add another Host with components ZK Server, ZK Client, and Ganglia Monitor.
+ // This host should get a HostVersion in CURRENT, and the ClusterVersion should stay in CURRENT
+ addHost("h-4", hostAttributes);
+ clusters.mapHostToCluster("h-4", clusterName);
+
+ Service svc2 = cluster.getService("ZOOKEEPER");
+ Service svc3 = cluster.getService("GANGLIA");
+
+ ServiceComponent sc2CompA = svc2.getServiceComponent("ZOOKEEPER_SERVER");
+ ServiceComponent sc2CompB = svc2.getServiceComponent("ZOOKEEPER_CLIENT");
+ ServiceComponent sc3CompB = svc3.getServiceComponent("GANGLIA_MONITOR");
+
+ ServiceComponentHost schHost4Serv2CompA = serviceComponentHostFactory.createNew(sc2CompA, "h-4");
+ ServiceComponentHost schHost4Serv2CompB = serviceComponentHostFactory.createNew(sc2CompB, "h-4");
+ ServiceComponentHost schHost4Serv3CompB = serviceComponentHostFactory.createNew(sc3CompB, "h-4");
+ sc2CompA.addServiceComponentHost(schHost4Serv2CompA);
+ sc2CompB.addServiceComponentHost(schHost4Serv2CompB);
+ sc3CompB.addServiceComponentHost(schHost4Serv3CompB);
+ schHost4Serv2CompA.persist();
+ schHost4Serv2CompB.persist();
+ schHost4Serv3CompB.persist();
+
+ simulateStackVersionListener(stackId, v1, cluster, hostComponentStateDAO.findByHost("h-4"));
+
+ Collection<HostVersionEntity> hostVersions = hostVersionDAO.findAll();
+ Assert.assertEquals(hostVersions.size(), clusters.getHosts().size());
+ HostVersionEntity h4Version1 = hostVersionDAO.findByClusterStackVersionAndHost(clusterName, stackId.getStackId(), v1, "h-4");
+ Assert.assertNotNull(h4Version1);
+ Assert.assertEquals(h4Version1.getState(), RepositoryVersionState.CURRENT);
+
+ // Distribute bits for a new repo
+ String v2 = "2.2.0-456";
+ RepositoryVersionEntity rv2 = helper.getOrCreateRepositoryVersion(stackId.getStackId(), v2);
+ for(String hostName : clusters.getHostsForCluster(clusterName).keySet()) {
+ HostEntity host = hostDAO.findByName(hostName);
+ HostVersionEntity hve = new HostVersionEntity(hostName, rv2, RepositoryVersionState.INSTALLED);
+ hve.setHostEntity(host);
+ hostVersionDAO.create(hve);
+ }
+ cluster.createClusterVersion(stackId.getStackId(), v2, "admin", RepositoryVersionState.INSTALLING);
+ cluster.transitionClusterVersion(stackId.getStackId(), v2, RepositoryVersionState.INSTALLED);
+
+ ClusterVersionEntity cv2 = clusterVersionDAO.findByClusterAndStackAndVersion(clusterName, stackId.getStackId(), v2);
+ Assert.assertNotNull(cv2);
+ Assert.assertEquals(cv2.getState(), RepositoryVersionState.INSTALLED);
+
+ // Add one more Host, with only Ganglia on it. It should have a HostVersion in OUT_OF_SYNC for v2
+ addHost("h-5", hostAttributes);
+ clusters.mapHostToCluster("h-5", clusterName);
+ ServiceComponentHost schHost5Serv3CompB = serviceComponentHostFactory.createNew(sc3CompB, "h-5");
+ sc3CompB.addServiceComponentHost(schHost5Serv3CompB);
+ schHost5Serv3CompB.persist();
+
+ // Host 5 will be in OUT_OF_SYNC, so redistribute bits to it so that it reaches a state of INSTALLED
+ HostVersionEntity h5Version2 = hostVersionDAO.findByClusterStackVersionAndHost(clusterName, stackId.getStackId(), v2, "h-5");
+ Assert.assertNotNull(h5Version2);
+ Assert.assertEquals(h5Version2.getState(), RepositoryVersionState.OUT_OF_SYNC);
+
+ h5Version2.setState(RepositoryVersionState.INSTALLED);
+ hostVersionDAO.merge(h5Version2);
+
+ // Perform an RU.
+ // Verify that on first component with the new version, the ClusterVersion transitions to UPGRADING.
+ // For hosts with only components that advertise a version, they HostVersion should be in UPGRADING.
+ // For the remaining hosts, the HostVersion should stay in INSTALLED.
+ versionedComponentCount = 0;
+ hostComponentStates = hostComponentStateDAO.findAll();
+ for(int i = 0; i < hostComponentStates.size(); i++) {
+ HostComponentStateEntity hce = hostComponentStates.get(i);
+ ComponentInfo compInfo = metaInfo.getComponent(
+ stackId.getStackName(), stackId.getStackVersion(),
+ hce.getServiceName(),
+ hce.getComponentName());
+
+ if (compInfo.isVersionAdvertised()) {
+ hce.setVersion(v2);
+ hostComponentStateDAO.merge(hce);
+ versionedComponentCount++;
+ }
+
+ // Simulate the StackVersionListener during the installation of the first Stack Version
+ Service svc = cluster.getService(hce.getServiceName());
+ ServiceComponent svcComp = svc.getServiceComponent(hce.getComponentName());
+ ServiceComponentHost scHost = svcComp.getServiceComponentHost(hce.getHostName());
+
+ scHost.recalculateHostVersionState();
+ cluster.recalculateClusterVersionState(v2);
+
+ Collection<ClusterVersionEntity> clusterVersions = cluster.getAllClusterVersions();
+
+ if (versionedComponentCount > 0) {
+ // On the first component with a version, a RepoVersion should have been created
+ RepositoryVersionEntity repositoryVersion = repositoryVersionDAO.findByStackAndVersion(stackId.getStackId(), v2);
+ Assert.assertNotNull(repositoryVersion);
+ Assert.assertTrue(clusterVersions != null && clusterVersions.size() == 2);
+
+ // First component to report a version should cause the ClusterVersion to go to UPGRADING
+ if (versionedComponentCount == 1 && i < (hostComponentStates.size() - 1)) {
+ cv2 = clusterVersionDAO.findByClusterAndStackAndVersion(clusterName, stackId.getStackId(), v2);
+ Assert.assertEquals(cv2.getState(), RepositoryVersionState.UPGRADING);
+ }
+ }
+ }
+
+ // Last component to report a version should still keep the ClusterVersion in UPGRADING because
+ // hosts 3 and 5 only have Ganglia and the HostVersion will remain in INSTALLED
+ cv2 = clusterVersionDAO.findByClusterAndStackAndVersion(clusterName, stackId.getStackId(), v2);
+ Assert.assertEquals(cv2.getState(), RepositoryVersionState.UPGRADING);
+
+ Collection<HostVersionEntity> v2HostVersions = hostVersionDAO.findByClusterStackAndVersion(clusterName, stackId.getStackId(), v2);
+ Assert.assertEquals(v2HostVersions.size(), clusters.getHostsForCluster(clusterName).size());
+ for (HostVersionEntity hve : v2HostVersions) {
+ if (hve.getHostName().equals("h-3") || hve.getHostName().equals("h-5")) {
+ Assert.assertEquals(hve.getState(), RepositoryVersionState.INSTALLED);
+ } else {
+ Assert.assertEquals(hve.getState(), RepositoryVersionState.UPGRADED);
+ }
+ }
+ }
+
@Test
public void testTransitionNonReportableHost() throws Exception {
- String clusterName = "c2";
+ String clusterName = "c1";
clusters.addCluster(clusterName);
- Cluster c2 = clusters.getCluster(clusterName);
- Assert.assertEquals(clusterName, c2.getClusterName());
- Assert.assertEquals(2, c2.getClusterId());
+ Cluster c1 = clusters.getCluster(clusterName);
+ Assert.assertEquals(clusterName, c1.getClusterName());
+ Assert.assertEquals(1, c1.getClusterId());
clusters.addHost("h-1");
clusters.addHost("h-2");
@@ -1196,41 +1631,40 @@ public class ClusterTest {
h.persist();
}
-
String v1 = "2.0.5-1";
String v2 = "2.0.5-2";
StackId stackId = new StackId("HDP-2.0.5");
- c2.setDesiredStackVersion(stackId);
+ c1.setDesiredStackVersion(stackId);
RepositoryVersionEntity rve1 = helper.getOrCreateRepositoryVersion(stackId.getStackName(), v1);
RepositoryVersionEntity rve2 = helper.getOrCreateRepositoryVersion(stackId.getStackName(), v2);
- c2.setCurrentStackVersion(stackId);
- c2.createClusterVersion(stackId.getStackName(), v1, "admin", RepositoryVersionState.UPGRADING);
- c2.transitionClusterVersion(stackId.getStackName(), v1, RepositoryVersionState.CURRENT);
+ c1.setCurrentStackVersion(stackId);
+ c1.createClusterVersion(stackId.getStackName(), v1, "admin", RepositoryVersionState.UPGRADING);
+ c1.transitionClusterVersion(stackId.getStackName(), v1, RepositoryVersionState.CURRENT);
- clusters.mapHostToCluster("h-1", "c2");
- clusters.mapHostToCluster("h-2", "c2");
- clusters.mapHostToCluster("h-3", "c2");
+ clusters.mapHostToCluster("h-1", clusterName);
+ clusters.mapHostToCluster("h-2", clusterName);
+ clusters.mapHostToCluster("h-3", clusterName);
ClusterVersionDAOMock.failOnCurrentVersionState = false;
- Service service = c2.addService("ZOOKEEPER");
+ Service service = c1.addService("ZOOKEEPER");
ServiceComponent sc = service.addServiceComponent("ZOOKEEPER_SERVER");
sc.addServiceComponentHost("h-1");
sc.addServiceComponentHost("h-2");
- service = c2.addService("SQOOP");
+ service = c1.addService("SQOOP");
sc = service.addServiceComponent("SQOOP");
sc.addServiceComponentHost("h-3");
List<HostVersionEntity> entities = hostVersionDAO.findByClusterAndHost(clusterName, "h-3");
assertTrue("Expected no host versions", null == entities || 0 == entities.size());
- c2.createClusterVersion(stackId.getStackName(), v2, "admin", RepositoryVersionState.INSTALLING);
- c2.transitionClusterVersion(stackId.getStackName(), v2, RepositoryVersionState.INSTALLED);
- c2.transitionClusterVersion(stackId.getStackName(), v2, RepositoryVersionState.UPGRADING);
- c2.transitionClusterVersion(stackId.getStackName(), v2, RepositoryVersionState.UPGRADED);
+ c1.createClusterVersion(stackId.getStackName(), v2, "admin", RepositoryVersionState.INSTALLING);
+ c1.transitionClusterVersion(stackId.getStackName(), v2, RepositoryVersionState.INSTALLED);
+ c1.transitionClusterVersion(stackId.getStackName(), v2, RepositoryVersionState.UPGRADING);
+ c1.transitionClusterVersion(stackId.getStackName(), v2, RepositoryVersionState.UPGRADED);
- c2.transitionClusterVersion(stackId.getStackName(), v2, RepositoryVersionState.CURRENT);
+ c1.transitionClusterVersion(stackId.getStackName(), v2, RepositoryVersionState.CURRENT);
entities = hostVersionDAO.findByClusterAndHost(clusterName, "h-3");
@@ -1244,11 +1678,11 @@ public class ClusterTest {
* and we add a new host to cluster. On a new host, both CURRENT and OUT_OF_SYNC host
* versions should be present
*/
- String clusterName = "c2";
+ String clusterName = "c1";
clusters.addCluster(clusterName);
- final Cluster c2 = clusters.getCluster(clusterName);
- Assert.assertEquals(clusterName, c2.getClusterName());
- Assert.assertEquals(2, c2.getClusterId());
+ final Cluster c1 = clusters.getCluster(clusterName);
+ Assert.assertEquals(clusterName, c1.getClusterName());
+ Assert.assertEquals(1, c1.getClusterId());
clusters.addHost("h-1");
clusters.addHost("h-2");
@@ -1270,30 +1704,30 @@ public class ClusterTest {
String v1 = "2.0.5-1";
String v2 = "2.0.5-2";
StackId stackId = new StackId("HDP-2.0.5");
- c2.setDesiredStackVersion(stackId);
+ c1.setDesiredStackVersion(stackId);
RepositoryVersionEntity rve1 = helper.getOrCreateRepositoryVersion(stackId.getStackId()
, v1);
RepositoryVersionEntity rve2 = helper.getOrCreateRepositoryVersion(stackId.getStackId(), v2);
- c2.setCurrentStackVersion(stackId);
- c2.createClusterVersion(stackId.getStackId(), v1, "admin", RepositoryVersionState.UPGRADING);
- c2.transitionClusterVersion(stackId.getStackId(), v1, RepositoryVersionState.CURRENT);
+ c1.setCurrentStackVersion(stackId);
+ c1.createClusterVersion(stackId.getStackId(), v1, "admin", RepositoryVersionState.UPGRADING);
+ c1.transitionClusterVersion(stackId.getStackId(), v1, RepositoryVersionState.CURRENT);
- clusters.mapHostToCluster("h-1", "c2");
- clusters.mapHostToCluster("h-2", "c2");
+ clusters.mapHostToCluster("h-1", clusterName);
+ clusters.mapHostToCluster("h-2", clusterName);
ClusterVersionDAOMock.failOnCurrentVersionState = false;
- Service service = c2.addService("ZOOKEEPER");
+ Service service = c1.addService("ZOOKEEPER");
ServiceComponent sc = service.addServiceComponent("ZOOKEEPER_SERVER");
sc.addServiceComponentHost("h-1");
sc.addServiceComponentHost("h-2");
- c2.createClusterVersion(stackId.getStackId(), v2, "admin", RepositoryVersionState.INSTALLING);
- c2.transitionClusterVersion(stackId.getStackId(), v2, RepositoryVersionState.INSTALLED);
- c2.transitionClusterVersion(stackId.getStackId(), v2, RepositoryVersionState.OUT_OF_SYNC);
+ c1.createClusterVersion(stackId.getStackId(), v2, "admin", RepositoryVersionState.INSTALLING);
+ c1.transitionClusterVersion(stackId.getStackId(), v2, RepositoryVersionState.INSTALLED);
+ c1.transitionClusterVersion(stackId.getStackId(), v2, RepositoryVersionState.OUT_OF_SYNC);
- clusters.mapHostToCluster(h3, "c2");
+ clusters.mapHostToCluster(h3, clusterName);
// This method is usually called when we receive heartbeat from new host
HostEntity hostEntity3 = mock(HostEntity.class);
@@ -1305,15 +1739,15 @@ public class ClusterTest {
HostVersionDAO hostVersionDAOMock = mock(HostVersionDAO.class);
Field field = ClusterImpl.class.getDeclaredField("hostVersionDAO");
field.setAccessible(true);
- field.set(c2, hostVersionDAOMock);
+ field.set(c1, hostVersionDAOMock);
ArgumentCaptor<HostVersionEntity> hostVersionCaptor = ArgumentCaptor.forClass(HostVersionEntity.class);
ClusterVersionDAOMock.mockedClusterVersions = new ArrayList<ClusterVersionEntity>() {{
- addAll(c2.getAllClusterVersions());
+ addAll(c1.getAllClusterVersions());
}};
- c2.transitionHostVersionState(hostEntity3, rve1, stackId);
+ c1.transitionHostVersionState(hostEntity3, rve1, stackId);
// Revert fields of static instance
ClusterVersionDAOMock.mockedClusterVersions = null;
@@ -1321,5 +1755,4 @@ public class ClusterTest {
verify(hostVersionDAOMock).merge(hostVersionCaptor.capture());
assertEquals(hostVersionCaptor.getValue().getState(), RepositoryVersionState.CURRENT);
}
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/GANGLIA/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/GANGLIA/metainfo.xml b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/GANGLIA/metainfo.xml
index fe5f482..9167f87 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/GANGLIA/metainfo.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/GANGLIA/metainfo.xml
@@ -27,6 +27,7 @@
<name>GANGLIA_SERVER</name>
<category>MASTER</category>
<cardinality>1</cardinality>
+ <versionAdvertised>false</versionAdvertised>
<commandScript>
<script>scripts/ganglia_server.py</script>
<scriptType>PYTHON</scriptType>
@@ -38,6 +39,7 @@
<name>GANGLIA_MONITOR</name>
<category>SLAVE</category>
<cardinality>ALL</cardinality>
+ <versionAdvertised>false</versionAdvertised>
<auto-deploy>
<enabled>true</enabled>
</auto-deploy>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/metainfo.xml b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/metainfo.xml
index e0a40b0..b5e6bc2 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/metainfo.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/metainfo.xml
@@ -28,6 +28,7 @@
<name>NAMENODE</name>
<category>MASTER</category>
<cardinality>1</cardinality>
+ <versionAdvertised>true</versionAdvertised>
<commandScript>
<script>scripts/namenode.py</script>
<scriptType>PYTHON</scriptType>
@@ -58,6 +59,7 @@
<name>DATANODE</name>
<category>SLAVE</category>
<cardinality>1+</cardinality>
+ <versionAdvertised>true</versionAdvertised>
<commandScript>
<script>scripts/datanode.py</script>
<scriptType>PYTHON</scriptType>
@@ -68,6 +70,7 @@
<component>
<name>SECONDARY_NAMENODE</name>
<!-- TODO: cardinality is conditional on HA usage -->
+ <versionAdvertised>false</versionAdvertised>
<cardinality>1</cardinality>
<category>MASTER</category>
<commandScript>
@@ -81,6 +84,7 @@
<name>HDFS_CLIENT</name>
<category>CLIENT</category>
<cardinality>0+</cardinality>
+ <versionAdvertised>true</versionAdvertised>
<commandScript>
<script>scripts/hdfs_client.py</script>
<scriptType>PYTHON</scriptType>
@@ -92,6 +96,7 @@
<name>JOURNALNODE</name>
<category>SLAVE</category>
<cardinality>0+</cardinality>
+ <versionAdvertised>true</versionAdvertised>
<commandScript>
<script>scripts/journalnode.py</script>
<scriptType>PYTHON</scriptType>
@@ -103,6 +108,7 @@
<name>ZKFC</name>
<category>SLAVE</category>
<!-- TODO: cardinality is conditional on HA topology -->
+ <versionAdvertised>false</versionAdvertised>
<cardinality>0+</cardinality>
<commandScript>
<script>scripts/zkfc_slave.py</script>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/ZOOKEEPER/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/ZOOKEEPER/metainfo.xml b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/ZOOKEEPER/metainfo.xml
index 205b445..1c988f7 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/ZOOKEEPER/metainfo.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/ZOOKEEPER/metainfo.xml
@@ -41,6 +41,7 @@
<name>ZOOKEEPER_CLIENT</name>
<category>CLIENT</category>
<cardinality>0+</cardinality>
+ <versionAdvertised>true</versionAdvertised>
<commandScript>
<script>scripts/zookeeper_client.py</script>
<scriptType>PYTHON</scriptType>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/resources/stacks/HDP/2.2.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/metainfo.xml b/ambari-server/src/test/resources/stacks/HDP/2.2.0/metainfo.xml
new file mode 100644
index 0000000..0fb46fe
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/metainfo.xml
@@ -0,0 +1,24 @@
+<?xml version="1.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.
+-->
+<metainfo>
+ <versions>
+ <active>true</active>
+ </versions>
+ <extends>2.1.1</extends>
+</metainfo>
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/resources/stacks/HDP/2.2.0/repos/hdp.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/repos/hdp.json b/ambari-server/src/test/resources/stacks/HDP/2.2.0/repos/hdp.json
new file mode 100644
index 0000000..37a6a60
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/repos/hdp.json
@@ -0,0 +1,10 @@
+{
+ "HDP-2.2.0": {
+ "latest": {
+ "centos6": "http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/BUILDS/2.2.0.0-123",
+ "redhat6": "http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/BUILDS/2.2.2.0-123",
+ "oraclelinux6": "http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/BUILDS/2.2.0.0-123",
+ "suse11": "http://s3.amazonaws.com/dev.hortonworks.com/HDP/suse11/2.x/BUILDS/2.2.0.0-123/hdp.repo"
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f5c7ac41/ambari-server/src/test/resources/stacks/HDP/2.2.0/repos/repoinfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/repos/repoinfo.xml b/ambari-server/src/test/resources/stacks/HDP/2.2.0/repos/repoinfo.xml
new file mode 100644
index 0000000..2a939f1
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/repos/repoinfo.xml
@@ -0,0 +1,62 @@
+<?xml version="1.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.
+-->
+<reposinfo>
+ <latest>./hdp.json</latest>
+ <os family="centos6">
+ <repo>
+ <baseurl>http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.2.0.0</baseurl>
+ <repoid>HDP-2.2.0</repoid>
+ <reponame>HDP</reponame>
+ </repo>
+ </os>
+ <os family="centos5">
+ <repo>
+ <baseurl>http://public-repo-1.hortonworks.com/HDP/centos5/2.x/updates/2.2.0.0</baseurl>
+ <repoid>HDP-2.2.0</repoid>
+ <reponame>HDP</reponame>
+ </repo>
+ </os>
+ <os family="redhat6">
+ <repo>
+ <baseurl>http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.2.0.0</baseurl>
+ <repoid>HDP-2.2.0</repoid>
+ <reponame>HDP</reponame>
+ </repo>
+ </os>
+ <os family="redhat5">
+ <repo>
+ <baseurl>http://public-repo-1.hortonworks.com/HDP/centos5/2.x/updates/2.2.0.0</baseurl>
+ <repoid>HDP-2.2.0</repoid>
+ <reponame>HDP</reponame>
+ </repo>
+ </os>
+ <os family="suse11">
+ <repo>
+ <baseurl>http://public-repo-1.hortonworks.com/HDP/suse11/2.x/updates/2.2.0.0</baseurl>
+ <repoid>HDP-2.2.0</repoid>
+ <reponame>HDP</reponame>
+ </repo>
+ </os>
+ <os family="sles11">
+ <repo>
+ <baseurl>http://public-repo-1.hortonworks.com/HDP/suse11/2.x/updates/2.2.0.0</baseurl>
+ <repoid>HDP-2.2.0</repoid>
+ <reponame>HDP</reponame>
+ </repo>
+ </os>
+</reposinfo>