Repository: ambari Updated Branches: refs/heads/trunk ac1ba0e4f -> 524368b4a
AMBARI-10981. Upgrade Framework Must Be Able To Have Configuration Properties Renamed (ncole) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/524368b4 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/524368b4 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/524368b4 Branch: refs/heads/trunk Commit: 524368b4a1ba8297a1462a8f98c65653c0a527ad Parents: ac1ba0e Author: Nate Cole <nc...@hortonworks.com> Authored: Wed May 6 17:27:15 2015 -0400 Committer: Nate Cole <nc...@hortonworks.com> Committed: Thu May 7 07:05:23 2015 -0400 ---------------------------------------------------------------------- .../internal/UpgradeResourceProvider.java | 20 ++- .../serveraction/upgrades/ConfigureAction.java | 166 ++++++++++++++++--- .../state/stack/upgrade/ConfigureTask.java | 77 +++++++++ .../state/stack/upgrade/TransferOperation.java | 40 +++++ .../stacks/HDP/2.2/upgrades/upgrade-2.3.xml | 5 + .../upgrades/ConfigureActionTest.java | 112 ++++++++++++- .../server/state/stack/UpgradePackTest.java | 45 +++++ .../stacks/HDP/2.1.1/upgrades/upgrade_test.xml | 9 + 8 files changed, 446 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/524368b4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java index 99535c2..bdb2784 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java @@ -98,6 +98,7 @@ import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.Gson; import com.google.inject.Inject; import com.google.inject.Provider; @@ -190,6 +191,8 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider @Inject private static HostDAO s_hostDAO = null; + private static Gson s_gson = new Gson(); + /** * Used to generated the correct tasks and stages during an upgrade. @@ -1015,14 +1018,16 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider case CONFIGURE: { ConfigureTask ct = (ConfigureTask) task; Map<String, String> configProperties = ct.getConfigurationProperties(cluster); + List<ConfigureTask.Transfer> transfers = ct.getTransfers(); // if the properties are empty it means that the conditions in the // task did not pass; - if (configProperties.isEmpty()) { + if (configProperties.isEmpty() && transfers.isEmpty()) { stageText = "No conditions were met for this configuration task."; itemDetail = stageText; } else { commandParams.putAll(configProperties); + commandParams.put(ConfigureTask.PARAMETER_TRANSFERS, s_gson.toJson(transfers)); // extract the config type, key and value to use to build the // summary and detail @@ -1030,8 +1035,17 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider String key = configProperties.get(ConfigureTask.PARAMETER_KEY); String value = configProperties.get(ConfigureTask.PARAMETER_VALUE); - itemDetail = String.format("Updating config %s/%s to %s", configType, - key, value); + StringBuilder detail = new StringBuilder(String.format("Updating config %s", configType)); + + if (null != key && null != value) { + detail.append(String.format("/%s to %s", key, value)); + } + + if (!transfers.isEmpty()) { + detail.append(String.format("; transferring %d properties", transfers.size())); + } + + itemDetail = detail.toString(); if (null != ct.summary) { stageText = ct.summary; http://git-wip-us.apache.org/repos/asf/ambari/blob/524368b4/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java index df9d7be..a812169 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/ConfigureAction.java @@ -18,7 +18,10 @@ package org.apache.ambari.server.serveraction.upgrades; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentMap; @@ -34,10 +37,14 @@ 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.ConfigMergeHelper; +import org.apache.ambari.server.state.ConfigMergeHelper.ThreeWayValue; import org.apache.ambari.server.state.DesiredConfig; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.stack.upgrade.ConfigureTask; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import com.google.inject.Inject; /** @@ -70,7 +77,12 @@ public class ConfigureAction extends AbstractServerAction { * The Ambari configuration. */ @Inject - private Configuration configuration; + private Configuration m_configuration; + + @Inject + private ConfigMergeHelper m_mergeHelper; + + private Gson m_gson = new Gson(); /** * Aside from the normal execution, this method performs the following logic, with @@ -126,24 +138,31 @@ public class ConfigureAction extends AbstractServerAction { } String clusterName = commandParameters.get("clusterName"); + // such as hdfs-site or hbase-env + String configType = commandParameters.get(ConfigureTask.PARAMETER_CONFIG_TYPE); + String key = commandParameters.get(ConfigureTask.PARAMETER_KEY); String value = commandParameters.get(ConfigureTask.PARAMETER_VALUE); - // such as hdfs-site or hbase-env - String configType = commandParameters.get(ConfigureTask.PARAMETER_CONFIG_TYPE); + List<ConfigureTask.Transfer> transfers = Collections.emptyList(); + String transferJson = commandParameters.get(ConfigureTask.PARAMETER_TRANSFERS); + if (null != transferJson) { + transfers = m_gson.fromJson( + transferJson, new TypeToken<List<ConfigureTask.Transfer>>(){}.getType()); + } - // if the two required properties are null, then assume that no - // conditions were met and let the action complete - if (null == configType && null == key) { + // if the two required properties are null and no transfer properties, then + // assume that no conditions were met and let the action complete + if (null == configType && null == key && transfers.isEmpty()) { return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", "", "Skipping configuration task"); } - // if only 1 of the required properties was null, then something went - // wrong - if (null == clusterName || null == configType || null == key) { - String message = "cluster={0}, type={1}, key={2}"; - message = MessageFormat.format(message, clusterName, configType, key); + // if only 1 of the required properties was null and no transfer properties, + // then something went wrong + if (null == clusterName || null == configType || (null == key && transfers.isEmpty())) { + String message = "cluster={0}, type={1}, key={2}, transfers={3}"; + message = MessageFormat.format(message, clusterName, configType, key, transfers); return createCommandReport(0, HostRoleStatus.FAILED, "{}", "", message); } @@ -157,25 +176,88 @@ public class ConfigureAction extends AbstractServerAction { StackId targetStack = cluster.getDesiredStackVersion(); StackId configStack = config.getStackId(); - String oldValue = config.getProperties().get(key); - // !!! values are not changing, so make this a no-op - if (null != oldValue && value.equals(oldValue)) { - if (currentStack.equals(targetStack)) { - return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", - MessageFormat.format("{0}/{1} for cluster {2} would not change, skipping setting", - configType, key, clusterName), - ""); + // !!! initial reference values + Map<String, String> base = config.getProperties(); + Map<String, String> newValues = new HashMap<String, String>(base); + + boolean changedValues = false; + + // !!! do transfers first before setting defined values + for (ConfigureTask.Transfer transfer : transfers) { + switch (transfer.operation) { + case COPY: + if (null == transfer.fromType && base.containsKey(transfer.fromKey)) { + newValues.put(transfer.toKey, base.get(transfer.fromKey)); + changedValues = true; + } else { + // !!! copying from another configuration + Config other = cluster.getDesiredConfigByType(transfer.fromType); + + if (null != other) { + Map<String, String> otherValues = other.getProperties(); + + if (otherValues.containsKey(transfer.fromKey)) { + newValues.put(transfer.toKey, otherValues.get(transfer.fromKey)); + changedValues = true; + } + } + } + break; + case MOVE: + if (newValues.containsKey(transfer.fromKey)) { + newValues.put(transfer.toKey, newValues.remove(transfer.fromKey)); + changedValues = true; + } + + break; + case DELETE: + if ("*".equals(transfer.deleteKey)) { + newValues.clear(); + + for (String keeper : transfer.keepKeys) { + newValues.put(keeper, base.get(keeper)); + } + + // !!! with preserved edits, find the values that are different + // from the stack-defined and keep them + if (transfer.preserveEdits) { + List<String> edited = findChangedValues(clusterName, config); + for (String changed : edited) { + newValues.put(changed, base.get(changed)); + } + } + changedValues = true; + } else { + newValues.remove(transfer.deleteKey); + changedValues = true; + } + + break; } } - Map<String, String> propertiesToChange = new HashMap<String, String>(); - propertiesToChange.put(key, value); - config.updateProperties(propertiesToChange); + + if (null != key) { + String oldValue = base.get(key); + + // !!! values are not changing, so make this a no-op + if (null != oldValue && value.equals(oldValue)) { + if (currentStack.equals(targetStack) && !changedValues) { + return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", + MessageFormat.format("{0}/{1} for cluster {2} would not change, skipping setting", + configType, key, clusterName), + ""); + } + } + } + + newValues.put(key, value); // !!! check to see if we're going to a new stack and double check the // configs are for the target. Then simply update the new properties instead // of creating a whole new history record since it was already done if (!targetStack.equals(currentStack) && targetStack.equals(configStack)) { + config.setProperties(newValues); config.persist(false); return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", @@ -191,15 +273,51 @@ public class ConfigureAction extends AbstractServerAction { String auditName = getExecutionCommand().getRoleParams().get(ServerAction.ACTION_USER_NAME); if (auditName == null) { - auditName = configuration.getAnonymousAuditName(); + auditName = m_configuration.getAnonymousAuditName(); } m_configHelper.createConfigType(cluster, m_controller, configType, - config.getProperties(), auditName, serviceVersionNote); + newValues, auditName, serviceVersionNote); String message = "Updated ''{0}'' with ''{1}={2}''"; message = MessageFormat.format(message, configType, key, value); return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", message, ""); } + + + /** + * @param clusterName the cluster name + * @param config the config with the tag to find conflicts + * @return the list of changed property keys + * @throws AmbariException + */ + private List<String> findChangedValues(String clusterName, Config config) + throws AmbariException { + + Map<String, Map<String, ThreeWayValue>> conflicts = + m_mergeHelper.getConflicts(clusterName, config.getStackId()); + + Map<String, ThreeWayValue> conflictMap = conflicts.get(config.getType()); + + if (null == conflictMap || conflictMap.isEmpty()) { + return Collections.emptyList(); + } + + List<String> result = new ArrayList<String>(); + + for (Map.Entry<String, ThreeWayValue> entry : conflictMap.entrySet()) { + ThreeWayValue twv = entry.getValue(); + if (null == twv.oldStackValue) { + result.add(entry.getKey()); + } else if (null != twv.savedValue && !twv.oldStackValue.equals(twv.savedValue)) { + result.add(entry.getKey()); + } + } + + return result; + } + + + } http://git-wip-us.apache.org/repos/asf/ambari/blob/524368b4/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigureTask.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigureTask.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigureTask.java index d3cb366..1f921c9 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigureTask.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/ConfigureTask.java @@ -17,6 +17,8 @@ */ package org.apache.ambari.server.state.stack.upgrade; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -94,6 +96,12 @@ public class ConfigureTask extends ServerSideActionTask { public static final String PARAMETER_VALUE = "configure-task-value"; /** + * Transfers can be several per task, so they're passed in as a json-ified list of + * objects. + */ + public static final String PARAMETER_TRANSFERS = "configure-task-transfers"; + + /** * Constructor. * */ @@ -119,12 +127,23 @@ public class ConfigureTask extends ServerSideActionTask { @XmlElement(name = "condition") private List<Condition> conditions; + @XmlElement(name = "transfer") + private List<Transfer> transfers; + @Override public Type getType() { return type; } /** + * @return the config type + */ + public String getConfigType() { + return configType; + } + + + /** * A conditional element that will only perform the configuration if the * condition is met. */ @@ -151,6 +170,64 @@ public class ConfigureTask extends ServerSideActionTask { } /** + * A {@code transfer} element will copy, move, or delete the value of one type/key to another type/key. + */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "transfer") + public static class Transfer { + @XmlAttribute(name = "operation") + public TransferOperation operation; + + @XmlAttribute(name = "from-type") + public String fromType; + + @XmlAttribute(name = "from-key") + public String fromKey; + + @XmlAttribute(name = "to-key") + public String toKey; + + @XmlAttribute(name = "delete-key") + public String deleteKey; + + @XmlAttribute(name = "preserve-edits") + public boolean preserveEdits = false; + + @XmlElement(name = "keep-key") + public List<String> keepKeys = new ArrayList<String>(); + + } + + /** + * @return the list of transfers, checking for appropriate null fields. + */ + public List<Transfer> getTransfers() { + if (null == transfers) { + return Collections.<Transfer>emptyList(); + } + + List<Transfer> list = new ArrayList<Transfer>(); + for (Transfer t : transfers) { + switch (t.operation) { + case COPY: + case MOVE: + if (null != t.fromKey && null != t.toKey) { + list.add(t); + } + break; + case DELETE: + if (null != t.deleteKey) { + list.add(t); + } + + break; + } + } + + return list; + } + + /** * Gets a map containing the following properties pertaining to the * configuration value to change: * <ul> http://git-wip-us.apache.org/repos/asf/ambari/blob/524368b4/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/TransferOperation.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/TransferOperation.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/TransferOperation.java new file mode 100644 index 0000000..1ee2a35 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/TransferOperation.java @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ambari.server.state.stack.upgrade; + +/** + * Operations valid for a property transfer. + */ +public enum TransferOperation { + /** + * The property should be removed. Special case "*" to delete all + * properties that have NOT been overridden by a user. + */ + DELETE, + /** + * The property value is moved. A property may only be moved within the + * same config type. To move across types, perform a {@link #COPY} to the target then + * a {@link #DELETE} from the source config. + */ + MOVE, + /** + * The property value is copied from another property. A property may be copied from + * another config type. + */ + COPY +} http://git-wip-us.apache.org/repos/asf/ambari/blob/524368b4/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml index 8dccf65..225cc63 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml +++ b/ambari-server/src/main/resources/stacks/HDP/2.2/upgrades/upgrade-2.3.xml @@ -573,6 +573,11 @@ <task xsi:type="manual"> <message>Before continuing, please deactivate and kill any currently running topologies.</message> </task> + <task xsi:type="configure" summary="Setting nimbus.seeds from nimbus.host"> + <type>storm-site</type> + <transfer operation="COPY" from-key="nimbus.host" + to-type="storm-site" to-key="nimbus.seeds" /> + </task> </pre-upgrade> <upgrade> <task xsi:type="restart" /> http://git-wip-us.apache.org/repos/asf/ambari/blob/524368b4/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java index 391db55..ecd55db 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ConfigureActionTest.java @@ -18,10 +18,14 @@ package org.apache.ambari.server.serveraction.upgrades; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.ambari.server.actionmanager.ExecutionCommandWrapper; @@ -38,6 +42,7 @@ import org.apache.ambari.server.orm.dao.RepositoryVersionDAO; import org.apache.ambari.server.orm.dao.StackDAO; import org.apache.ambari.server.orm.entities.HostVersionEntity; import org.apache.ambari.server.orm.entities.StackEntity; +import org.apache.ambari.server.serveraction.ServerAction; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; import org.apache.ambari.server.state.Config; @@ -46,10 +51,12 @@ import org.apache.ambari.server.state.Host; import org.apache.ambari.server.state.RepositoryVersionState; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.stack.upgrade.ConfigureTask; +import org.apache.ambari.server.state.stack.upgrade.TransferOperation; import org.junit.After; import org.junit.Before; import org.junit.Test; +import com.google.gson.Gson; import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.Injector; @@ -207,8 +214,111 @@ public class ConfigureActionTest { assertNotNull(config); assertEquals("version2", config.getTag()); assertEquals("11", config.getProperties().get("initLimit")); - } + @Test + public void testConfigTransferCopy() throws Exception { + makeUpgradeCluster(); + + Cluster c = m_injector.getInstance(Clusters.class).getCluster("c1"); + assertEquals(1, c.getConfigsByType("zoo.cfg").size()); + + c.setDesiredStackVersion(HDP_21_STACK); + ConfigFactory cf = m_injector.getInstance(ConfigFactory.class); + Config config = cf.createNew(c, "zoo.cfg", new HashMap<String, String>() {{ + put("initLimit", "10"); + put("copyIt", "10"); + put("moveIt", "10"); + put("deleteIt", "10"); + }}, new HashMap<String, Map<String,String>>()); + config.setTag("version2"); + config.persist(); + + c.addConfig(config); + c.addDesiredConfig("user", Collections.singleton(config)); + assertEquals(2, c.getConfigsByType("zoo.cfg").size()); + + + Map<String, String> commandParams = new HashMap<String, String>(); + commandParams.put("upgrade_direction", "upgrade"); + commandParams.put("version", HDP_2_2_1_0); + commandParams.put("clusterName", "c1"); + commandParams.put(ConfigureTask.PARAMETER_CONFIG_TYPE, "zoo.cfg"); + commandParams.put(ConfigureTask.PARAMETER_KEY, "initLimit"); + commandParams.put(ConfigureTask.PARAMETER_VALUE, "11"); + + List<ConfigureTask.Transfer> transfers = new ArrayList<ConfigureTask.Transfer>(); + ConfigureTask.Transfer transfer = new ConfigureTask.Transfer(); + transfer.operation = TransferOperation.COPY; + transfer.fromKey = "copyIt"; + transfer.toKey = "copyKey"; + transfers.add(transfer); + + transfer = new ConfigureTask.Transfer(); + transfer.operation = TransferOperation.MOVE; + transfer.fromKey = "moveIt"; + transfer.toKey = "movedKey"; + transfers.add(transfer); + + transfer = new ConfigureTask.Transfer(); + transfer.operation = TransferOperation.DELETE; + transfer.deleteKey = "deleteIt"; + transfers.add(transfer); + + commandParams.put(ConfigureTask.PARAMETER_TRANSFERS, new Gson().toJson(transfers)); + + ExecutionCommand executionCommand = new ExecutionCommand(); + executionCommand.setCommandParams(commandParams); + executionCommand.setClusterName("c1"); + executionCommand.setRoleParams(new HashMap<String, String>()); + executionCommand.getRoleParams().put(ServerAction.ACTION_USER_NAME, "username"); + + HostRoleCommand hostRoleCommand = hostRoleCommandFactory.create(null, null, + null, null); + + hostRoleCommand.setExecutionCommandWrapper(new ExecutionCommandWrapper( + executionCommand)); + + ConfigureAction action = m_injector.getInstance(ConfigureAction.class); + action.setExecutionCommand(executionCommand); + action.setHostRoleCommand(hostRoleCommand); + + CommandReport report = action.execute(null); + assertNotNull(report); + + assertEquals(3, c.getConfigsByType("zoo.cfg").size()); + + config = c.getDesiredConfigByType("zoo.cfg"); + assertNotNull(config); + assertFalse("version2".equals(config.getTag())); + + Map<String, String> map = config.getProperties(); + assertEquals("11", map.get("initLimit")); + assertEquals("10", map.get("copyIt")); + assertTrue(map.containsKey("copyKey")); + assertEquals(map.get("copyIt"), map.get("copyKey")); + assertFalse(map.containsKey("moveIt")); + assertTrue(map.containsKey("movedKey")); + assertFalse(map.containsKey("deletedKey")); + + transfers.clear(); + transfer = new ConfigureTask.Transfer(); + transfer.operation = TransferOperation.DELETE; + transfer.deleteKey = "*"; + transfer.preserveEdits = true; + transfer.keepKeys.add("copyKey"); + transfers.add(transfer); + commandParams.put(ConfigureTask.PARAMETER_TRANSFERS, new Gson().toJson(transfers)); + + report = action.execute(null); + assertNotNull(report); + + assertEquals(4, c.getConfigsByType("zoo.cfg").size()); + config = c.getDesiredConfigByType("zoo.cfg"); + map = config.getProperties(); + assertEquals(2, map.size()); + assertTrue(map.containsKey("initLimit")); // it just changed to 11 from 10 + assertTrue(map.containsKey("copyKey")); // is new + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/524368b4/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java index 1701a33..cdde452 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/state/stack/UpgradePackTest.java @@ -34,10 +34,13 @@ import org.apache.ambari.server.orm.InMemoryDefaultTestModule; import org.apache.ambari.server.state.stack.UpgradePack.ProcessingComponent; import org.apache.ambari.server.state.stack.upgrade.ClusterGrouping; import org.apache.ambari.server.state.stack.upgrade.ClusterGrouping.ExecuteStage; +import org.apache.ambari.server.state.stack.upgrade.ConfigureTask; +import org.apache.ambari.server.state.stack.upgrade.ConfigureTask.Transfer; import org.apache.ambari.server.state.stack.upgrade.Direction; import org.apache.ambari.server.state.stack.upgrade.Grouping; import org.apache.ambari.server.state.stack.upgrade.RestartTask; import org.apache.ambari.server.state.stack.upgrade.Task; +import org.apache.ambari.server.state.stack.upgrade.TransferOperation; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -140,6 +143,48 @@ public class UpgradePackTest { assertEquals(1, pc.postTasks.size()); assertNotNull(pc.tasks); assertEquals(1, pc.tasks.size()); + + pc = up.getTasks().get("YARN").get("NODEMANAGER"); + assertNotNull(pc.preTasks); + assertEquals(2, pc.preTasks.size()); + Task t = pc.preTasks.get(1); + assertEquals(ConfigureTask.class, t.getClass()); + ConfigureTask ct = (ConfigureTask) t; + assertEquals("core-site", ct.getConfigType()); + assertEquals(4, ct.getTransfers().size()); + + /* + <transfer operation="COPY" from-key="copy-key" to-key="copy-key-to" /> + <transfer operation="COPY" from-type="my-site" from-key="my-copy-key" to-key="my-copy-key-to" /> + <transfer operation="MOVE" from-key="move-key" to-key="move-key-to" /> + <transfer operation="DELETE" delete-key="delete-key"> + <keep-key>important-key</keep-key> + </transfer> + */ + Transfer t1 = ct.getTransfers().get(0); + assertEquals(TransferOperation.COPY, t1.operation); + assertEquals("copy-key", t1.fromKey); + assertEquals("copy-key-to", t1.toKey); + + Transfer t2 = ct.getTransfers().get(1); + assertEquals(TransferOperation.COPY, t2.operation); + assertEquals("my-site", t2.fromType); + assertEquals("my-copy-key", t2.fromKey); + assertEquals("my-copy-key-to", t2.toKey); + assertTrue(t2.keepKeys.isEmpty()); + + Transfer t3 = ct.getTransfers().get(2); + assertEquals(TransferOperation.MOVE, t3.operation); + assertEquals("move-key", t3.fromKey); + assertEquals("move-key-to", t3.toKey); + + Transfer t4 = ct.getTransfers().get(3); + assertEquals(TransferOperation.DELETE, t4.operation); + assertEquals("delete-key", t4.deleteKey); + assertNull(t4.toKey); + assertTrue(t4.preserveEdits); + assertEquals(1, t4.keepKeys.size()); + assertEquals("important-key", t4.keepKeys.get(0)); } @Test http://git-wip-us.apache.org/repos/asf/ambari/blob/524368b4/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test.xml b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test.xml index 088d15f..32c419b 100644 --- a/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test.xml +++ b/ambari-server/src/test/resources/stacks/HDP/2.1.1/upgrades/upgrade_test.xml @@ -183,6 +183,15 @@ <task xsi:type="execute"> <command>ls</command> </task> + <task xsi:type="configure"> + <type>core-site</type> + <transfer operation="COPY" from-key="copy-key" to-key="copy-key-to" /> + <transfer operation="COPY" from-type="my-site" from-key="my-copy-key" to-key="my-copy-key-to" /> + <transfer operation="MOVE" from-key="move-key" to-key="move-key-to" /> + <transfer operation="DELETE" delete-key="delete-key" preserve-edits="true"> + <keep-key>important-key</keep-key> + </transfer> + </task> </pre-upgrade> </component> </service>