This is an automated email from the ASF dual-hosted git repository.
jonathanhurley pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push:
new 4c70e1a [AMBARI-24994] Updates to the SPI for Upgrade Action
Operations (#2687)
4c70e1a is described below
commit 4c70e1a7ec5609992fa06fca9618f5b112f941a5
Author: Jonathan Hurley <[email protected]>
AuthorDate: Tue Dec 4 16:11:58 2018 -0500
[AMBARI-24994] Updates to the SPI for Upgrade Action Operations (#2687)
---
.../org/apache/ambari/spi/ClusterInformation.java | 25 +--
.../apache/ambari/spi/upgrade/UpgradeAction.java | 7 +-
.../spi/upgrade/UpgradeActionOperations.java | 168 +++++++++++++++++++--
.../ambari/spi/upgrade/UpgradeInformation.java | 131 ++++++++++++++++
.../orm/entities/RepositoryVersionEntity.java | 17 ++-
.../upgrades/AbstractUpgradeServerAction.java | 18 +++
.../upgrades/PluginUpgradeServerAction.java | 63 +++++++-
.../stack/upgrade/orchestrate/UpgradeContext.java | 42 ++++++
.../ambari/server/state/cluster/ClusterImpl.java | 7 +-
.../upgrades/PluginUpgradeServerActionTest.java | 105 ++++++++++---
10 files changed, 519 insertions(+), 64 deletions(-)
diff --git
a/ambari-server-spi/src/main/java/org/apache/ambari/spi/ClusterInformation.java
b/ambari-server-spi/src/main/java/org/apache/ambari/spi/ClusterInformation.java
index eb9974e..774fe65 100644
---
a/ambari-server-spi/src/main/java/org/apache/ambari/spi/ClusterInformation.java
+++
b/ambari-server-spi/src/main/java/org/apache/ambari/spi/ClusterInformation.java
@@ -21,8 +21,6 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import com.google.common.collect.Maps;
-
/**
* The {@link ClusterInformation} class is used to pass the state of the
cluster
* as simple primitive values and collections. It contains the following types
of information:
@@ -124,13 +122,17 @@ public class ClusterInformation {
return hosts;
}
+ /**
+ * Gets the configuration properties for the specified type. If the type does
+ * not exist, this will return {@code null}.
+ *
+ * @param configurationType
+ * the configuration type to retrieve.
+ * @return the property name and value pairs for the configuration type, or
+ * {@code null} if no configuration type exists.
+ */
public Map<String, String> getConfigurationProperties(String
configurationType) {
- Map<String, String> properties = m_configurations.get(configurationType);
- if (null == properties) {
- return Maps.newHashMap();
- }
-
- return properties;
+ return m_configurations.get(configurationType);
}
/**
@@ -143,7 +145,12 @@ public class ClusterInformation {
* @return the property value, or {@code null} if it does not exist.
*/
public String getConfigurationProperty(String configurationType, String
propertyName) {
- return getConfigurationProperties(configurationType).get(propertyName);
+ Map<String, String> configType =
getConfigurationProperties(configurationType);
+ if (null == configType) {
+ return null;
+ }
+
+ return configType.get(propertyName);
}
/**
diff --git
a/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeAction.java
b/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeAction.java
index 1e25c34..a34cee6 100644
---
a/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeAction.java
+++
b/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeAction.java
@@ -35,13 +35,14 @@ public interface UpgradeAction {
*
* @param clusterInformation
* the cluster information, such as topology, configurations, etc.
- *
+ * @param upgradeInformation
+ * the upgrade type, direction, services, repository versions, etc.
* @return the changes to perform during the upgrade, such as updating
* configurations.
* @throws UpgradeActionException
* if the class is unable to create the operations for the Ambari
* Server to execute.
*/
- UpgradeActionOperations getOperations(ClusterInformation clusterInformation)
- throws UpgradeActionException;
+ UpgradeActionOperations getOperations(ClusterInformation clusterInformation,
+ UpgradeInformation upgradeInformation) throws UpgradeActionException;
}
diff --git
a/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeActionOperations.java
b/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeActionOperations.java
index ddba98c..8a17538 100644
---
a/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeActionOperations.java
+++
b/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeActionOperations.java
@@ -18,12 +18,16 @@
package org.apache.ambari.spi.upgrade;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
/**
* The {@link UpgradeActionOperations} is used to instruct Ambari Server to
* perform actions during an upgrade. It is returned by
- * {@link UpgradeAction#getOperations()}.
+ * {@link
UpgradeAction#getOperations(org.apache.ambari.spi.ClusterInformation,
UpgradeInformation)}
*/
public class UpgradeActionOperations {
@@ -33,13 +37,36 @@ public class UpgradeActionOperations {
private List<ConfigurationChanges> m_configurationChanges;
/**
+ * Any configuration types which should be completely removed.
+ */
+ private Set<String> m_configurationTypeRemovals;
+
+ /**
* A buffer that the {@link UpgradeAction} can use to pass messages back to
* Ambari to display to the user.
*/
- private StringBuilder m_standardOutput;
+ private String m_standardOutput;
+
+ /**
+ * Sets configuration changes which are a part of the actions to be performed
+ * during the upgrade for a single configuration type only. If multiple
+ * configuration types are being updated, then
+ * {@link #setConfigurationChanges(List)} should be used.
+ *
+ * @param configurationChanges
+ * the configuration changes to make.
+ * @return an instance of the {@link UpgradeActionOperations} with the value
+ * set.
+ * @see #setConfigurationChanges(List)
+ */
+ public UpgradeActionOperations setConfigurationChanges(
+ ConfigurationChanges configurationChanges) {
+ setConfigurationChanges(Collections.singletonList(configurationChanges));
+ return this;
+ }
/**
- * Sets configuration changes which are a part of the actions to be perfomred
+ * Sets configuration changes which are a part of the actions to be performed
* during the upgrade.
*
* @param configurationChanges
@@ -54,14 +81,48 @@ public class UpgradeActionOperations {
}
/**
- * Sets a {@link StringBuilder} which is used by the server to display
- * messages about what the action did.
+ * Adds a single configuration change to the operations which should be
+ * performed. This might be more useful thank the bulk methods, such as
+ * {@link #setConfigurationChanges(List)}.
+ *
+ * @param configurationChanges
+ * the configuration changes to make.
+ * @return an instance of the {@link UpgradeActionOperations} with the value
+ * set.
+ */
+ public UpgradeActionOperations addConfigurationChange(ConfigurationChanges
configurationChanges) {
+ if (null == m_configurationChanges) {
+ m_configurationChanges = new ArrayList<>();
+ }
+
+ m_configurationChanges.add(configurationChanges);
+ return this;
+ }
+
+ /**
+ * Sets any configuration types which should be completely removed.
+ *
+ * @param configurationTypeRemovals
+ * the configuration types to be removed, if any.
+ * @return an instance of the {@link UpgradeActionOperations} with the value
+ * set.
+ */
+ public UpgradeActionOperations setConfigurationTypeRemoval(
+ Set<String> configurationTypeRemovals) {
+ m_configurationTypeRemovals = configurationTypeRemovals;
+ return this;
+ }
+
+ /**
+ * Sets the standard output which will be used by the server to display
+ * information about what actions are being performed.
*
* @param standardOutput
+ * the output which will be displayed by the upgrade process.
* @return an instance of the {@link UpgradeActionOperations} with the value
* set.
*/
- public UpgradeActionOperations setStandardOutput(StringBuilder
standardOutput) {
+ public UpgradeActionOperations setStandardOutput(String standardOutput) {
m_standardOutput = standardOutput;
return this;
}
@@ -76,13 +137,22 @@ public class UpgradeActionOperations {
}
/**
+ * Gets the configuration types which should be removed, if any.
+ *
+ * @return the configuration types which should be completely removed, if
any.
+ */
+ public Set<String> getConfigurationTypeRemovals() {
+ return m_configurationTypeRemovals;
+ }
+
+ /**
* Gets the standard output, if any, for the server to display as part of the
* action being run.
*
* @return any messages that should be display along with the command's
* status.
*/
- public StringBuilder getStandardOutput() {
+ public String getStandardOutput() {
return m_standardOutput;
}
@@ -117,20 +187,34 @@ public class UpgradeActionOperations {
private final List<PropertyChange> m_changes = new ArrayList<>();
/**
+ * {@code true} if the only changes included are removals (or there are no
+ * changes at all), {@code false} if there are additions and/or
+ * modifications as well.
+ */
+ private boolean m_onlyRemovals = true;
+
+ /**
* Constructor.
*
* @param configType
+ * the name of the configuration type, such as {@code foo-site}.
*/
public ConfigurationChanges(String configType) {
m_configType = configType;
}
/**
+ * Sets either a new or an update to an existing configuration property.
+ *
* @param propertyName
+ * the name of the property.
* @param propertyValue
- * @return
+ * the value for the property.
+ * @return an instance of this class with the value set.
*/
public ConfigurationChanges set(String propertyName, String propertyValue)
{
+ m_onlyRemovals = false;
+
PropertyChange propertyChange = new PropertyChange(ChangeType.SET,
propertyName,
propertyValue);
@@ -139,8 +223,11 @@ public class UpgradeActionOperations {
}
/**
+ * Marks a configuration property for removal.
+ *
* @param propertyName
- * @return
+ * the name of the property to remove.
+ * @return an instance of this class with the property marked for removal.
*/
public ConfigurationChanges remove(String propertyName) {
PropertyChange propertyChange = new PropertyChange(ChangeType.REMOVE,
propertyName, null);
@@ -161,11 +248,67 @@ public class UpgradeActionOperations {
* Gets all of the additions, updates, and removals for this configuration
* type.
*
- * @return
+ * @return all of the various property changes, including additions and
+ * removals.
*/
public List<PropertyChange> getPropertyChanges() {
return m_changes;
}
+
+ /**
+ * Gets whether the only changes included for this configuration type are
+ * removals (or there are no changes at all of any kind). If there are any
+ * additions or modifications, this will be {@code false}.
+ *
+ * @return whether there are only removals in this change request, or if
+ * there are also additions or modifications to properties.
+ */
+ public boolean isOnlyRemovals() {
+ return m_onlyRemovals;
+ }
+
+ /**
+ * Gets whether there are no changes yet for this configuration change
type.
+ *
+ * @return {@code true} if there are no changes yet, otherwise
+ * {@code false}.
+ */
+ public boolean isEmpty() {
+ return null == m_changes || m_changes.isEmpty();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ if(m_changes.isEmpty()) {
+ return "There are no configuration changes";
+ }
+
+ StringBuilder buffer = new StringBuilder(m_configType);
+ buffer.append(System.lineSeparator());
+
+ for( PropertyChange propertyChange : m_changes ) {
+ switch(propertyChange.getChangeType()) {
+ case REMOVE:
+ buffer.append(" Removed "
).append(propertyChange.getPropertyName());
+ break;
+ case SET:
+ buffer
+ .append(" Set " )
+ .append(propertyChange.getPropertyName())
+ .append(" to " )
+
.append(StringUtils.abbreviateMiddle(propertyChange.getPropertyValue(),
"\u2026", 30));
+ break;
+ default:
+ break;
+
+ }
+ }
+
+ return buffer.toString();
+ }
}
/**
@@ -196,8 +339,7 @@ public class UpgradeActionOperations {
* @param propertyName
* the name of the property being added, updated, or removed.
* @param propertyValue
- * the value to add/update if the type is
- * {@link ConfigurationChangeType#SET}.
+ * the value to add/update if the type is {@link ChangeType#SET}.
*/
public PropertyChange(ChangeType changeType,
String propertyName, String propertyValue) {
@@ -226,7 +368,7 @@ public class UpgradeActionOperations {
/**
* Gets the name of the property value to set if the configuration type is
- * {@link ConfigurationChangeType#SET}.
+ * {@link ChangeType#SET}
*
* @return the property value.
*/
diff --git
a/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeInformation.java
b/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeInformation.java
new file mode 100644
index 0000000..19de747
--- /dev/null
+++
b/ambari-server-spi/src/main/java/org/apache/ambari/spi/upgrade/UpgradeInformation.java
@@ -0,0 +1,131 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.spi.upgrade;
+
+import java.util.Map;
+
+import org.apache.ambari.spi.RepositoryVersion;
+
+/**
+ * The {@link UpgradeInformation} class contains information about a running
+ * upgrade or downgrade.
+ */
+public class UpgradeInformation {
+
+ /**
+ * {@code true} if the direction is upgrade, {@code false} if it is a
+ * downgrade.
+ */
+ private final boolean m_isUpgrade;
+
+ /**
+ * The orchestration type of the upgrade.
+ */
+ private final UpgradeType m_upgradeType;
+
+ /**
+ * The target version of the upgrade or downgrade.
+ */
+ private final RepositoryVersion m_targetVersion;
+
+ /**
+ * The source version of every service in the upgrade.
+ */
+ private final Map<String, RepositoryVersion> m_sourceVersions;
+
+ /**
+ * The target version of every service in the upgrade.
+ */
+ private final Map<String, RepositoryVersion> m_targetVersions;
+
+ /**
+ * Constructor.
+ *
+ * @param isUpgrade
+ * {@code true} if this is an upgrade, {@code false} otherwise.
+ * @param upgradeType
+ * the orchestration type of the upgrade.
+ * @param targetVersion
+ * the target version for all services and components in the upgrade
+ * or downgrade. If this is an upgrade, then this is the version tha
+ * all services are moving to. If this is a downgrade, then this is
+ * the version that all services are coming back from.
+ * @param sourceVersions
+ * the versions that all services and components are coming from.
+ * @param targetVersions
+ * the versions that all services and components in the upgrade are
+ * moving to.
+ */
+ public UpgradeInformation(boolean isUpgrade, UpgradeType upgradeType,
+ RepositoryVersion targetVersion, Map<String, RepositoryVersion>
sourceVersions,
+ Map<String, RepositoryVersion> targetVersions) {
+ m_isUpgrade = isUpgrade;
+ m_upgradeType = upgradeType;
+ m_targetVersion = targetVersion;
+ m_sourceVersions = sourceVersions;
+ m_targetVersions = targetVersions;
+ }
+
+ /**
+ * {@code true} if this is an upgrade, {@code false} otherwise.
+ *
+ * @return the upgrade direction.
+ */
+ public boolean isUpgrade() {
+ return m_isUpgrade;
+ }
+
+ /**
+ * The orchestration type of the upgrade.
+ *
+ * @return the orchestration type.
+ */
+ public UpgradeType getUpgradeType() {
+ return m_upgradeType;
+ }
+
+ /**
+ * The target version for all services and components in the upgrade or
+ * downgrade. If this is an upgrade, then this is the version tha all
services
+ * are moving to. If this is a downgrade, then this is the version that all
+ * services are coming back from.
+ *
+ * @return the target versions for all services.
+ */
+ public RepositoryVersion getRepositoryVersion() {
+ return m_targetVersion;
+ }
+
+ /**
+ * The versions that all services and components are coming from.
+ *
+ * @return the source versions of all services.
+ */
+ public Map<String, RepositoryVersion> getSourceVersions() {
+ return m_sourceVersions;
+ }
+
+ /**
+ * The versions that all services and components in the upgrade are moving
to.
+ *
+ * @return the target versions for all services.
+ */
+ public Map<String, RepositoryVersion> getTargetVersions() {
+ return m_targetVersions;
+ }
+}
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
index 358de55..ef63538 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/RepositoryVersionEntity.java
@@ -47,16 +47,14 @@ import javax.persistence.UniqueConstraint;
import org.apache.ambari.annotations.Experimental;
import org.apache.ambari.annotations.ExperimentalFeature;
import org.apache.ambari.server.StaticallyInject;
-import org.apache.ambari.server.stack.upgrade.RepositoryVersionHelper;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.repository.VersionDefinitionXml;
import org.apache.ambari.spi.RepositoryType;
+import org.apache.ambari.spi.RepositoryVersion;
import org.apache.commons.lang.StringUtils;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
@Entity
@Table(name = "repo_version", uniqueConstraints = {
@@ -93,9 +91,6 @@ import com.google.inject.Provider;
query = "SELECT repositoryVersion FROM RepositoryVersionEntity
repositoryVersion WHERE repositoryVersion IN (SELECT DISTINCT
sd1.desiredRepositoryVersion FROM ServiceDesiredStateEntity sd1 WHERE
sd1.desiredRepositoryVersion IN ?1)") })
@StaticallyInject
public class RepositoryVersionEntity {
- @Inject
- private static Provider<RepositoryVersionHelper>
repositoryVersionHelperProvider;
-
@Id
@Column(name = "repo_version_id")
@GeneratedValue(strategy = GenerationType.TABLE, generator =
"repository_version_id_generator")
@@ -504,4 +499,14 @@ public class RepositoryVersionEntity {
repoOsEntity.setRepositoryVersionEntity(this);
}
}
+
+ /**
+ * Builds a {@link RepositoryVersion} instance type from this entity.
+ *
+ * @return a single POJO to represent this entity.
+ */
+ public RepositoryVersion getRepositoryVersion() {
+ return new RepositoryVersion(getId(), getStackName(), getStackVersion(),
+ getStackId().getStackId(), getVersion(), getType());
+ }
}
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AbstractUpgradeServerAction.java
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AbstractUpgradeServerAction.java
index ea4d007..52c85e1 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AbstractUpgradeServerAction.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AbstractUpgradeServerAction.java
@@ -19,6 +19,7 @@ package org.apache.ambari.server.serveraction.upgrades;
import org.apache.ambari.server.agent.stomp.AgentConfigsHolder;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.orm.dao.UpgradeDAO;
import org.apache.ambari.server.orm.entities.UpgradeEntity;
import org.apache.ambari.server.serveraction.AbstractServerAction;
@@ -27,6 +28,7 @@ import
org.apache.ambari.server.stack.upgrade.orchestrate.UpgradeContextFactory;
import org.apache.ambari.server.stack.upgrade.orchestrate.UpgradeHelper;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.StackInfo;
import com.google.gson.Gson;
@@ -64,6 +66,9 @@ public abstract class AbstractUpgradeServerAction extends
AbstractServerAction {
@Inject
private UpgradeContextFactory m_upgradeContextFactory;
+ /**
+ * Used for updating push data to the agents.
+ */
@Inject
protected AgentConfigsHolder agentConfigsHolder;
@@ -74,6 +79,19 @@ public abstract class AbstractUpgradeServerAction extends
AbstractServerAction {
protected Provider<AmbariMetaInfo> m_metainfoProvider;
/**
+ * Used for manipulting configurations, such as removing entire types and
+ * creating new ones.
+ */
+ @Inject
+ protected ConfigHelper m_configHelper;
+
+ /**
+ * Who knows what this is used for or why it even exists.
+ */
+ @Inject
+ protected AmbariManagementController m_amc;
+
+ /**
* Gets the injected instance of the {@link Gson} serializer/deserializer.
*
* @return the injected {@link Gson} instance.
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/PluginUpgradeServerAction.java
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/PluginUpgradeServerAction.java
index 839cd94..154352e 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/PluginUpgradeServerAction.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/PluginUpgradeServerAction.java
@@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
@@ -28,6 +29,7 @@ import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.actionmanager.HostRoleStatus;
import org.apache.ambari.server.agent.CommandReport;
import org.apache.ambari.server.serveraction.ServerAction;
+import org.apache.ambari.server.stack.upgrade.Direction;
import org.apache.ambari.server.stack.upgrade.UpgradePack;
import org.apache.ambari.server.stack.upgrade.orchestrate.UpgradeContext;
import org.apache.ambari.server.state.Cluster;
@@ -98,14 +100,15 @@ public class PluginUpgradeServerAction extends
AbstractUpgradeServerAction {
try {
ClusterInformation clusterInformation =
cluster.buildClusterInformation();
UpgradeActionOperations upgradeActionOperations =
upgradeAction.getOperations(
- clusterInformation);
+ clusterInformation, upgradeContext.buildUpgradeInformation());
// update configurations
- changeConfigurations(cluster,
upgradeActionOperations.getConfigurationChanges());
+ changeConfigurations(cluster,
upgradeActionOperations.getConfigurationChanges(), upgradeContext);
+ removeConfigurationTypes(cluster,
upgradeActionOperations.getConfigurationTypeRemovals());
standardOutput = "Successfully executed " + pluginClassName;
if(null != upgradeActionOperations.getStandardOutput()) {
- standardOutput =
upgradeActionOperations.getStandardOutput().toString();
+ standardOutput = upgradeActionOperations.getStandardOutput();
}
} catch (UpgradeActionException exception) {
LOG.error("Unable to run the upgrade action {}", pluginClassName,
exception);
@@ -124,22 +127,51 @@ public class PluginUpgradeServerAction extends
AbstractUpgradeServerAction {
}
/**
- * Updates configurations in the cluster.
+ * Updates configurations in the cluster. This will create new configuration
+ * types if changes are required for one which does not exist.
*
* @param cluster
* the cluster used to retrieve the configurations.
* @param configurationChanges
* the changes to make.
+ * @param upgradeContext
+ * upgrade information for the current upgrade or downgrade.
* @throws AmbariException
* if there was a problem determining what change to make or while
* making changes.
*/
private void changeConfigurations(Cluster cluster,
- List<ConfigurationChanges> configurationChanges)
+ List<ConfigurationChanges> configurationChanges, UpgradeContext
upgradeContext)
throws AmbariException {
+ if (null == configurationChanges) {
+ return;
+ }
+
for (ConfigurationChanges configTypeChanges : configurationChanges) {
String configType = configTypeChanges.getConfigType();
+
+ // the configuration could be null, so try to figure out if we're
creating
+ // it by checking all of the changes being made
Config config = cluster.getDesiredConfigByType(configType);
+ if (null == config) {
+ // no additions/updates, so just skip it entirely
+ if (configTypeChanges.isOnlyRemovals()) {
+ continue;
+ }
+
+ Direction direction = upgradeContext.getDirection();
+ String serviceVersionNote = String.format("%s %s %s",
direction.getText(true),
+ direction.getPreposition(),
upgradeContext.getRepositoryVersion().getVersion());
+
+ m_configHelper.createConfigType(cluster,
upgradeContext.getRepositoryVersion().getStackId(),
+ m_amc, configType, new HashMap<>(), m_amc.getAuthName(),
serviceVersionNote);
+
+ config = cluster.getDesiredConfigByType(configType);
+ if (null == config) {
+ throw new AmbariException(
+ String.format("Unable to create the % configuration type",
configType));
+ }
+ }
List<PropertyChange> propertyChanges =
configTypeChanges.getPropertyChanges();
for (PropertyChange propertyChange : propertyChanges) {
@@ -165,6 +197,27 @@ public class PluginUpgradeServerAction extends
AbstractUpgradeServerAction {
}
/**
+ * Remove the specified configuration types from the cluster.
+ *
+ * @param cluster
+ * the cluster to remove the configurations from.
+ * @param configurationTypeRemovals
+ * the types to remove.
+ * @throws AmbariException
+ * if there were problems removing the configuration types.
+ */
+ private void removeConfigurationTypes(Cluster cluster, Set<String>
configurationTypeRemovals)
+ throws AmbariException {
+ if (null == configurationTypeRemovals) {
+ return;
+ }
+
+ for (String configType : configurationTypeRemovals) {
+ m_configHelper.removeConfigsByType(cluster, configType);
+ }
+ }
+
+ /**
* Gets the fully qualified classname of the {@link UpgradeAction} class
which
* will be executed. This will look in the command parameters of the
execution
* command for {@link ServerAction#WRAPPED_CLASS_NAME}.
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/orchestrate/UpgradeContext.java
b/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/orchestrate/UpgradeContext.java
index d2e68bb..dc1cf8e 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/orchestrate/UpgradeContext.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/orchestrate/UpgradeContext.java
@@ -86,7 +86,9 @@ import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.repository.ClusterVersionSummary;
import org.apache.ambari.server.state.repository.VersionDefinitionXml;
import org.apache.ambari.spi.RepositoryType;
+import org.apache.ambari.spi.RepositoryVersion;
import org.apache.ambari.spi.upgrade.UpgradeCheckStatus;
+import org.apache.ambari.spi.upgrade.UpgradeInformation;
import org.apache.ambari.spi.upgrade.UpgradeType;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
@@ -1457,4 +1459,44 @@ public class UpgradeContext {
return packs.get(upgrade.getUpgradePackage());
}
+
+ /**
+ * Builds a {@link UpgradeInformation} instance from a {@link Cluster} where
+ * there is an upgrade in progress.
+ *
+ * @return the {@link UpgradeInformation} instance comprised of simple POJOs
+ * and SPI classes.
+ */
+ public UpgradeInformation buildUpgradeInformation() {
+ RepositoryVersionEntity targetRepositoryVersionEntity =
m_repositoryVersion;
+
+ Map<String, Service> clusterServices = m_cluster.getServices();
+ Map<String, RepositoryVersion> clusterServiceVersions = new HashMap<>();
+ if (null != clusterServices) {
+ for (Map.Entry<String, Service> serviceEntry :
clusterServices.entrySet()) {
+ Service service = serviceEntry.getValue();
+ RepositoryVersionEntity desiredRepositoryEntity =
service.getDesiredRepositoryVersion();
+ RepositoryVersion desiredRepositoryVersion =
desiredRepositoryEntity.getRepositoryVersion();
+
+ clusterServiceVersions.put(serviceEntry.getKey(),
desiredRepositoryVersion);
+ }
+ }
+
+ Map<String, RepositoryVersionEntity> sourceVersionEntites =
getSourceVersions();
+ Map<String, RepositoryVersionEntity> targetVersionEntites =
getTargetVersions();
+ Map<String, RepositoryVersion> sourceVersions = new HashMap<>();
+ Map<String, RepositoryVersion> targetVersions = new HashMap<>();
+
+ sourceVersionEntites.forEach(
+ (service, repositoryVersion) -> sourceVersions.put(service,
repositoryVersion.getRepositoryVersion()));
+
+ targetVersionEntites.forEach(
+ (service, repositoryVersion) -> targetVersions.put(service,
repositoryVersion.getRepositoryVersion()));
+
+ UpgradeInformation upgradeInformation = new UpgradeInformation(
+ getDirection().isUpgrade(), getType(),
+ targetRepositoryVersionEntity.getRepositoryVersion(), sourceVersions,
targetVersions);
+
+ return upgradeInformation;
+ }
}
\ No newline at end of file
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 897a433..e23c571 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
@@ -2950,12 +2950,7 @@ public class ClusterImpl implements Cluster {
for (Map.Entry<String, Service> serviceEntry :
clusterServices.entrySet()) {
Service service = serviceEntry.getValue();
RepositoryVersionEntity desiredRepositoryEntity =
service.getDesiredRepositoryVersion();
- StackId stackId = desiredRepositoryEntity.getStackId();
-
- RepositoryVersion desiredRepositoryVersion = new RepositoryVersion(
- desiredRepositoryEntity.getId(), stackId.getStackName(),
stackId.getStackVersion(),
- stackId.getStackId(), desiredRepositoryEntity.getVersion(),
- desiredRepositoryEntity.getType());
+ RepositoryVersion desiredRepositoryVersion =
desiredRepositoryEntity.getRepositoryVersion();
clusterServiceVersions.put(serviceEntry.getKey(),
desiredRepositoryVersion);
}
diff --git
a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/PluginUpgradeServerActionTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/PluginUpgradeServerActionTest.java
index 49b31af..cd88ff9 100644
---
a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/PluginUpgradeServerActionTest.java
+++
b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/PluginUpgradeServerActionTest.java
@@ -17,6 +17,7 @@
*/
package org.apache.ambari.server.serveraction.upgrades;
+import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
@@ -28,19 +29,26 @@ import java.util.Map;
import org.apache.ambari.server.agent.ExecutionCommand;
import org.apache.ambari.server.agent.stomp.AgentConfigsHolder;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.serveraction.ServerAction;
+import org.apache.ambari.server.stack.upgrade.Direction;
import org.apache.ambari.server.stack.upgrade.UpgradePack;
import org.apache.ambari.server.stack.upgrade.orchestrate.UpgradeContext;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.spi.ClusterInformation;
+import org.apache.ambari.spi.RepositoryType;
+import org.apache.ambari.spi.RepositoryVersion;
import org.apache.ambari.spi.exceptions.UpgradeActionException;
import org.apache.ambari.spi.upgrade.UpgradeAction;
import org.apache.ambari.spi.upgrade.UpgradeActionOperations;
import
org.apache.ambari.spi.upgrade.UpgradeActionOperations.ConfigurationChanges;
+import org.apache.ambari.spi.upgrade.UpgradeInformation;
import org.easymock.EasyMockSupport;
import org.junit.After;
import org.junit.Before;
@@ -59,11 +67,12 @@ public class PluginUpgradeServerActionTest extends
EasyMockSupport {
private static final String CLUSTER_NAME = "c1";
private static final String FOO_SITE = "foo-site";
+ private static final String AUTH_USERNAME = "admin";
private static final String CLASS_NAME = MockUpgradeAction.class.getName();
private final Map<String, String> m_commandParams = new HashMap<>();
- private final StackId m_mockStackId = createNiceMock(StackId.class);
+ private final StackId m_stackId = new StackId("FOO-STACK-1.0");
private final StackInfo m_mockStackInfo = createNiceMock(StackInfo.class);
private final Clusters m_mockClusters = createNiceMock(Clusters.class);
@@ -74,9 +83,14 @@ public class PluginUpgradeServerActionTest extends
EasyMockSupport {
private final UpgradePack m_mockUpgradePack =
createNiceMock(UpgradePack.class);
private final ClassLoader m_mockClassLoader =
createNiceMock(ClassLoader.class);
private final AmbariMetaInfo m_mockMetaInfo =
createNiceMock(AmbariMetaInfo.class);
+ private final AmbariManagementController m_mockController =
createNiceMock(AmbariManagementController.class);
- private final AgentConfigsHolder m_mockAgentConfigsHolder = createNiceMock(
- AgentConfigsHolder.class);
+ private final RepositoryVersion m_repositoryVersion = new
RepositoryVersion(1L, "FOO-STACK",
+ "1.0", "FOO-STACK-1.0", "1.0.0.0-b1", RepositoryType.STANDARD);
+
+ private final RepositoryVersionEntity m_mocRepoEntity =
createNiceMock(RepositoryVersionEntity.class);
+ private final AgentConfigsHolder m_mockAgentConfigsHolder =
createNiceMock(AgentConfigsHolder.class);
+ private final ConfigHelper m_mockConfigHelper =
createNiceMock(ConfigHelper.class);
private PluginUpgradeServerAction m_action;
@@ -84,7 +98,7 @@ public class PluginUpgradeServerActionTest extends
EasyMockSupport {
* @throws Exception
*/
@Before
- @SuppressWarnings("rawtypes")
+ @SuppressWarnings({ "rawtypes", "unchecked" })
public void before() throws Exception {
m_action =
PowerMock.createNicePartialMock(PluginUpgradeServerAction.class,
"getUpgradeContext",
"createCommandReport", "getClusters");
@@ -98,10 +112,21 @@ public class PluginUpgradeServerActionTest extends
EasyMockSupport {
m_action.m_clusters = m_mockClusters;
m_action.m_metainfoProvider = () -> m_mockMetaInfo;
+ m_action.m_amc = m_mockController;
+ m_action.m_configHelper = m_mockConfigHelper;
+
+ expect(m_mockController.getAuthName()).andReturn(AUTH_USERNAME).anyTimes();
+
+ expect(m_mocRepoEntity.getStackId()).andReturn(m_stackId).anyTimes();
+ expect(m_mocRepoEntity.getVersion()).andReturn("1.0.0.0-b1").anyTimes();
+
expect(m_mocRepoEntity.getRepositoryVersion()).andReturn(m_repositoryVersion).anyTimes();
expect(m_mockUpgradeContext.getUpgradePack()).andReturn(m_mockUpgradePack).atLeastOnce();
-
expect(m_mockUpgradePack.getOwnerStackId()).andReturn(m_mockStackId).atLeastOnce();
-
expect(m_mockMetaInfo.getStack(m_mockStackId)).andReturn(m_mockStackInfo).atLeastOnce();
+
expect(m_mockUpgradeContext.getDirection()).andReturn(Direction.UPGRADE).anyTimes();
+
expect(m_mockUpgradeContext.getRepositoryVersion()).andReturn(m_mocRepoEntity).anyTimes();
+
+
expect(m_mockUpgradePack.getOwnerStackId()).andReturn(m_stackId).atLeastOnce();
+
expect(m_mockMetaInfo.getStack(m_stackId)).andReturn(m_mockStackInfo).atLeastOnce();
expect(m_mockStackInfo.getLibraryClassLoader()).andReturn(m_mockClassLoader).atLeastOnce();
expect(m_action.getClusters()).andReturn(m_mockClusters).anyTimes();
@@ -110,17 +135,6 @@ public class PluginUpgradeServerActionTest extends
EasyMockSupport {
Class clazz = MockUpgradeAction.class;
expect(m_mockClassLoader.loadClass(CLASS_NAME)).andReturn(clazz).atLeastOnce();
-
expect(m_mockCluster.getDesiredConfigByType(FOO_SITE)).andReturn(m_mockConfig).once();
-
- Map<String, String> configUpdates = new HashMap<>();
- configUpdates.put("property-name", "property-value");
-
- m_mockConfig.updateProperties(configUpdates);
- expectLastCall().once();
-
- m_mockConfig.save();
- expectLastCall().once();
-
m_action.agentConfigsHolder = m_mockAgentConfigsHolder;
m_commandParams.put("clusterName", CLUSTER_NAME);
@@ -144,6 +158,53 @@ public class PluginUpgradeServerActionTest extends
EasyMockSupport {
*/
@Test
public void testExecute() throws Exception {
+ // mock out the config stuff
+
expect(m_mockCluster.getDesiredConfigByType(FOO_SITE)).andReturn(m_mockConfig).once();
+
+ Map<String, String> configUpdates = new HashMap<>();
+ configUpdates.put("property-name", "property-value");
+
+ m_mockConfig.updateProperties(configUpdates);
+ expectLastCall().once();
+
+ m_mockConfig.save();
+ expectLastCall().once();
+
+ PowerMock.replay(m_action);
+ replayAll();
+
+ m_action.execute(null);
+
+ // easymock verify
+ verifyAll();
+ }
+
+ /**
+ * Tests that when a new configuration type is specified in the list of
+ * configurattion changes, that the new type is created first.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testExecuteAddNewConfiguration() throws Exception {
+ // mock two different answers
+
expect(m_mockCluster.getDesiredConfigByType(FOO_SITE)).andReturn(null).once();
+
expect(m_mockCluster.getDesiredConfigByType(FOO_SITE)).andReturn(m_mockConfig).once();
+
+ m_mockConfigHelper.createConfigType(eq(m_mockCluster), eq(m_stackId),
eq(m_mockController),
+ eq(FOO_SITE), eq(new HashMap<>()), eq(AUTH_USERNAME), eq("Upgrade to
1.0.0.0-b1"));
+
+ expectLastCall();
+
+ Map<String, String> configUpdates = new HashMap<>();
+ configUpdates.put("property-name", "property-value");
+
+ m_mockConfig.updateProperties(configUpdates);
+ expectLastCall().once();
+
+ m_mockConfig.save();
+ expectLastCall().once();
+
PowerMock.replay(m_action);
replayAll();
@@ -162,18 +223,18 @@ public class PluginUpgradeServerActionTest extends
EasyMockSupport {
* {@inheritDoc}
*/
@Override
- public UpgradeActionOperations getOperations(ClusterInformation
clusterInformation)
- throws UpgradeActionException {
+ public UpgradeActionOperations getOperations(ClusterInformation
clusterInformation,
+ UpgradeInformation upgradeInformation) throws UpgradeActionException {
List<ConfigurationChanges> allChanges = new ArrayList<>();
ConfigurationChanges configurationTypeChanges = new
ConfigurationChanges(FOO_SITE);
configurationTypeChanges.set( "property-name", "property-value");
allChanges.add(configurationTypeChanges);
- StringBuilder standardOutput = new StringBuilder("Standard Output");
-
UpgradeActionOperations upgradeActionOperations = new
UpgradeActionOperations();
-
upgradeActionOperations.setConfigurationChanges(allChanges).setStandardOutput(standardOutput);
+ upgradeActionOperations
+ .setConfigurationChanges(allChanges)
+ .setStandardOutput("Standard Output");
return upgradeActionOperations;
}