This is an automated email from the ASF dual-hosted git repository.
benyoka pushed a commit to branch branch-feature-AMBARI-14714
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/branch-feature-AMBARI-14714 by
this push:
new deac5ab [AMBARI-24657] Fix exception in blueprint deployment with
host group configs (#2355)
deac5ab is described below
commit deac5ab3030109681f5fe80401de45363e40a7c0
Author: benyoka <[email protected]>
AuthorDate: Mon Sep 24 22:09:15 2018 +0200
[AMBARI-24657] Fix exception in blueprint deployment with host group
configs (#2355)
* AMBARI-24657 WIP (benyoka)
* AMBARI-24657 Blueprint install with host group configs (benyoka)
* AMBARI-24657 fixe review comment (benyoka)
* AMBARI-24657 fixed unit tests (benyoka)
---
.../controller/AmbariManagementControllerImpl.java | 10 ++-
.../server/controller/internal/CompositeStack.java | 18 ++----
.../ambari/server/controller/internal/Stack.java | 9 +++
.../controller/internal/StackDefinition.java | 6 ++
.../org/apache/ambari/server/state/Cluster.java | 17 ++++--
.../ambari/server/state/cluster/ClusterImpl.java | 43 ++++---------
.../server/state/configgroup/ConfigGroupImpl.java | 18 ++++--
.../ambari/server/topology/AmbariContext.java | 48 ++++++---------
.../ambari/server/utils/CollectionUtils.java | 71 ++++++++++++++++++++++
.../controller/internal/CompositeStackTest.java | 19 ++++++
.../server/controller/internal/StackTest.java | 54 +++++++++++++++-
.../ambari/server/state/ConfigGroupTest.java | 11 +++-
.../ambari/server/topology/AmbariContextTest.java | 4 +-
13 files changed, 242 insertions(+), 86 deletions(-)
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 2b3bff2..ba6f902 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -69,6 +69,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -1160,7 +1161,10 @@ public class AmbariManagementControllerImpl implements
AmbariManagementControlle
Config config = configFactory.createNew(stackId, cluster, type,
versionTag, properties,
propertiesAttributes, serviceId);
-
+ // TODO: the constructor of ConfigImpl adds itself to the cluster so
calling this method
+ // should not be necessary. It causes some confusion with service instance
level configs
+ // (where a serviceId is present). The result of the extra addConfig()
call adds these configs
+ // to the cluster level configs too adding confusion.
cluster.addConfig(config);
return config;
}
@@ -1626,7 +1630,7 @@ public class AmbariManagementControllerImpl implements
AmbariManagementControlle
Config config = null;
//TODO : Remove after getting rid of cluster configurations
if (request.getServiceId() != null) {
- config = cluster.getConfigByServiceId(request.getType(),
request.getVersionTag(), request.getServiceId());
+ config = cluster.getConfig(request.getType(), request.getVersionTag(),
Optional.of(request.getServiceId()));
if (null != config) {
response = new ConfigurationResponse(
cluster.getClusterName(), config, request.getServiceId(),
request.getServiceGroupId());
@@ -1911,7 +1915,7 @@ public class AmbariManagementControllerImpl implements
AmbariManagementControlle
}
}
note = cr.getServiceConfigVersionNote();
- Config config = cluster.getConfig(configType, cr.getVersionTag());
+ Config config = cluster.getConfig(configType, cr.getVersionTag(),
Optional.ofNullable(cr.getServiceId()));
if (null != config) {
configs.add(config);
}
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompositeStack.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompositeStack.java
index 6c5e6ec..fa3d14c 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompositeStack.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/CompositeStack.java
@@ -243,18 +243,12 @@ public class CompositeStack implements StackDefinition {
@Override
public Stream<String> getServicesForConfigType(String config) {
- if (ConfigHelper.CLUSTER_ENV.equals(config)) { // for backwards
compatibility
- return Stream.empty();
- }
- return stacks.stream()
- .map(m -> {
- try {
- return m.getServiceForConfigType(config);
- } catch (IllegalArgumentException e) {
- return null;
- }
- })
- .filter(Objects::nonNull);
+ return stacks.stream().flatMap(s -> s.getServicesForConfigType(config));
+ }
+
+ @Override
+ public Stream<Pair<StackId, String>> getStackServicesForConfigType(String
config) {
+ return stacks.stream().flatMap(m ->
m.getStackServicesForConfigType(config));
}
@Override
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java
index 28d5ce0..e42dea7 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java
@@ -431,6 +431,9 @@ public class Stack implements StackDefinition {
@Override
public Stream<String> getServicesForConfigType(String config) {
+ if (ConfigHelper.CLUSTER_ENV.equals(config)) { // for backwards
compatibility
+ return Stream.empty();
+ }
return serviceConfigurations.entrySet().stream()
.filter(e -> e.getValue().containsKey(config))
.filter(e -> !getExcludedConfigurationTypes(e.getKey()).contains(config))
@@ -438,6 +441,12 @@ public class Stack implements StackDefinition {
}
@Override
+ public Stream<Pair<StackId, String>> getStackServicesForConfigType(String
config) {
+ return getServicesForConfigType(config).map(service ->
Pair.of(getStackId(), service));
+ }
+
+
+ @Override
public Collection<DependencyInfo> getDependenciesForComponent(String
component) {
return dependencies.containsKey(component) ? dependencies.get(component) :
Collections.emptySet();
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackDefinition.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackDefinition.java
index eb9a0ef..8f9029b 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackDefinition.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackDefinition.java
@@ -229,6 +229,12 @@ public interface StackDefinition {
Stream<String> getServicesForConfigType(String config);
/**
+ * @return stream of service names along with the id of their defining stack
which correspond
+ * to the specified configuration type name
+ */
+ Stream<Pair<StackId, String>> getStackServicesForConfigType(String config);
+
+ /**
* Return the dependencies specified for the given component.
*
* @param component component to get dependency information for
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 ca44b39..a04e5d6 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
@@ -23,8 +23,11 @@ import static java.util.stream.Collectors.toSet;
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
+import javax.annotation.Nonnull;
+
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ClusterSettingNotFoundException;
import org.apache.ambari.server.ServiceGroupNotFoundException;
@@ -415,6 +418,8 @@ public interface Cluster {
Map<PropertyInfo.PropertyType, Set<String>> getConfigPropertiesTypes(String
configType);
/**
+ * @deprecated {@link #getConfig(String, String, Optional)} should be
preferred
+ *
* Gets the specific config that matches the specified type and tag. This
not
* necessarily a DESIRED configuration that applies to a cluster.
*
@@ -423,19 +428,23 @@ public interface Cluster {
* @return a {@link Config} object, or <code>null</code> if the specific type
* and version have not been set.
*/
- Config getConfig(String configType, String versionTag);
+ @Deprecated
+ Config getConfig(@Nonnull String configType, @Nonnull String versionTag);
/**
- * Gets the specific config that matches the specified type and tag. This
not
+ * Gets the specific config that matches the specified type and tag. This not
* necessarily a DESIRED configuration that applies to a cluster.
*
+ * If {@code serviceId} is present, the config will be first looked up in
service instance level configs, when absent,
+ * cluster level configs will be searched.
+ *
* @param configType the config type to find
* @param versionTag the config version tag to find
- * @param serviceId the service for the config
+ * @param serviceId The optional serviceid. When present, the config will be
looked up from service leve configs
* @return a {@link Config} object, or <code>null</code> if the specific type
* and version have not been set.
*/
- Config getConfigByServiceId(String configType, String versionTag, Long
serviceId);
+ Config getConfig(@Nonnull String configType, @Nonnull String versionTag,
@Nonnull Optional<Long> serviceId);
/**
* Get latest (including inactive ones) configurations with any of the given
types.
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 d45b38d..2619e68 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
@@ -19,6 +19,7 @@
package org.apache.ambari.server.state.cluster;
import static java.util.stream.Collectors.toList;
+import static
org.apache.ambari.server.utils.CollectionUtils.emptyConcurrentMap;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -32,6 +33,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -42,6 +44,7 @@ import java.util.concurrent.locks.ReadWriteLock;
import java.util.function.Function;
import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.persistence.EntityManager;
import javax.persistence.RollbackException;
@@ -163,6 +166,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Functions;
+import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -1498,37 +1502,19 @@ public class ClusterImpl implements Cluster {
}
@Override
- public Config getConfig(String configType, String versionTag) {
- clusterGlobalLock.readLock().lock();
- try {
- if (!allConfigs.containsKey(configType)
- || !allConfigs.get(configType).containsKey(versionTag)) {
- return null;
- }
- return allConfigs.get(configType).get(versionTag);
- } finally {
- clusterGlobalLock.readLock().unlock();
- }
+ public Config getConfig(String configType, @Nonnull String versionTag) {
+ return getConfig(configType, versionTag, Optional.empty());
}
@Override
- public Config getConfigByServiceId(String configType, String versionTag,
Long serviceId) {
+ public Config getConfig(@Nonnull String configType, @Nonnull String
versionTag, @Nonnull Optional<Long> serviceId) {
clusterGlobalLock.readLock().lock();
try {
- if (!serviceConfigs.containsKey(serviceId)) {
- return null;
- }
- else {
- ConcurrentMap<String, ConcurrentMap<String, Config>> allServiceConfigs
= serviceConfigs.get(serviceId);
- if (!allServiceConfigs.containsKey(configType)
- || !allServiceConfigs.get(configType).containsKey(versionTag))
{
- return null;
- }
- return allServiceConfigs.get(configType).get(versionTag);
- }
- }
- finally {
- clusterGlobalLock.readLock().unlock();
+ ConcurrentMap<String, ConcurrentMap<String, Config>> configs =
+ serviceId.isPresent() ? serviceConfigs.getOrDefault(serviceId.get(),
emptyConcurrentMap()) : allConfigs;
+ return configs.getOrDefault(configType,
emptyConcurrentMap()).get(versionTag);
+ } finally {
+ clusterGlobalLock.readLock().unlock();
}
}
@@ -1610,10 +1596,7 @@ public class ClusterImpl implements Cluster {
@Override
public void addConfig(Config config) {
- if (config.getType() == null || config.getType().isEmpty()) {
- throw new IllegalArgumentException("Config type cannot be empty");
- }
-
+ Preconditions.checkArgument(config.getType() != null &&
!config.getType().isEmpty(), "Config type cannot be empty");
clusterGlobalLock.writeLock().lock();
try {
if (!allConfigs.containsKey(config.getType())) {
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java
b/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java
index e488086..c6c3fed 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/state/configgroup/ConfigGroupImpl.java
@@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -175,8 +176,10 @@ public class ConfigGroupImpl implements ConfigGroup {
// Populate configs
for (ConfigGroupConfigMappingEntity configMappingEntity :
configGroupEntity.getConfigGroupConfigMappingEntities()) {
- Config config = cluster.getConfig(configMappingEntity.getConfigType(),
- configMappingEntity.getVersionTag());
+ Config config = cluster.getConfig(
+ configMappingEntity.getConfigType(),
+ configMappingEntity.getVersionTag(),
+ Optional.ofNullable(serviceId));
if (config != null) {
m_configurations.put(config.getType(), config);
@@ -436,9 +439,16 @@ public class ConfigGroupImpl implements ConfigGroup {
if (clusterConfigEntity == null) {
Service service = cluster.getService(serviceId);
- //TODO check the serviceid = null for the right use case
config = configFactory.createNew(service.getStackId(), cluster,
config.getType(),
- config.getTag(), config.getProperties(),
config.getPropertiesAttributes(), null);
+ config.getTag(), config.getProperties(),
config.getPropertiesAttributes(), serviceId);
+ // TODO: the following line should not be here, adding only
temporarily for compatibility
+ // ClusterImpl keeps cluster level configs and service instance
level configs (those associated with
+ // a serviceId) separately. Most of current Ambari code only uses
cluster level configs. (TODO: fix it!)
+ // When a service instance level config is created using
AmbariManagementController.createConfig() it will
+ // be added to the cluster both as service level and cluster level
configs. To keep consistency with
+ // this behavior service level configs created here will too be
added as cluster level configs until
+ // this thing gets fixed.
+ cluster.addConfig(config);
entry.setValue(config);
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
index 4cb3333..730a3c5 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
@@ -25,6 +25,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
@@ -32,9 +33,9 @@ import java.util.TreeSet;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
-import javax.annotation.Nullable;
import javax.inject.Inject;
import org.apache.ambari.server.AmbariException;
@@ -92,9 +93,11 @@ import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.State;
import org.apache.ambari.server.state.configgroup.ConfigGroup;
import org.apache.ambari.server.utils.RetryHelper;
+import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
@@ -146,7 +149,6 @@ public class AmbariContext {
//todo: task id's. Use existing mechanism for getting next task id sequence
private final static AtomicLong nextTaskId = new AtomicLong(10000);
- static final String DEFAULT_SERVICE_GROUP_NAME = "default_service_group"; //
exposed for test
private static ClusterController clusterController;
private static HostRoleCommandFactory hostRoleCommandFactory;
@@ -160,7 +162,6 @@ public class AmbariContext {
private final static Logger LOG =
LoggerFactory.getLogger(AmbariContext.class);
-
/**
* When config groups are created using Blueprints these are created when
* hosts join a hostgroup and are added to the corresponding config group.
@@ -696,7 +697,8 @@ public class AmbariContext {
* and the hosts associated with the host group are assigned to the config
group.
*/
private void createConfigGroupsAndRegisterHost(ClusterTopology topology,
String groupName) throws AmbariException {
- Map<String, Map<String, Config>> groupConfigs = new HashMap<>();
+ // (StackId, Service) -> Config Type -> Config
+ Map<Pair<StackId, String>, Map<String, Config>> groupConfigs = new
HashMap<>();
StackDefinition stack = topology.getStack();
// get the host-group config with cluster creation template overrides
@@ -710,26 +712,21 @@ public class AmbariContext {
// iterate over topo host group configs which were defined in
for (Map.Entry<String, Map<String, String>> entry :
userProvidedGroupProperties.entrySet()) {
String type = entry.getKey();
- String service = stack.getServicesForConfigType(type)
- .filter(each -> topology.getServiceTypes().contains(each))
- .findFirst()
- // TODO check if this is required at all (might be handled by the
"orphan" removal)
- // TODO move this validation earlier
- .orElseThrow(() -> new IllegalArgumentException("Specified
configuration type is not associated with any service in the blueprint: " +
type));
-
- Config config = configFactory.createReadOnly(type, groupName,
entry.getValue(), null);
- //todo: attributes
- Map<String, Config> serviceConfigs = groupConfigs.get(service);
- if (serviceConfigs == null) {
- serviceConfigs = new HashMap<>();
- groupConfigs.put(service, serviceConfigs);
- }
- serviceConfigs.put(type, config);
+ List<Pair<StackId, String>> stackServices =
stack.getStackServicesForConfigType(type).
+ filter(each ->
topology.getServiceTypes().contains(each.getValue())).collect(Collectors.toList());
+ Preconditions.checkArgument(!stackServices.isEmpty(), "Specified
configuration type is not associated with any service in the blueprint: " +
type);
+ stackServices.forEach( stackService -> {
+ Config config = configFactory.createReadOnly(type, groupName,
entry.getValue(), null);
+ //todo: attributes
+ groupConfigs.computeIfAbsent(stackService, __ -> new
HashMap<>()).put(type, config);
+ });
}
String bpName = topology.getBlueprintName();
- for (Map.Entry<String, Map<String, Config>> entry :
groupConfigs.entrySet()) {
- String service = entry.getKey();
+ for (Map.Entry<Pair<StackId, String>, Map<String, Config>> entry :
groupConfigs.entrySet()) {
+ Pair<StackId, String> stackService = entry.getKey();
+ StackId stackId = entry.getKey().getLeft();
+ String service = entry.getKey().getRight();
Map<String, Config> serviceConfigs = entry.getValue();
String absoluteGroupName = getConfigurationGroupName(bpName, groupName);
Collection<String> groupHosts;
@@ -747,15 +744,10 @@ public class AmbariContext {
}
final Map<String, Host> clusterHosts =
getController().getClusters().getHostsForCluster(clusterName);
- Iterable<String> filteredGroupHosts = Iterables.filter(groupHosts, new
com.google.common.base.Predicate<String>() {
- @Override
- public boolean apply(@Nullable String groupHost) {
- return clusterHosts.containsKey(groupHost);
- }
- });
+ Iterable<String> filteredGroupHosts = Iterables.filter(groupHosts,
groupHost -> clusterHosts.containsKey(groupHost));
ConfigGroupRequest request = new ConfigGroupRequest(null, clusterName,
- absoluteGroupName, service, DEFAULT_SERVICE_GROUP_NAME, service, "Host
Group Configuration",
+ absoluteGroupName, service, stackId.getStackName(), service, "Host
Group Configuration",
Sets.newHashSet(filteredGroupHosts), serviceConfigs);
// get the config group provider and create config group resource
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/utils/CollectionUtils.java
b/ambari-server/src/main/java/org/apache/ambari/server/utils/CollectionUtils.java
new file mode 100644
index 0000000..d5e7828
--- /dev/null
+++
b/ambari-server/src/main/java/org/apache/ambari/server/utils/CollectionUtils.java
@@ -0,0 +1,71 @@
+/*
+ * 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.utils;
+
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Utilities for collections
+ */
+public class CollectionUtils {
+
+ /**
+ * Returns a singleton instance of an empty immutable {@link ConcurrentMap}
+ * @param <K> key type
+ * @param <V> value type
+ * @return a singleton instance of an empty immutable {@link ConcurrentMap}
+ */
+ public static <K, V> ConcurrentMap<K, V> emptyConcurrentMap() {
+ return (ConcurrentMap<K, V>)EmptyConcurrentMap.INSTANCE;
+ }
+
+
+ private static class EmptyConcurrentMap<K, V> extends AbstractMap<K, V>
implements ConcurrentMap<K, V> {
+ @SuppressWarnings({"rawtypes"})
+ private static final EmptyConcurrentMap INSTANCE = new
EmptyConcurrentMap();
+
+ @Override
+ public Set<Entry<K, V>> entrySet() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public boolean remove(Object key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean replace(K key, V oldValue, V newValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public V replace(K key, V newValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public V putIfAbsent(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompositeStackTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompositeStackTest.java
index 0561bb4..9ca6cf7 100644
---
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompositeStackTest.java
+++
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/CompositeStackTest.java
@@ -29,9 +29,12 @@ import java.util.Set;
import org.apache.ambari.server.stack.StackManager;
import org.apache.ambari.server.stack.StackManagerTest;
import org.apache.ambari.server.state.StackId;
+import org.apache.commons.lang3.tuple.Pair;
import org.junit.BeforeClass;
import org.junit.Test;
+import com.google.common.collect.ImmutableSet;
+
public class CompositeStackTest {
private static Set<Stack> elements;
@@ -66,6 +69,22 @@ public class CompositeStackTest {
}
@Test
+ public void getServicesByConfigType() {
+ assertEquals(
+ ImmutableSet.of("HDFS"),
+ composite.getServicesForConfigType("hdfs-site").collect(toSet()));
+ }
+
+ @Test
+ public void getStackServicesByConfigType() {
+ assertEquals(
+ ImmutableSet.of(
+ Pair.of(new StackId("HDP", "0.1"), "HDFS"),
+ Pair.of(new StackId("OTHER", "1.0"), "HDFS")),
+ composite.getStackServicesForConfigType("hdfs-site").collect(toSet()));
+ }
+
+ @Test
public void getComponents() {
Set<String> components = new HashSet<>(composite.getComponents());
for (Stack stack : elements) {
diff --git
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackTest.java
index e6794b8..f9a50f3 100644
---
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackTest.java
+++
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackTest.java
@@ -28,7 +28,9 @@ import static org.junit.Assert.assertSame;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.ambari.server.controller.StackLevelConfigurationResponse;
@@ -45,6 +47,7 @@ import org.easymock.EasyMockSupport;
import org.junit.Before;
import org.junit.Test;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
/**
@@ -57,6 +60,7 @@ public class StackTest {
private static final String STACK_CONFIG_FILE = STACK_CONFIG_TYPE + ".xml";
private static final String SERVICE_CONFIG_TYPE = "test-site";
private static final String SERVICE_CONFIG_FILE = SERVICE_CONFIG_TYPE +
".xml";
+ public static final String SERVICE_NAME = "some service";
private StackInfo stackInfo;
private ServiceInfo serviceInfo;
@@ -73,7 +77,7 @@ public class StackTest {
stackInfo.setVersion(STACK_ID.getStackVersion());
serviceInfo = new ServiceInfo();
- serviceInfo.setName("some service");
+ serviceInfo.setName(SERVICE_NAME);
stackInfo.getServices().add(serviceInfo);
componentInfo = new ComponentInfo();
@@ -136,6 +140,54 @@ public class StackTest {
}
@Test
+ public void getServicesForConfigType() throws Exception {
+ // GIVEN
+ Stack stack = new Stack(stackInfo);
+
+ // WHEN
+ List<String> services =
stack.getServicesForConfigType(SERVICE_CONFIG_TYPE).collect(Collectors.toList());
+
+ // THEN
+ assertEquals(ImmutableList.of(SERVICE_NAME), services);
+ }
+
+ @Test
+ public void getServicesForConfigType_ClusterEnv() throws Exception {
+ // GIVEN
+ Stack stack = new Stack(stackInfo);
+
+ // WHEN
+ List<String> services =
stack.getServicesForConfigType(STACK_CONFIG_TYPE).collect(Collectors.toList());
+
+ // THEN
+ assertEquals(ImmutableList.of(), services);
+ }
+
+ @Test
+ public void getStackServicesForConfigType() throws Exception {
+ // GIVEN
+ Stack stack = new Stack(stackInfo);
+
+ // WHEN
+ List<Pair<StackId, String>> stackServices =
stack.getStackServicesForConfigType(SERVICE_CONFIG_TYPE).collect(Collectors.toList());
+
+ // THEN
+ assertEquals(ImmutableList.of(Pair.of(STACK_ID, SERVICE_NAME)),
stackServices);
+ }
+
+ @Test
+ public void getStackServicesForConfigType_ClusterEnv() throws Exception {
+ // GIVEN
+ Stack stack = new Stack(stackInfo);
+
+ // WHEN
+ List<String> stackServices =
stack.getServicesForConfigType(STACK_CONFIG_TYPE).collect(Collectors.toList());
+
+ // THEN
+ assertEquals(ImmutableList.of(), stackServices);
+ }
+
+ @Test
public void getServicesForOwnStackId() throws Exception {
// GIVEN
Stack stack = new Stack(stackInfo);
diff --git
a/ambari-server/src/test/java/org/apache/ambari/server/state/ConfigGroupTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/state/ConfigGroupTest.java
index 3eb7ab6..0b2e9b8 100644
---
a/ambari-server/src/test/java/org/apache/ambari/server/state/ConfigGroupTest.java
+++
b/ambari-server/src/test/java/org/apache/ambari/server/state/ConfigGroupTest.java
@@ -32,6 +32,7 @@ import org.apache.ambari.server.orm.dao.ClusterServiceDAO;
import org.apache.ambari.server.orm.dao.ConfigGroupDAO;
import org.apache.ambari.server.orm.dao.ConfigGroupHostMappingDAO;
import org.apache.ambari.server.orm.dao.ServiceGroupDAO;
+import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
import org.apache.ambari.server.orm.entities.ClusterEntity;
import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
import org.apache.ambari.server.orm.entities.ConfigGroupConfigMappingEntity;
@@ -63,6 +64,7 @@ public class ConfigGroupTest {
private ClusterDAO clusterDAO;
private ClusterServiceDAO clusterServiceDAO;
private ServiceGroupDAO serviceGroupDAO;
+ private StackId stackId;
@Before
public void setup() throws Exception {
@@ -78,7 +80,7 @@ public class ConfigGroupTest {
clusterDAO = injector.getInstance(ClusterDAO.class);
serviceGroupDAO = injector.getInstance(ServiceGroupDAO.class);
- StackId stackId = new StackId("HDP-0.1");
+ stackId = new StackId("HDP-0.1");
OrmTestHelper helper = injector.getInstance(OrmTestHelper.class);
helper.createMpack(stackId);
@@ -107,7 +109,7 @@ public class ConfigGroupTest {
Map<String, String> attributes = new HashMap<>();
attributes.put("a", "true");
propertiesAttributes.put("final", attributes);
- Config config = configFactory.createNew(cluster, "hdfs-site",
"testversion", properties, propertiesAttributes);
+ Config config = configFactory.createNew(stackId, cluster, "hdfs-site",
"testversion", properties, propertiesAttributes, 1L);
Host host = clusters.getHost("h1");
@@ -130,6 +132,7 @@ public class ConfigGroupTest {
clusterServiceEntity.setServiceGroupEntity(serviceGroupEntity);
clusterServiceEntity.setServiceName("HDFS");
clusterServiceEntity.setServiceType("HDFS");
+ clusterServiceEntity.setServiceId(1L);
clusterServiceDAO.create(clusterServiceEntity);
ConfigGroup configGroup = configGroupFactory.createNew(cluster, 1L,
clusterServiceEntity.getServiceId(), "cg-test", "HDFS", "New HDFS configs for
h1", configs, hosts);
@@ -151,7 +154,9 @@ public class ConfigGroupTest {
Assert.assertNotNull(configMappingEntity);
Assert.assertEquals("hdfs-site", configMappingEntity.getConfigType());
Assert.assertEquals("testversion", configMappingEntity.getVersionTag());
- Assert.assertNotNull(configMappingEntity.getClusterConfigEntity());
+ ClusterConfigEntity clusterConfigEntity =
configMappingEntity.getClusterConfigEntity();
+ Assert.assertNotNull(clusterConfigEntity);
+ Assert.assertEquals(Long.valueOf(1L), clusterConfigEntity.getServiceId());
Assert.assertTrue(configMappingEntity
.getClusterConfigEntity().getData().contains("a"));
Assert.assertEquals("{\"final\":{\"a\":\"true\"}}", configMappingEntity
diff --git
a/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java
index 3ea53fc..0f8ea19 100644
---
a/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java
+++
b/ambari-server/src/test/java/org/apache/ambari/server/topology/AmbariContextTest.java
@@ -269,7 +269,9 @@ public class AmbariContextTest {
expect(stack.getVersion()).andReturn(STACK_VERSION).anyTimes();
for (Map.Entry<String, String> entry :
configTypeServiceMapping.entrySet()) {
-
expect(stack.getServicesForConfigType(entry.getKey())).andReturn(Stream.of(entry.getValue())).anyTimes();
+ expect(stack.getStackServicesForConfigType(entry.getKey()))
+ .andReturn( Stream.of(Pair.of(STACK_ID, entry.getValue())) )
+ .anyTimes();
}
expect(controller.getClusters()).andReturn(clusters).anyTimes();