ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lpus...@apache.org
Subject [3/3] ambari git commit: AMBARI-20755 topology configuration type validation on blueprint deployments
Date Fri, 14 Apr 2017 19:13:40 GMT
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/a9cda4f1
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a9cda4f1
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a9cda4f1

Branch: refs/heads/branch-2.5
Commit: a9cda4f1f82aa0f42aa3fb7ddee5947ef2dab603
Parents: 80e3cf0
Author: lpuskas <lpuskas@apache.org>
Authored: Wed Apr 12 18:43:47 2017 +0200
Committer: lpuskas <lpuskas@apache.org>
Committed: Fri Apr 14 18:50:54 2017 +0200

----------------------------------------------------------------------
 .../internal/ExportBlueprintRequest.java        |    6 -
 .../internal/ProvisionClusterRequest.java       |   21 +-
 .../internal/ScaleClusterRequest.java           |    7 -
 .../ambari/server/topology/ClusterTopology.java |    2 +
 .../server/topology/ClusterTopologyImpl.java    |   57 +-
 .../server/topology/PersistedStateImpl.java     |   40 +-
 .../ambari/server/topology/TopologyManager.java |   43 +-
 .../ambari/server/topology/TopologyRequest.java |   22 +-
 .../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    | 2338 +++++++++---------
 .../internal/ProvisionClusterRequestTest.java   |   32 -
 .../internal/ScaleClusterRequestTest.java       |    6 -
 .../ClusterDeployWithStartOnlyTest.java         |   78 +-
 ...InstallWithoutStartOnComponentLevelTest.java |   73 +-
 .../ClusterInstallWithoutStartTest.java         |   78 +-
 .../topology/ClusterTopologyImplTest.java       |  100 +-
 .../topology/RequiredPasswordValidatorTest.java |  113 +-
 .../server/topology/TopologyManagerTest.java    |    5 +-
 .../validators/HiveServiceValidatorTest.java    |    3 +
 .../StackConfigTypeValidatorTest.java           |  126 +
 25 files changed, 1806 insertions(+), 1560 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/a9cda4f1/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 4d8e56f..d705b46 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
@@ -36,7 +36,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/a9cda4f1/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/a9cda4f1/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/a9cda4f1/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 de99518..b309f5a 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/a9cda4f1/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 e5568be..45f4811 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
@@ -19,23 +19,23 @@
 
 package org.apache.ambari.server.topology;
 
+import static org.apache.ambari.server.controller.internal.ProvisionAction.INSTALL_AND_START;
+import static org.apache.ambari.server.controller.internal.ProvisionAction.INSTALL_ONLY;
+
 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;
 
