You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2017/04/17 20:18:22 UTC
[28/34] ambari git commit: AMBARI-20755 topology configuration type
validation on blueprint deployments
AMBARI-20755 topology configuration type validation on blueprint deployments
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/103e49a8
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/103e49a8
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/103e49a8
Branch: refs/heads/branch-feature-AMBARI-12556
Commit: 103e49a899b57ff286889b8840e758c53bdaf1e8
Parents: 86c3058
Author: lpuskas <lp...@apache.org>
Authored: Wed Apr 12 18:43:47 2017 +0200
Committer: lpuskas <lp...@apache.org>
Committed: Fri Apr 14 16:01:10 2017 +0200
----------------------------------------------------------------------
.../internal/ExportBlueprintRequest.java | 6 -
.../internal/ProvisionClusterRequest.java | 21 +-
.../internal/ScaleClusterRequest.java | 7 -
.../ambari/server/topology/ClusterTopology.java | 2 +
.../server/topology/ClusterTopologyImpl.java | 37 +-
.../server/topology/PersistedStateImpl.java | 5 -
.../ambari/server/topology/TopologyManager.java | 43 +-
.../ambari/server/topology/TopologyRequest.java | 8 -
.../validators/ChainedTopologyValidator.java | 58 ++
.../validators/HiveServiceValidator.java | 2 +-
.../validators/RequiredPasswordValidator.java | 6 +-
.../validators/StackConfigTypeValidator.java | 64 ++
.../validators/TopologyValidatorFactory.java | 34 +
.../validators/TopologyValidatorService.java | 52 ++
.../BlueprintConfigurationProcessorTest.java | 660 ++++++++++---------
.../internal/ProvisionClusterRequestTest.java | 32 -
.../internal/ScaleClusterRequestTest.java | 6 -
.../ClusterDeployWithStartOnlyTest.java | 37 +-
...InstallWithoutStartOnComponentLevelTest.java | 33 +-
.../ClusterInstallWithoutStartTest.java | 37 +-
.../topology/ClusterTopologyImplTest.java | 57 +-
.../topology/RequiredPasswordValidatorTest.java | 113 +++-
.../server/topology/TopologyManagerTest.java | 5 +-
.../validators/HiveServiceValidatorTest.java | 3 +
.../StackConfigTypeValidatorTest.java | 126 ++++
25 files changed, 850 insertions(+), 604 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExportBlueprintRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExportBlueprintRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExportBlueprintRequest.java
index f24c138..19d9141 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExportBlueprintRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExportBlueprintRequest.java
@@ -47,7 +47,6 @@ import org.apache.ambari.server.topology.HostGroupImpl;
import org.apache.ambari.server.topology.HostGroupInfo;
import org.apache.ambari.server.topology.InvalidTopologyTemplateException;
import org.apache.ambari.server.topology.TopologyRequest;
-import org.apache.ambari.server.topology.TopologyValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -114,11 +113,6 @@ public class ExportBlueprintRequest implements TopologyRequest {
}
@Override
- public List<TopologyValidator> getTopologyValidators() {
- return Collections.emptyList();
- }
-
- @Override
public String getDescription() {
return String.format("Export Command For Cluster '%s'", clusterName);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java
index 1a14b01..de7883d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java
@@ -19,7 +19,6 @@ package org.apache.ambari.server.controller.internal;
import java.util.Collection;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -36,17 +35,12 @@ import org.apache.ambari.server.topology.HostGroupInfo;
import org.apache.ambari.server.topology.InvalidTopologyTemplateException;
import org.apache.ambari.server.topology.NoSuchBlueprintException;
import org.apache.ambari.server.topology.SecurityConfiguration;
-import org.apache.ambari.server.topology.TopologyValidator;
-import org.apache.ambari.server.topology.validators.ClusterConfigTypeValidator;
-import org.apache.ambari.server.topology.validators.HiveServiceValidator;
-import org.apache.ambari.server.topology.validators.RequiredPasswordValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Enums;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
/**
* Request for provisioning a cluster.
@@ -146,8 +140,6 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
private final String quickLinksProfileJson;
- private final List<TopologyValidator> topologyValidators;
-
private final static Logger LOG = LoggerFactory.getLogger(ProvisionClusterRequest.class);
/**
@@ -197,9 +189,6 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
} catch (QuickLinksProfileEvaluationException ex) {
throw new InvalidTopologyTemplateException("Invalid quick links profile", ex);
}
-
- topologyValidators = ImmutableList.of(new RequiredPasswordValidator(defaultPassword),
- new ClusterConfigTypeValidator(), new HiveServiceValidator());
}
private String processQuickLinksProfile(Map<String, Object> properties) throws QuickLinksProfileEvaluationException {
@@ -273,11 +262,6 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
}
@Override
- public List<TopologyValidator> getTopologyValidators() {
- return topologyValidators;
- }
-
- @Override
public String getDescription() {
return String.format("Provision Cluster '%s'", clusterName);
}
@@ -480,4 +464,9 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
public String getQuickLinksProfileJson() {
return quickLinksProfileJson;
}
+
+ public String getDefaultPassword() {
+ return defaultPassword;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java
index b5d2f9d..2a91bfe 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ScaleClusterRequest.java
@@ -20,7 +20,6 @@
package org.apache.ambari.server.controller.internal;
import java.util.Collections;
-import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -30,7 +29,6 @@ import org.apache.ambari.server.topology.Blueprint;
import org.apache.ambari.server.topology.Configuration;
import org.apache.ambari.server.topology.HostGroupInfo;
import org.apache.ambari.server.topology.InvalidTopologyTemplateException;
-import org.apache.ambari.server.topology.TopologyValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -90,11 +88,6 @@ public class ScaleClusterRequest extends BaseClusterRequest {
}
@Override
- public List<TopologyValidator> getTopologyValidators() {
- return Collections.emptyList();
- }
-
- @Override
public String getDescription() {
return String.format("Scale Cluster '%s' (+%s hosts)", clusterName, getTotalRequestedHostCount());
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopology.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopology.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopology.java
index e37c68d..639c406 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopology.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopology.java
@@ -178,4 +178,6 @@ public interface ClusterTopology {
*/
void removeHost(String hostname);
+ String getDefaultPassword();
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopologyImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopologyImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopologyImpl.java
index 37fb7d4..2ea904e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopologyImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/ClusterTopologyImpl.java
@@ -26,13 +26,13 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.controller.RequestStatusResponse;
import org.apache.ambari.server.controller.internal.ProvisionAction;
+import org.apache.ambari.server.controller.internal.ProvisionClusterRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -54,6 +54,7 @@ public class ClusterTopologyImpl implements ClusterTopology {
private Map<String, AdvisedConfiguration> advisedConfigurations = new HashMap<>();
private final Map<String, HostGroupInfo> hostGroupInfoMap = new HashMap<>();
private final AmbariContext ambariContext;
+ private final String defaultPassword;
private final static Logger LOG = LoggerFactory.getLogger(ClusterTopologyImpl.class);
@@ -65,26 +66,16 @@ public class ClusterTopologyImpl implements ClusterTopology {
// provision cluster currently requires that all hostgroups have same BP so it is ok to use root level BP here
this.blueprint = topologyRequest.getBlueprint();
this.configuration = topologyRequest.getConfiguration();
+ if (topologyRequest instanceof ProvisionClusterRequest) {
+ this.defaultPassword = ((ProvisionClusterRequest) topologyRequest).getDefaultPassword();
+ } else {
+ this.defaultPassword = null;
+ }
registerHostGroupInfo(topologyRequest.getHostGroupInfo());
- validateTopology(topologyRequest.getTopologyValidators());
- this.ambariContext = ambariContext;
- }
-
- //todo: only used in tests, remove. Validators not invoked when this constructor is used.
- public ClusterTopologyImpl(AmbariContext ambariContext,
- Long clusterId,
- Blueprint blueprint,
- Configuration configuration,
- Map<String, HostGroupInfo> hostGroupInfo)
- throws InvalidTopologyException {
-
- this.clusterId = clusterId;
- this.blueprint = blueprint;
- this.configuration = configuration;
-
- registerHostGroupInfo(hostGroupInfo);
+ // todo extract validation to specialized service
+ validateTopology();
this.ambariContext = ambariContext;
}
@@ -213,12 +204,9 @@ public class ClusterTopologyImpl implements ClusterTopology {
&& configProperties.get("yarn-site").get("yarn.resourcemanager.ha.enabled").equals("true");
}
- private void validateTopology(List<TopologyValidator> validators)
+ private void validateTopology()
throws InvalidTopologyException {
- for (TopologyValidator validator : validators) {
- validator.validate(this);
- }
if(isNameNodeHAEnabled()){
Collection<String> nnHosts = getHostAssignmentsForComponent("NAMENODE");
if (nnHosts.size() != 2) {
@@ -320,6 +308,11 @@ public class ClusterTopologyImpl implements ClusterTopology {
}
}
+ @Override
+ public String getDefaultPassword() {
+ return defaultPassword;
+ }
+
private void registerHostGroupInfo(Map<String, HostGroupInfo> requestedHostGroupInfoMap) throws InvalidTopologyException {
LOG.debug("Registering requested host group information for {} hostgroups", requestedHostGroupInfoMap.size());
checkForDuplicateHosts(requestedHostGroupInfoMap);
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java
index 2ac9950..36eb1bc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/PersistedStateImpl.java
@@ -20,7 +20,6 @@ package org.apache.ambari.server.topology;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -399,10 +398,6 @@ public class PersistedStateImpl implements PersistedState {
return hostGroupInfoMap;
}
- @Override
- public List<TopologyValidator> getTopologyValidators() {
- return Collections.emptyList();
- }
@Override
public String getDescription() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyManager.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyManager.java
index 392a53e..643945c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyManager.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyManager.java
@@ -74,6 +74,7 @@ import org.apache.ambari.server.state.host.HostImpl;
import org.apache.ambari.server.state.quicklinksprofile.QuickLinksProfile;
import org.apache.ambari.server.topology.tasks.ConfigureClusterTask;
import org.apache.ambari.server.topology.tasks.ConfigureClusterTaskFactory;
+import org.apache.ambari.server.topology.validators.TopologyValidatorService;
import org.apache.ambari.server.utils.RetryHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -89,7 +90,9 @@ import com.google.inject.persist.Transactional;
@Singleton
public class TopologyManager {
- /** internal token for topology related async tasks */
+ /**
+ * internal token for topology related async tasks
+ */
public static final String INTERNAL_AUTH_TOKEN = "internal_topology_token";
public static final String INITIAL_CONFIG_TAG = "INITIAL";
@@ -135,6 +138,9 @@ public class TopologyManager {
@Inject
private SettingDAO settingDAO;
+ @Inject
+ private TopologyValidatorService topologyValidatorService;
+
/**
* A boolean not cached thread-local (volatile) to prevent double-checked
* locking on the synchronized keyword.
@@ -264,32 +270,35 @@ public class TopologyManager {
// get the id prior to creating ambari resources which increments the counter
final Long provisionId = ambariContext.getNextRequestId();
- boolean configureSecurity = false;
+ SecurityType securityType = null;
+ Credential credential = null;
SecurityConfiguration securityConfiguration = processSecurityConfiguration(request);
if (securityConfiguration != null && securityConfiguration.getType() == SecurityType.KERBEROS) {
- configureSecurity = true;
+ securityType = SecurityType.KERBEROS;
addKerberosClient(topology);
// refresh default stack config after adding KERBEROS_CLIENT component to topology
- topology.getBlueprint().getConfiguration().setParentConfiguration(stack.getConfiguration(topology.getBlueprint
- ().getServices()));
-
- // create Cluster resource with security_type = KERBEROS, this will trigger cluster Kerberization
- // upon host install task execution
- ambariContext.createAmbariResources(topology, clusterName, SecurityType.KERBEROS, repoVersion);
- if (securityConfiguration.getDescriptor() != null) {
- submitKerberosDescriptorAsArtifact(clusterName, securityConfiguration.getDescriptor());
- }
+ topology.getBlueprint().getConfiguration().setParentConfiguration(stack.getConfiguration(topology.getBlueprint().getServices()));
- Credential credential = request.getCredentialsMap().get(KDC_ADMIN_CREDENTIAL);
+ credential = request.getCredentialsMap().get(KDC_ADMIN_CREDENTIAL);
if (credential == null) {
throw new InvalidTopologyException(KDC_ADMIN_CREDENTIAL + " is missing from request.");
}
+ }
+
+ topologyValidatorService.validateTopologyConfiguration(topology);
+
+ // create resources
+ ambariContext.createAmbariResources(topology, clusterName, securityType, repoVersion);
+
+ if (securityConfiguration != null && securityConfiguration.getDescriptor() != null) {
+ submitKerberosDescriptorAsArtifact(clusterName, securityConfiguration.getDescriptor());
+ }
+
+ if (credential != null) {
submitCredential(clusterName, credential);
- } else {
- ambariContext.createAmbariResources(topology, clusterName, null, repoVersion);
}
long clusterId = ambariContext.getClusterId(clusterName);
@@ -312,8 +321,8 @@ public class TopologyManager {
clusterTopologyMap.put(clusterId, topology);
- addClusterConfigRequest(topology, new ClusterConfigurationRequest(
- ambariContext, topology, true, stackAdvisorBlueprintProcessor, configureSecurity));
+ addClusterConfigRequest(topology, new ClusterConfigurationRequest(ambariContext, topology, true,
+ stackAdvisorBlueprintProcessor, securityType == SecurityType.KERBEROS));
// Notify listeners that cluster configuration finished
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequest.java
index cbc6642..4cadefa 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/TopologyRequest.java
@@ -18,7 +18,6 @@
package org.apache.ambari.server.topology;
-import java.util.List;
import java.util.Map;
/**
@@ -70,13 +69,6 @@ public interface TopologyRequest {
Map<String, HostGroupInfo> getHostGroupInfo();
/**
- * Get request topology validators.
- *
- * @return list of topology validators
- */
- List<TopologyValidator> getTopologyValidators();
-
- /**
* Get request description.
*
* @return string description of the request
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/ChainedTopologyValidator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/ChainedTopologyValidator.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/ChainedTopologyValidator.java
new file mode 100644
index 0000000..8bcbcff
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/ChainedTopologyValidator.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed 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.
+ */
+
+/*
+ * Licensed 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.topology.validators;
+
+import java.util.List;
+
+import org.apache.ambari.server.topology.ClusterTopology;
+import org.apache.ambari.server.topology.InvalidTopologyException;
+import org.apache.ambari.server.topology.TopologyValidator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Topology validator wrapper implementation. Executes a set of validations by calling a preconfgured set of validator implementations.
+ */
+public class ChainedTopologyValidator implements TopologyValidator {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ChainedTopologyValidator.class);
+ private List<TopologyValidator> validators;
+
+ public ChainedTopologyValidator(List<TopologyValidator> validators) {
+ this.validators = validators;
+ }
+
+ @Override
+ public void validate(ClusterTopology topology) throws InvalidTopologyException {
+ for (TopologyValidator validator : validators) {
+ LOGGER.info("Performing topology validation: {}", validator.getClass());
+ validator.validate(topology);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/HiveServiceValidator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/HiveServiceValidator.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/HiveServiceValidator.java
index 1351739..80b2593 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/HiveServiceValidator.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/HiveServiceValidator.java
@@ -59,7 +59,7 @@ public class HiveServiceValidator implements TopologyValidator {
}
// hive database settings need the mysql-server component in the blueprint
- if (!topology.getBlueprint().getServices().contains(MYSQL_SERVER_COMPONENT)) {
+ if (!topology.getBlueprint().getComponents(HIVE_SERVICE).contains(MYSQL_SERVER_COMPONENT)) {
String errorMessage = String.format("Component [%s] must explicitly be set in the blueprint when hive database " +
"is configured with the current settings. HIVE service validation failed.", MYSQL_SERVER_COMPONENT);
LOGGER.error(errorMessage);
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/RequiredPasswordValidator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/RequiredPasswordValidator.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/RequiredPasswordValidator.java
index 591a124..5b4ecc1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/RequiredPasswordValidator.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/RequiredPasswordValidator.java
@@ -33,10 +33,10 @@ import org.apache.ambari.server.topology.TopologyValidator;
*/
public class RequiredPasswordValidator implements TopologyValidator {
+ // todo remove the field as all the information is available in the topology being validated
private String defaultPassword;
- public RequiredPasswordValidator(String defaultPassword) {
- this.defaultPassword = defaultPassword;
+ public RequiredPasswordValidator() {
}
/**
@@ -46,6 +46,8 @@ public class RequiredPasswordValidator implements TopologyValidator {
* default is specified via 'default_password'
*/
public void validate(ClusterTopology topology) throws InvalidTopologyException {
+
+ defaultPassword = topology.getDefaultPassword();
Map<String, Map<String, Collection<String>>> missingPasswords = validateRequiredPasswords(topology);
if (! missingPasswords.isEmpty()) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/StackConfigTypeValidator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/StackConfigTypeValidator.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/StackConfigTypeValidator.java
new file mode 100644
index 0000000..f028a31
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/StackConfigTypeValidator.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed 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.topology.validators;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.ambari.server.topology.ClusterTopology;
+import org.apache.ambari.server.topology.InvalidTopologyException;
+import org.apache.ambari.server.topology.TopologyValidator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Validates whether incoming config types (form the blueprint or the cluster creation template) are valid.
+ * A configuration type is considered valid if the stack based on which the cluster is to be created contains such a
+ * config type.
+ */
+public class StackConfigTypeValidator implements TopologyValidator {
+ private static final Logger LOGGER = LoggerFactory.getLogger(StackConfigTypeValidator.class);
+
+ public StackConfigTypeValidator() {
+ }
+
+ @Override
+ public void validate(ClusterTopology topology) throws InvalidTopologyException {
+
+ // get the config types form the request
+ Set<String> incomingConfigTypes = new HashSet<>(topology.getConfiguration().getAllConfigTypes());
+
+ if (incomingConfigTypes.isEmpty()) {
+ LOGGER.debug("No config types to be checked.");
+ return;
+ }
+
+ Set<String> stackConfigTypes = new HashSet<>(topology.getBlueprint().getStack().getConfiguration().getAllConfigTypes());
+
+ // remove all "valid" config types from the incoming set
+ incomingConfigTypes.removeAll(stackConfigTypes);
+
+ if (!incomingConfigTypes.isEmpty()) {
+ // there are config types in the request that are not in the stack
+ String message = String.format("The following config types are not defined in the stack: %s ", incomingConfigTypes);
+ LOGGER.error(message);
+ throw new InvalidTopologyException(message);
+ }
+ }
+}
+
+
+
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/TopologyValidatorFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/TopologyValidatorFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/TopologyValidatorFactory.java
new file mode 100644
index 0000000..0e77301
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/TopologyValidatorFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed 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.topology.validators;
+
+import java.util.List;
+
+import org.apache.ambari.server.topology.TopologyValidator;
+
+import com.google.common.collect.ImmutableList;
+
+public class TopologyValidatorFactory {
+ List<TopologyValidator> validators;
+
+ public TopologyValidatorFactory() {
+ validators = ImmutableList.of(new RequiredPasswordValidator(), new HiveServiceValidator(), new StackConfigTypeValidator());
+ }
+
+ public TopologyValidator createConfigurationValidatorChain() {
+ return new ChainedTopologyValidator(validators);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/103e49a8/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/TopologyValidatorService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/TopologyValidatorService.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/TopologyValidatorService.java
new file mode 100644
index 0000000..425cf1e
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/validators/TopologyValidatorService.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed 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.topology.validators;
+
+import javax.inject.Inject;
+
+import org.apache.ambari.server.topology.ClusterTopology;
+import org.apache.ambari.server.topology.InvalidTopologyException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Service implementation dealing with topology validation.
+ * It's intended to manage cluster topology validation by grouping validators into different sets as it's imposed by the
+ * callee logic.
+ *
+ * Ideally this service should be used as instead of directly use validator implementations.
+ */
+public class TopologyValidatorService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(TopologyValidatorService.class);
+
+ @Inject
+ private TopologyValidatorFactory topologyValidatorFactory;
+
+ public TopologyValidatorService() {
+ }
+
+ public void validateTopologyConfiguration(ClusterTopology clusterTopology) throws InvalidTopologyException {
+ LOGGER.info("Validating cluster topology: {}", clusterTopology);
+ topologyValidatorFactory.createConfigurationValidatorChain().validate(clusterTopology);
+ }
+
+}
+
+
+
+
+
+