-import static org.apache.ambari.server.controller.internal.ProvisionAction.INSTALL_AND_START;
-import static org.apache.ambari.server.controller.internal.ProvisionAction.INSTALL_ONLY;
-
 /**
  * Represents a cluster topology.
  * Topology includes the the associated blueprint, cluster configuration and hostgroup ->
host mapping.
@@ -51,9 +51,10 @@ public class ClusterTopologyImpl implements ClusterTopology {
   private Configuration configuration;
   private ConfigRecommendationStrategy configRecommendationStrategy;
   private ProvisionAction provisionAction = ProvisionAction.INSTALL_AND_START;
-  private Map<String, AdvisedConfiguration> advisedConfigurations = new HashMap<String,
AdvisedConfiguration>();
-  private final Map<String, HostGroupInfo> hostGroupInfoMap = new HashMap<String,
HostGroupInfo>();
+  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,14 @@ 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);
     this.ambariContext = ambariContext;
   }
 
@@ -121,7 +110,7 @@ public class ClusterTopologyImpl implements ClusterTopology {
   //todo: do we want to return groups with no requested hosts?
   @Override
   public Collection<String> getHostGroupsForComponent(String component) {
-    Collection<String> resultGroups = new ArrayList<String>();
+    Collection<String> resultGroups = new ArrayList<>();
     for (HostGroup group : getBlueprint().getHostGroups().values() ) {
       if (group.getComponentNames().contains(component)) {
         resultGroups.add(group.getName());
@@ -173,7 +162,7 @@ public class ClusterTopologyImpl implements ClusterTopology {
   @Override
   public Collection<String> getHostAssignmentsForComponent(String component) {
     //todo: ordering requirements?
-    Collection<String> hosts = new ArrayList<String>();
+    Collection<String> hosts = new ArrayList<>();
     Collection<String> hostGroups = getHostGroupsForComponent(component);
     for (String group : hostGroups) {
       HostGroupInfo hostGroupInfo = getHostGroupInfo().get(group);
@@ -213,13 +202,6 @@ public class ClusterTopologyImpl implements ClusterTopology {
       && configProperties.get("yarn-site").get("yarn.resourcemanager.ha.enabled").equals("true");
   }
 
-  private void validateTopology(List<TopologyValidator> validators)
-      throws InvalidTopologyException {
-
-    for (TopologyValidator validator : validators) {
-      validator.validate(this);
-    }
-  }
 
   @Override
   public boolean isClusterKerberosEnabled() {
@@ -306,6 +288,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);
@@ -368,12 +355,12 @@ public class ClusterTopologyImpl implements ClusterTopology {
 
 
   private void checkForDuplicateHosts(Map<String, HostGroupInfo> groupInfoMap) throws
InvalidTopologyException {
-    Set<String> hosts = new HashSet<String>();
-    Set<String> duplicates = new HashSet<String>();
+    Set<String> hosts = new HashSet<>();
+    Set<String> duplicates = new HashSet<>();
     for (HostGroupInfo group : groupInfoMap.values()) {
       // check for duplicates within the new groups
       Collection<String> groupHosts = group.getHostNames();
-      Collection<String> groupHostsCopy = new HashSet<String>(group.getHostNames());
+      Collection<String> groupHostsCopy = new HashSet<>(group.getHostNames());
       groupHostsCopy.retainAll(hosts);
       duplicates.addAll(groupHostsCopy);
       hosts.addAll(groupHosts);

http://git-wip-us.apache.org/repos/asf/ambari/blob/a9cda4f1/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 2727429..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
@@ -18,13 +18,18 @@
 
 package org.apache.ambari.server.topology;
 
-import com.google.gson.Gson;
-import com.google.inject.Inject;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Singleton;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.api.predicate.InvalidQueryException;
 import org.apache.ambari.server.controller.internal.BaseClusterRequest;
-import org.apache.ambari.server.controller.internal.ProvisionClusterRequest;
 import org.apache.ambari.server.orm.dao.HostDAO;
 import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
 import org.apache.ambari.server.orm.dao.TopologyHostGroupDAO;
@@ -46,13 +51,8 @@ import org.apache.ambari.server.topology.tasks.TopologyTask;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.inject.Singleton;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import com.google.gson.Gson;
+import com.google.inject.Inject;
 
 /**
  * Implementation which uses Ambari Database DAO and Entity objects for persistence
@@ -171,10 +171,10 @@ public class PersistedStateImpl implements PersistedState {
   public Map<ClusterTopology, List<LogicalRequest>> getAllRequests() {
     //todo: we only currently support a single request per ambari instance so there should
only
     //todo: be a single cluster topology
-    Map<ClusterTopology, List<LogicalRequest>> allRequests = new HashMap<ClusterTopology,
List<LogicalRequest>>();
+    Map<ClusterTopology, List<LogicalRequest>> allRequests = new HashMap<>();
     Collection<TopologyRequestEntity> entities = topologyRequestDAO.findAll();
 
-    Map<Long, ClusterTopology> topologyRequests = new HashMap<Long, ClusterTopology>();
+    Map<Long, ClusterTopology> topologyRequests = new HashMap<>();
     for (TopologyRequestEntity entity : entities) {
       TopologyRequest replayedRequest = new ReplayedTopologyRequest(entity, blueprintFactory);
       ClusterTopology clusterTopology = topologyRequests.get(replayedRequest.getClusterId());
@@ -238,7 +238,7 @@ public class PersistedStateImpl implements PersistedState {
     }
 
     // host groups
-    Collection<TopologyHostGroupEntity> hostGroupEntities = new ArrayList<TopologyHostGroupEntity>();
+    Collection<TopologyHostGroupEntity> hostGroupEntities = new ArrayList<>();
     for (HostGroupInfo groupInfo : request.getHostGroupInfo().values())  {
       hostGroupEntities.add(toEntity(groupInfo, entity));
     }
@@ -256,7 +256,7 @@ public class PersistedStateImpl implements PersistedState {
     entity.setTopologyRequestId(topologyRequestEntity.getId());
 
     // host requests
-    Collection<TopologyHostRequestEntity> hostRequests = new ArrayList<TopologyHostRequestEntity>();
+    Collection<TopologyHostRequestEntity> hostRequests = new ArrayList<>();
     entity.setTopologyHostRequestEntities(hostRequests);
     for (HostRequest hostRequest : request.getHostRequests()) {
       hostRequests.add(toEntity(hostRequest, entity));
@@ -275,7 +275,7 @@ public class PersistedStateImpl implements PersistedState {
         logicalRequestEntity.getTopologyRequestId(), request.getHostgroupName()));
 
     // logical tasks
-    Collection<TopologyHostTaskEntity> hostRequestTaskEntities = new ArrayList<TopologyHostTaskEntity>();
+    Collection<TopologyHostTaskEntity> hostRequestTaskEntities = new ArrayList<>();
     entity.setTopologyHostTaskEntities(hostRequestTaskEntities);
     // for now only worry about install and start tasks
     for (TopologyTask task : request.getTopologyTasks()) {
@@ -284,7 +284,7 @@ public class PersistedStateImpl implements PersistedState {
         hostRequestTaskEntities.add(topologyTaskEntity);
         topologyTaskEntity.setType(task.getType().name());
         topologyTaskEntity.setTopologyHostRequestEntity(entity);
-        Collection<TopologyLogicalTaskEntity> logicalTaskEntities = new ArrayList<TopologyLogicalTaskEntity>();
+        Collection<TopologyLogicalTaskEntity> logicalTaskEntities = new ArrayList<>();
         topologyTaskEntity.setTopologyLogicalTaskEntities(logicalTaskEntities);
         for (Long logicalTaskId : request.getLogicalTasksForTopologyTask(task).values())
{
           TopologyLogicalTaskEntity logicalTaskEntity = new TopologyLogicalTaskEntity();
@@ -312,7 +312,7 @@ public class PersistedStateImpl implements PersistedState {
     entity.setTopologyRequestEntity(topologyRequestEntity);
 
     // host info
-    Collection<TopologyHostInfoEntity> hostInfoEntities = new ArrayList<TopologyHostInfoEntity>();
+    Collection<TopologyHostInfoEntity> hostInfoEntities = new ArrayList<>();
     entity.setTopologyHostInfoEntities(hostInfoEntities);
 
     Collection<String> hosts = groupInfo.getHostNames();
@@ -355,7 +355,7 @@ public class PersistedStateImpl implements PersistedState {
     private final String description;
     private final Blueprint blueprint;
     private final Configuration configuration;
-    private final Map<String, HostGroupInfo> hostGroupInfoMap = new HashMap<String,
HostGroupInfo>();
+    private final Map<String, HostGroupInfo> hostGroupInfoMap = new HashMap<>();
 
     public ReplayedTopologyRequest(TopologyRequestEntity entity, BlueprintFactory blueprintFactory)
{
       clusterId = entity.getClusterId();
@@ -398,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/a9cda4f1/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 8e991d6..c192122 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/a9cda4f1/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 516ea14..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;
 
 /**
@@ -28,21 +27,21 @@ public interface TopologyRequest {
   /**
    * Request types.
    */
-  public enum Type { PROVISION, SCALE, EXPORT }
+  enum Type { PROVISION, SCALE, EXPORT }
 
   /**
    * Get the cluster id associated with the request. Can be <code>null</code>.
    *
    * @return associated cluster id
    */
-  public Long getClusterId();
+  Long getClusterId();
 
   /**
    * Get the request type.
    *
    * @return the type of request
    */
-  public Type getType();
+  Type getType();
 
   //todo: only a single BP may be specified so all host groups have the same bp.
   //todo: BP really needs to be associated with the HostGroupInfo, even for create which
will have a single BP
@@ -53,33 +52,26 @@ public interface TopologyRequest {
    *
    * @return associated blueprint instance
    */
-  public Blueprint getBlueprint();
+  Blueprint getBlueprint();
 
   /**
    * Get the cluster scoped configuration for the request.
    *
    * @return cluster scoped configuration
    */
-  public Configuration getConfiguration();
+  Configuration getConfiguration();
 
   /**
    * Get host group info.
    *
    * @return map of host group name to group info
    */
-  public Map<String, HostGroupInfo> getHostGroupInfo();
-
-  /**
-   * Get request topology validators.
-   *
-   * @return list of topology validators
-   */
-  public List<TopologyValidator> getTopologyValidators();
+  Map<String, HostGroupInfo> getHostGroupInfo();
 
   /**
    * Get request description.
    *
    * @return string description of the request
    */
-  public String getDescription();
+  String getDescription();
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a9cda4f1/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/a9cda4f1/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/a9cda4f1/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 f230d3d..dd9bc3a 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
@@ -37,10 +37,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() {
   }
 
   /**
@@ -50,6 +50,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/a9cda4f1/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/a9cda4f1/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/a9cda4f1/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);
+  }
+
+}
+
+
+
+
+
+


Mime
View raw message