You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by js...@apache.org on 2015/04/27 07:53:05 UTC
[11/13] ambari git commit: AMBARI-10750. Initial merge of advanced
api provisioning work.
http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
index 03acd40..aab5395 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
@@ -30,7 +30,6 @@ import java.util.Set;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.DuplicateResourceException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
@@ -43,16 +42,16 @@ import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.orm.dao.BlueprintDAO;
-import org.apache.ambari.server.orm.dao.StackDAO;
import org.apache.ambari.server.orm.entities.BlueprintConfigEntity;
import org.apache.ambari.server.orm.entities.BlueprintConfiguration;
import org.apache.ambari.server.orm.entities.BlueprintEntity;
import org.apache.ambari.server.orm.entities.HostGroupComponentEntity;
-import org.apache.ambari.server.orm.entities.HostGroupConfigEntity;
import org.apache.ambari.server.orm.entities.HostGroupEntity;
import org.apache.ambari.server.orm.entities.StackEntity;
-import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.stack.NoSuchStackException;
+import org.apache.ambari.server.topology.Blueprint;
+import org.apache.ambari.server.topology.BlueprintFactory;
+import org.apache.ambari.server.topology.InvalidTopologyException;
import com.google.gson.Gson;
@@ -60,32 +59,32 @@ import com.google.gson.Gson;
/**
* Resource Provider for Blueprint resources.
*/
-public class BlueprintResourceProvider extends BaseBlueprintProcessor {
+public class BlueprintResourceProvider extends AbstractControllerResourceProvider {
// ----- Property ID constants ---------------------------------------------
// Blueprints
- protected static final String BLUEPRINT_NAME_PROPERTY_ID =
+ public static final String BLUEPRINT_NAME_PROPERTY_ID =
PropertyHelper.getPropertyId("Blueprints", "blueprint_name");
- protected static final String STACK_NAME_PROPERTY_ID =
+ public static final String STACK_NAME_PROPERTY_ID =
PropertyHelper.getPropertyId("Blueprints", "stack_name");
- protected static final String STACK_VERSION_PROPERTY_ID =
+ public static final String STACK_VERSION_PROPERTY_ID =
PropertyHelper.getPropertyId("Blueprints", "stack_version");
// Host Groups
- protected static final String HOST_GROUP_PROPERTY_ID = "host_groups";
- protected static final String HOST_GROUP_NAME_PROPERTY_ID = "name";
- protected static final String HOST_GROUP_CARDINALITY_PROPERTY_ID = "cardinality";
+ public static final String HOST_GROUP_PROPERTY_ID = "host_groups";
+ public static final String HOST_GROUP_NAME_PROPERTY_ID = "name";
+ public static final String HOST_GROUP_CARDINALITY_PROPERTY_ID = "cardinality";
// Host Group Components
- protected static final String COMPONENT_PROPERTY_ID ="components";
- protected static final String COMPONENT_NAME_PROPERTY_ID ="name";
+ public static final String COMPONENT_PROPERTY_ID ="components";
+ public static final String COMPONENT_NAME_PROPERTY_ID ="name";
// Configurations
- protected static final String CONFIGURATION_PROPERTY_ID = "configurations";
- protected static final String PROPERTIES_PROPERTY_ID = "properties";
- protected static final String PROPERTIES_ATTRIBUTES_PROPERTY_ID = "properties_attributes";
- protected static final String SCHEMA_IS_NOT_SUPPORTED_MESSAGE =
+ public static final String CONFIGURATION_PROPERTY_ID = "configurations";
+ public static final String PROPERTIES_PROPERTY_ID = "properties";
+ public static final String PROPERTIES_ATTRIBUTES_PROPERTY_ID = "properties_attributes";
+ public static final String SCHEMA_IS_NOT_SUPPORTED_MESSAGE =
"Configuration format provided in Blueprint is not supported";
// Primary Key Fields
@@ -94,6 +93,16 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
BLUEPRINT_NAME_PROPERTY_ID}));
/**
+ * Used to create Blueprint instances
+ */
+ private static BlueprintFactory blueprintFactory;
+
+ /**
+ * Blueprint Data Access Object
+ */
+ private static BlueprintDAO blueprintDAO;
+
+ /**
* Used to serialize to/from json.
*/
private static Gson jsonSerializer;
@@ -118,19 +127,14 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
/**
* Static initialization.
*
- * @param dao
- * blueprint data access object
- * @param gson
- * json serializer
- * @param metaInfo
- * stack related information
+ * @param factory blueprint factory
+ * @param dao blueprint data access object
+ * @param gson json serializer
*/
- public static void init(BlueprintDAO dao, StackDAO stacks, Gson gson,
- AmbariMetaInfo metaInfo) {
+ public static void init(BlueprintFactory factory, BlueprintDAO dao, Gson gson) {
+ blueprintFactory = factory;
blueprintDAO = dao;
- stackDAO = stacks;
jsonSerializer = gson;
- stackInfo = metaInfo;
}
// ----- ResourceProvider ------------------------------------------------
@@ -154,6 +158,7 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
}
@Override
+ //todo: continue to use dao/entity directly or use blueprint factory?
public Set<Resource> getResources(Request request, Predicate predicate)
throws SystemException, UnsupportedPropertyException,
NoSuchResourceException, NoSuchParentResourceException {
@@ -278,172 +283,6 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
}
/**
- * Convert a map of properties to a blueprint entity.
- *
- * @param properties property map
- * @return new blueprint entity
- */
- @SuppressWarnings("unchecked")
- protected BlueprintEntity toBlueprintEntity(Map<String, Object> properties) {
- String name = (String) properties.get(BLUEPRINT_NAME_PROPERTY_ID);
- if (name == null || name.isEmpty()) {
- throw new IllegalArgumentException("Blueprint name must be provided");
- }
-
- String stackName = (String) properties.get(STACK_NAME_PROPERTY_ID);
- String stackVersion = (String) properties.get(STACK_VERSION_PROPERTY_ID);
- StackEntity stackEntity = stackDAO.find(stackName, stackVersion);
-
- BlueprintEntity blueprint = new BlueprintEntity();
- blueprint.setBlueprintName(name);
- blueprint.setStack(stackEntity);
-
- createHostGroupEntities(blueprint,
- (HashSet<HashMap<String, Object>>) properties.get(HOST_GROUP_PROPERTY_ID));
-
- createBlueprintConfigEntities((Collection<Map<String, String>>)
- properties.get(CONFIGURATION_PROPERTY_ID), blueprint);
-
- return blueprint;
- }
-
- /**
- * Create host group entities and add to the parent blueprint entity.
- *
- * @param blueprint parent blueprint entity
- * @param setHostGroups set of host group property maps
- */
- @SuppressWarnings("unchecked")
- private void createHostGroupEntities(BlueprintEntity blueprint,
- HashSet<HashMap<String, Object>> setHostGroups) {
-
- if (setHostGroups == null || setHostGroups.isEmpty()) {
- throw new IllegalArgumentException("At least one host group must be specified in a blueprint");
- }
-
- Collection<HostGroupEntity> entities = new ArrayList<HostGroupEntity>();
-
- StackEntity stackEntity = blueprint.getStack();
-
- Collection<String> stackComponentNames = getAllStackComponents(
- stackEntity.getStackName(), stackEntity.getStackVersion());
-
- for (HashMap<String, Object> hostGroupProperties : setHostGroups) {
- HostGroupEntity hostGroup = new HostGroupEntity();
- entities.add(hostGroup);
-
- String hostGroupName = (String) hostGroupProperties.get(HOST_GROUP_NAME_PROPERTY_ID);
- if (hostGroupName == null || hostGroupName.isEmpty()) {
- throw new IllegalArgumentException("Every host group must include a non-null 'name' property");
- }
-
- hostGroup.setName(hostGroupName);
- hostGroup.setBlueprintEntity(blueprint);
- hostGroup.setBlueprintName(blueprint.getBlueprintName());
- hostGroup.setCardinality((String) hostGroupProperties.get(HOST_GROUP_CARDINALITY_PROPERTY_ID));
-
- createHostGroupConfigEntities((Collection<Map<String,
- String>>) hostGroupProperties.get(CONFIGURATION_PROPERTY_ID), hostGroup);
-
- createComponentEntities(hostGroup, (HashSet<HashMap<String, String>>)
- hostGroupProperties.get(COMPONENT_PROPERTY_ID), stackComponentNames);
- }
- blueprint.setHostGroups(entities);
- }
-
- /**
- * Create component entities and add to parent host group.
- *
- * @param group parent host group
- * @param setComponents set of component property maps
- * @param componentNames set of all component names for the associated stack
- */
- @SuppressWarnings("unchecked")
- private void createComponentEntities(HostGroupEntity group, HashSet<HashMap<String, String>> setComponents,
- Collection<String> componentNames) {
-
- Collection<HostGroupComponentEntity> components = new ArrayList<HostGroupComponentEntity>();
- String groupName = group.getName();
- group.setComponents(components);
-
- if (setComponents == null || setComponents.isEmpty()) {
- throw new IllegalArgumentException("Host group '" + groupName + "' must contain at least one component");
- }
-
- for (HashMap<String, String> componentProperties : setComponents) {
- HostGroupComponentEntity component = new HostGroupComponentEntity();
- components.add(component);
-
- String componentName = componentProperties.get(COMPONENT_NAME_PROPERTY_ID);
- if (componentName == null || componentName.isEmpty()) {
- throw new IllegalArgumentException("Host group '" + groupName +
- "' contains a component with no 'name' property");
- }
-
- if (! componentNames.contains(componentName)) {
- throw new IllegalArgumentException("The component '" + componentName + "' in host group '" +
- groupName + "' is not valid for the specified stack");
- }
-
- component.setName(componentName);
- component.setBlueprintName(group.getBlueprintName());
- component.setHostGroupEntity(group);
- component.setHostGroupName(group.getName());
- }
- group.setComponents(components);
- }
-
- /**
- * Obtain all component names for the specified stack.
- *
- * @param stackName stack name
- * @param stackVersion stack version
- *
- * @return collection of component names for the specified stack
- * @throws IllegalArgumentException if the specified stack doesn't exist
- */
- private Collection<String> getAllStackComponents(String stackName, String stackVersion) {
- Collection<String> componentNames = new HashSet<String>();
- componentNames.add("AMBARI_SERVER");
- Collection<ComponentInfo> components;
- try {
- components = getComponents(stackName, stackVersion);
- } catch (AmbariException e) {
- throw new IllegalArgumentException("The specified stack doesn't exist. Name='" +
- stackName + "', Version='" + stackVersion + "'");
- }
- if (components != null) {
- for (ComponentInfo component : components) {
- componentNames.add(component.getName());
- }
- }
- return componentNames;
- }
-
- /**
- * Get all the components for the specified stack.
- *
- * @param stackName stack name
- * @param version stack version
- *
- * @return all components for the specified stack
- * @throws AmbariException if the stack doesn't exist
- */
- private Collection<ComponentInfo> getComponents(String stackName, String version) throws AmbariException {
- Collection<ComponentInfo> components = new HashSet<ComponentInfo>();
- Map<String, ServiceInfo> services = stackInfo.getServices(stackName, version);
-
- for (ServiceInfo service : services.values()) {
- List<ComponentInfo> serviceComponents = stackInfo.getComponentsByService(
- stackName, version, service.getName());
- for (ComponentInfo component : serviceComponents) {
- components.add(component);
- }
- }
- return components;
- }
-
- /**
* Populate a list of configuration property maps from a collection of configuration entities.
*
* @param configurations collection of configuration entities
@@ -495,28 +334,6 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
blueprint.setConfigurations(configurations);
}
- /**
- * Populate host group configurations.
- *
- * @param propertyMaps collection of configuration property maps
- * @param hostGroup host group entity to set configurations on
- */
- private void createHostGroupConfigEntities(Collection<Map<String, String>> propertyMaps,
- HostGroupEntity hostGroup) {
-
- Collection<HostGroupConfigEntity> configurations = new ArrayList<HostGroupConfigEntity>();
- if (propertyMaps != null) {
- for (Map<String, String> configuration : propertyMaps) {
- HostGroupConfigEntity configEntity = new HostGroupConfigEntity();
- configEntity.setHostGroupEntity(hostGroup);
- configEntity.setHostGroupName(hostGroup.getName());
- configEntity.setBlueprintName(hostGroup.getBlueprintName());
- populateConfigurationEntity(configuration, configEntity);
- configurations.add(configEntity);
- }
- }
- hostGroup.setConfigurations(configurations);
- }
/**
* Populate a configuration entity from properties.
@@ -560,31 +377,39 @@ public class BlueprintResourceProvider extends BaseBlueprintProcessor {
return new Command<Void>() {
@Override
public Void invoke() throws AmbariException {
- BlueprintEntity blueprint = toBlueprintEntity(properties);
+ Blueprint blueprint;
+ try {
+ blueprint = blueprintFactory.createBlueprint(properties);
+ } catch (NoSuchStackException e) {
+ throw new IllegalArgumentException("Specified stack doesn't exist: " + e, e);
+ }
- if (blueprintDAO.findByName(blueprint.getBlueprintName()) != null) {
+ if (blueprintDAO.findByName(blueprint.getName()) != null) {
throw new DuplicateResourceException(
"Attempted to create a Blueprint which already exists, blueprint_name=" +
- blueprint.getBlueprintName());
+ blueprint.getName());
}
- Map<String, Map<String, Collection<String>>> missingProperties = blueprint.validateConfigurations(
- stackInfo, false);
- if (! missingProperties.isEmpty()) {
- throw new IllegalArgumentException("Required configurations are missing from the specified host groups: " +
- missingProperties);
+ try {
+ blueprint.validateRequiredProperties();
+ } catch (InvalidTopologyException e) {
+ throw new IllegalArgumentException("Blueprint configuration validation failed: " + e.getMessage(), e);
}
String validateTopology = requestInfoProps.get("validate_topology");
if (validateTopology == null || ! validateTopology.equalsIgnoreCase("false")) {
- validateTopology(blueprint);
+ try {
+ blueprint.validateTopology();
+ } catch (InvalidTopologyException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
}
if (LOG.isDebugEnabled()) {
- LOG.debug("Creating Blueprint, name=" + blueprint.getBlueprintName());
+ LOG.debug("Creating Blueprint, name=" + blueprint.getName());
}
try {
- blueprintDAO.create(blueprint);
+ blueprintDAO.create(blueprint.toEntity());
} catch (Exception e) {
throw new RuntimeException(e);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Cardinality.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Cardinality.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Cardinality.java
deleted file mode 100644
index 74e594f..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Cardinality.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * 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.controller.internal;
-
-/**
- * Component cardinality representation.
- */
-class Cardinality {
- String cardinality;
- int min = 0;
- int max = Integer.MAX_VALUE;
- int exact = -1;
- boolean isAll = false;
-
- public Cardinality(String cardinality) {
- this.cardinality = cardinality;
- if (cardinality != null && ! cardinality.isEmpty()) {
- if (cardinality.contains("+")) {
- min = Integer.valueOf(cardinality.split("\\+")[0]);
- } else if (cardinality.contains("-")) {
- String[] toks = cardinality.split("-");
- min = Integer.parseInt(toks[0]);
- max = Integer.parseInt(toks[1]);
- } else if (cardinality.equals("ALL")) {
- isAll = true;
- } else {
- exact = Integer.parseInt(cardinality);
- }
- }
- }
-
- /**
- * Determine if component is required for all host groups.
- *
- * @return true if cardinality is 'ALL', false otherwise
- */
- public boolean isAll() {
- return isAll;
- }
-
- /**
- * Determine if the given count satisfies the required cardinality.
- *
- * @param count number of host groups containing component
- *
- * @return true id count satisfies the required cardinality, false otherwise
- */
- public boolean isValidCount(int count) {
- if (isAll) {
- return false;
- } else if (exact != -1) {
- return count == exact;
- } else return count >= min && count <= max;
- }
-
- /**
- * Determine if the cardinality count supports auto-deployment.
- * This determination is independent of whether the component is configured
- * to be auto-deployed. This only indicates whether auto-deployment is
- * supported for the current cardinality.
- *
- * At this time, only cardinalities of ALL or where a count of 1 is valid are
- * supported.
- *
- * @return true if cardinality supports auto-deployment
- */
- public boolean supportsAutoDeploy() {
- return isValidCount(1) || isAll;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
index 2c43e1a..2db2d28 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
@@ -270,7 +270,7 @@ public class ClientConfigResourceProvider extends AbstractControllerResourceProv
Map<String, Set<String>> clusterHostInfo = null;
ServiceInfo serviceInfo = null;
String osFamily = null;
- clusterHostInfo = StageUtils.getClusterHostInfo(managementController.getClusters().getHostsForCluster(cluster.getClusterName()), cluster);
+ clusterHostInfo = StageUtils.getClusterHostInfo(cluster);
serviceInfo = managementController.getAmbariMetaInfo().getService(stackId.getStackName(),
stackId.getStackVersion(), serviceName);
clusterHostInfo = substituteHostIndexes(clusterHostInfo);
http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
index 0b5bb8e..812aa5d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
@@ -18,15 +18,22 @@
package org.apache.ambari.server.controller.internal;
import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.ClusterRequest;
import org.apache.ambari.server.controller.ClusterResponse;
-import org.apache.ambari.server.controller.ConfigGroupRequest;
import org.apache.ambari.server.controller.ConfigurationRequest;
import org.apache.ambari.server.controller.RequestStatusResponse;
import org.apache.ambari.server.controller.ServiceConfigVersionRequest;
import org.apache.ambari.server.controller.ServiceConfigVersionResponse;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+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.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
import org.apache.ambari.server.controller.spi.Predicate;
@@ -34,50 +41,32 @@ import org.apache.ambari.server.controller.spi.Request;
import org.apache.ambari.server.controller.spi.RequestStatus;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
-import org.apache.ambari.server.controller.spi.ResourceProvider;
import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.orm.dao.BlueprintDAO;
-import org.apache.ambari.server.orm.entities.BlueprintConfigEntity;
-import org.apache.ambari.server.orm.entities.BlueprintEntity;
-import org.apache.ambari.server.orm.entities.HostGroupEntity;
-import org.apache.ambari.server.state.Config;
-import org.apache.ambari.server.state.ConfigHelper;
-import org.apache.ambari.server.state.ConfigImpl;
import org.apache.ambari.server.state.SecurityType;
-import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.topology.*;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
/**
* Resource provider for cluster resources.
*/
-public class ClusterResourceProvider extends BaseBlueprintProcessor {
+public class ClusterResourceProvider extends AbstractControllerResourceProvider {
// ----- Property ID constants ---------------------------------------------
// Clusters
public static final String CLUSTER_ID_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "cluster_id");
public static final String CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "cluster_name");
- protected static final String CLUSTER_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "version");
- protected static final String CLUSTER_PROVISIONING_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "provisioning_state");
- protected static final String CLUSTER_SECURITY_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "security_type");
- protected static final String CLUSTER_DESIRED_CONFIGS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "desired_configs");
- protected static final String CLUSTER_DESIRED_SERVICE_CONFIG_VERSIONS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "desired_service_config_versions");
- protected static final String CLUSTER_TOTAL_HOSTS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "total_hosts");
- protected static final String CLUSTER_HEALTH_REPORT_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "health_report");
- protected static final String BLUEPRINT_PROPERTY_ID = PropertyHelper.getPropertyId(null, "blueprint");
- protected static final String SESSION_ATTRIBUTES_PROPERTY_ID = "session_attributes";
+ public static final String CLUSTER_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "version");
+ public static final String CLUSTER_PROVISIONING_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "provisioning_state");
+ public static final String CLUSTER_SECURITY_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "security_type");
+ public static final String CLUSTER_DESIRED_CONFIGS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "desired_configs");
+ public static final String CLUSTER_DESIRED_SERVICE_CONFIG_VERSIONS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "desired_service_config_versions");
+ public static final String CLUSTER_TOTAL_HOSTS_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "total_hosts");
+ public static final String CLUSTER_HEALTH_REPORT_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "health_report");
+ public static final String BLUEPRINT_PROPERTY_ID = PropertyHelper.getPropertyId(null, "blueprint");
+ public static final String SESSION_ATTRIBUTES_PROPERTY_ID = "session_attributes";
/**
* The session attributes property prefix.
@@ -90,6 +79,16 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
public static final String GET_IGNORE_PERMISSIONS_PROPERTY_ID = "get_resource/ignore_permissions";
/**
+ * topology manager instance
+ */
+ private static TopologyManager topologyManager;
+
+ /**
+ * factory for creating topology requests which are used to provision a cluster via a blueprint
+ */
+ private static TopologyRequestFactory topologyRequestFactory;
+
+ /**
* The cluster primary key properties.
*/
private static Set<String> pkPropertyIds =
@@ -107,6 +106,8 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
* The property ids for a cluster resource.
*/
private static Set<String> propertyIds = new HashSet<String>();
+
+
static {
propertyIds.add(CLUSTER_ID_PROPERTY_ID);
propertyIds.add(CLUSTER_NAME_PROPERTY_ID);
@@ -121,16 +122,6 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
propertyIds.add(SESSION_ATTRIBUTES_PROPERTY_ID);
}
- /**
- * Maps configuration type (string) to associated properties
- */
- private Map<String, Map<String, String>> mapClusterConfigurations =
- new HashMap<String, Map<String, String>>();
- /**
- * Maps configuration type (string) to property attributes, and their values
- */
- private Map<String, Map<String, Map<String, String>>> mapClusterAttributes =
- new HashMap<String, Map<String, Map<String, String>>>();
// ----- Constructors ----------------------------------------------------
@@ -336,21 +327,13 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
/**
* Inject the blueprint data access object which is used to obtain blueprint entities.
*
- * @param dao blueprint data access object
+ * @param manager topology manager
+ * @param requestFactory request factory
*/
- public static void init(BlueprintDAO dao, AmbariMetaInfo metaInfo, ConfigHelper ch) {
- blueprintDAO = dao;
- stackInfo = metaInfo;
- configHelper = ch;
- }
-
-
- /**
- * Package-level access for cluster config
- * @return cluster config map
- */
- Map<String, Map<String, String>> getClusterConfigurations() {
- return mapClusterConfigurations;
+ //todo: proper static injection mechanism
+ public static void init(TopologyManager manager, TopologyRequestFactory requestFactory) {
+ topologyManager = manager;
+ topologyRequestFactory = requestFactory;
}
@@ -477,439 +460,24 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
throws ResourceAlreadyExistsException, SystemException, UnsupportedPropertyException,
NoSuchParentResourceException {
- String blueprintName = (String) properties.get(BLUEPRINT_PROPERTY_ID);
-
LOG.info("Creating Cluster '" + properties.get(CLUSTER_NAME_PROPERTY_ID) +
- "' based on blueprint '" + blueprintName + "'.");
-
- //todo: build up a proper topology object
- BlueprintEntity blueprint = getExistingBlueprint(blueprintName);
- Stack stack = parseStack(blueprint);
-
- Map<String, HostGroupImpl> blueprintHostGroups = parseBlueprintHostGroups(blueprint, stack);
- applyRequestInfoToHostGroups(properties, blueprintHostGroups);
- Collection<Map<String, String>> configOverrides = (Collection<Map<String, String>>)properties.get("configurations");
-
- String message = null;
- for (BlueprintConfigEntity blueprintConfig: blueprint.getConfigurations()){
- if(blueprintConfig.getType().equals("global")){
- message = "WARNING: Global configurations are deprecated, please use *-env";
- break;
- }
- }
-
- processConfigurations(processBlueprintConfigurations(blueprint, configOverrides),
- processBlueprintAttributes(blueprint), stack, blueprintHostGroups);
- validatePasswordProperties(blueprint, blueprintHostGroups, (String) properties.get("default_password"));
-
- String clusterName = (String) properties.get(CLUSTER_NAME_PROPERTY_ID);
- createClusterResource(buildClusterResourceProperties(stack, clusterName));
- setConfigurationsOnCluster(clusterName, stack, blueprintHostGroups);
-
- Set<String> services = getServicesToDeploy(stack, blueprintHostGroups);
-
- createServiceAndComponentResources(blueprintHostGroups, clusterName, services);
- createHostAndComponentResources(blueprintHostGroups, clusterName);
-
- registerConfigGroups(clusterName, blueprintHostGroups, stack);
-
- persistInstallStateForUI(clusterName);
-
- RequestStatusResponse request = ((ServiceResourceProvider) getResourceProvider(Resource.Type.Service)).
- installAndStart(clusterName);
-
- request.setMessage(message);
-
- return request;
- }
-
- /**
- * Validate that all required password properties have been set or that 'default_password' is specified.
- *
- * @param blueprint associated blueprint entity
- * @param hostGroups host groups in blueprint
- * @param defaultPassword specified default password, may be null
- *
- * @throws IllegalArgumentException if required password properties are missing and no
- * default is specified via 'default_password'
- */
- private void validatePasswordProperties(BlueprintEntity blueprint, Map<String, HostGroupImpl> hostGroups,
- String defaultPassword) {
-
- Map<String, Map<String, Collection<String>>> missingPasswords = blueprint.validateConfigurations(
- stackInfo, true);
-
- Iterator<Map.Entry<String, Map<String, Collection<String>>>> iter;
- for(iter = missingPasswords.entrySet().iterator(); iter.hasNext(); ) {
- Map.Entry<String, Map<String, Collection<String>>> entry = iter.next();
- Map<String, Collection<String>> missingProps = entry.getValue();
- Iterator<Map.Entry<String, Collection<String>>> hostGroupIter;
-
- for (hostGroupIter = missingProps.entrySet().iterator(); hostGroupIter.hasNext(); ) {
- Map.Entry<String, Collection<String>> hgEntry = hostGroupIter.next();
- String configType = hgEntry.getKey();
- Collection<String> propertySet = hgEntry.getValue();
-
- for (Iterator<String> propIter = propertySet.iterator(); propIter.hasNext(); ) {
- String property = propIter.next();
- if (isPropertyInConfiguration(mapClusterConfigurations.get(configType), property)){
- propIter.remove();
- } else {
- HostGroupImpl hg = hostGroups.get(entry.getKey());
- if (hg != null && isPropertyInConfiguration(hg.getConfigurationProperties().get(configType), property)) {
- propIter.remove();
- } else if (setDefaultPassword(defaultPassword, configType, property)) {
- propIter.remove();
- }
- }
- }
- if (propertySet.isEmpty()) {
- hostGroupIter.remove();
- }
- }
- if (entry.getValue().isEmpty()) {
- iter.remove();
- }
- }
-
- if (! missingPasswords.isEmpty()) {
- throw new IllegalArgumentException("Missing required password properties. Specify a value for these " +
- "properties in the cluster or host group configurations or include 'default_password' field in request. " +
- missingPasswords);
- }
- }
-
- /**
- * Attempt to set the default password in cluster configuration for missing password property.
- *
- * @param defaultPassword default password specified in request, may be null
- * @param configType configuration type
- * @param property password property name
- *
- * @return true if password was set, otherwise false. Currently the password will always be set
- * unless it is null
- */
- private boolean setDefaultPassword(String defaultPassword, String configType, String property) {
- boolean setDefaultPassword = false;
- Map<String, String> typeProps = mapClusterConfigurations.get(configType);
- if (defaultPassword != null && ! defaultPassword.trim().isEmpty()) {
- // set default password in cluster config
- if (typeProps == null) {
- typeProps = new HashMap<String, String>();
- mapClusterConfigurations.put(configType, typeProps);
- }
- typeProps.put(property, defaultPassword);
- setDefaultPassword = true;
- }
- return setDefaultPassword;
- }
-
- /**
- * Determine if a specific property is in a configuration.
- *
- * @param props property map to check
- * @param property property to check for
- *
- * @return true if the property is contained in the configuration, otherwise false
- */
- private boolean isPropertyInConfiguration(Map<String, String> props, String property) {
- boolean foundProperty = false;
- if (props != null) {
- String val = props.get(property);
- foundProperty = (val != null && ! val.trim().isEmpty());
- }
- return foundProperty;
- }
-
- /**
- * Create service and component resources.
- *
- * @param blueprintHostGroups host groups contained in blueprint
- * @param clusterName cluster name
- * @param services services to be deployed
- *
- * @throws SystemException an unexpected exception occurred
- * @throws UnsupportedPropertyException an unsupported property was specified in the request
- * @throws ResourceAlreadyExistsException attempted to create a service or component that already exists
- * @throws NoSuchParentResourceException a required parent resource is missing
- */
- private void createServiceAndComponentResources(Map<String, HostGroupImpl> blueprintHostGroups,
- String clusterName, Set<String> services)
- throws SystemException,
- UnsupportedPropertyException,
- ResourceAlreadyExistsException,
- NoSuchParentResourceException {
-
- Set<Map<String, Object>> setServiceRequestProps = new HashSet<Map<String, Object>>();
- for (String service : services) {
- Map<String, Object> serviceProperties = new HashMap<String, Object>();
- serviceProperties.put(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID, clusterName);
- serviceProperties.put(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID, service);
- setServiceRequestProps.add(serviceProperties);
- }
-
- Request serviceRequest = new RequestImpl(null, setServiceRequestProps, null, null);
- getResourceProvider(Resource.Type.Service).createResources(serviceRequest);
- createComponentResources(blueprintHostGroups, clusterName, services);
- }
-
- /**
- * Build the cluster properties necessary for creating a cluster resource.
- *
- * @param stack associated stack
- * @param clusterName cluster name
- * @return map of cluster properties used to create a cluster resource
- */
- private Map<String, Object> buildClusterResourceProperties(Stack stack, String clusterName) {
- Map<String, Object> clusterProperties = new HashMap<String, Object>();
- clusterProperties.put(CLUSTER_NAME_PROPERTY_ID, clusterName);
- clusterProperties.put(CLUSTER_VERSION_PROPERTY_ID, stack.getName() + "-" + stack.getVersion());
- return clusterProperties;
- }
-
- /**
- * Create component resources.
- *
- * @param blueprintHostGroups host groups specified in blueprint
- * @param clusterName cluster name
- * @param services services to be deployed
- *
- * @throws SystemException an unexpected exception occurred
- * @throws UnsupportedPropertyException an invalid property was specified
- * @throws ResourceAlreadyExistsException attempt to create a component which already exists
- * @throws NoSuchParentResourceException a required parent resource is missing
- */
- private void createComponentResources(Map<String, HostGroupImpl> blueprintHostGroups,
- String clusterName, Set<String> services)
- throws SystemException,
- UnsupportedPropertyException,
- ResourceAlreadyExistsException,
- NoSuchParentResourceException {
- for (String service : services) {
- Set<String> components = new HashSet<String>();
- for (HostGroupImpl hostGroup : blueprintHostGroups.values()) {
- Collection<String> serviceComponents = hostGroup.getComponents(service);
- if (serviceComponents != null && !serviceComponents.isEmpty()) {
- components.addAll(serviceComponents);
- }
- }
-
- Set<Map<String, Object>> setComponentRequestProps = new HashSet<Map<String, Object>>();
- for (String component : components) {
- Map<String, Object> componentProperties = new HashMap<String, Object>();
- componentProperties.put("ServiceComponentInfo/cluster_name", clusterName);
- componentProperties.put("ServiceComponentInfo/service_name", service);
- componentProperties.put("ServiceComponentInfo/component_name", component);
- setComponentRequestProps.add(componentProperties);
- }
- Request componentRequest = new RequestImpl(null, setComponentRequestProps, null, null);
- ResourceProvider componentProvider = getResourceProvider(Resource.Type.Component);
- componentProvider.createResources(componentRequest);
- }
- }
-
- /**
- * Set all configurations on the cluster resource.
- *
- * @param clusterName cluster name
- * @param stack Stack definition object used for this cluster
- * @param blueprintHostGroups host groups defined in the Blueprint for this cluster
- *
- * @throws SystemException an unexpected exception occurred
- */
- void setConfigurationsOnCluster(String clusterName, Stack stack, Map<String, HostGroupImpl> blueprintHostGroups) throws SystemException {
- List<BlueprintServiceConfigRequest> listofConfigRequests =
- new LinkedList<BlueprintServiceConfigRequest>();
-
- // create a list of config requests on a per-service basis, in order
- // to properly support the new service configuration versioning mechanism
- // in Ambari
- for (String service : getServicesToDeploy(stack, blueprintHostGroups)) {
- BlueprintServiceConfigRequest blueprintConfigRequest =
- new BlueprintServiceConfigRequest(service);
-
- for (String serviceConfigType : stack.getConfigurationTypes(service)) {
- Set<String> excludedConfigTypes = stack.getExcludedConfigurationTypes(service);
- if (excludedConfigTypes == null) {
- // if the service does not have excluded config types
- // associated, then treat this as an empty set
- excludedConfigTypes = Collections.emptySet();
- }
-
- // only include config types that are not excluded, re-introducing fix from AMBARI-8009
- if (!excludedConfigTypes.contains(serviceConfigType)) {
- // skip handling of cluster-env here
- if (!serviceConfigType.equals("cluster-env")) {
- if (mapClusterConfigurations.containsKey(serviceConfigType)) {
- blueprintConfigRequest.addConfigElement(serviceConfigType,
- mapClusterConfigurations.get(serviceConfigType),
- mapClusterAttributes.get(serviceConfigType));
- }
- }
- }
- }
-
- listofConfigRequests.add(blueprintConfigRequest);
- }
-
- // since the stack returns "cluster-env" with each service's config
- // this code needs to ensure that only one ClusterRequest occurs for
- // the global cluster-env configuration
- BlueprintServiceConfigRequest globalConfigRequest =
- new BlueprintServiceConfigRequest("GLOBAL-CONFIG");
- globalConfigRequest.addConfigElement("cluster-env",
- mapClusterConfigurations.get("cluster-env"),
- mapClusterAttributes.get("cluster-env"));
- listofConfigRequests.add(globalConfigRequest);
+ "' based on blueprint '" + String.valueOf(properties.get(BLUEPRINT_PROPERTY_ID)) + "'.");
+ TopologyRequest createClusterRequest;
try {
- //todo: properly handle non system exceptions
- setConfigurationsOnCluster(clusterName, listofConfigRequests);
- } catch (AmbariException e) {
- throw new SystemException("Unable to set configurations on cluster.", e);
- }
-
- }
-
-
- /**
- * Creates a ClusterRequest for each service that
- * includes any associated config types and configuration. The Blueprints
- * implementation will now create one ClusterRequest per service, in order
- * to comply with the ServiceConfigVersioning framework in Ambari.
- *
- * This method will also send these requests to the management controller.
- *
- * @param clusterName name of cluster
- * @param listOfBlueprintConfigRequests a list of requests to send to the AmbariManagementController.
- *
- * @throws AmbariException upon any error that occurs during updateClusters
- */
- private void setConfigurationsOnCluster(String clusterName, List<BlueprintServiceConfigRequest> listOfBlueprintConfigRequests) throws AmbariException {
- // iterate over services to deploy
- for (BlueprintServiceConfigRequest blueprintConfigRequest : listOfBlueprintConfigRequests) {
- ClusterRequest clusterRequest = null;
- // iterate over the config types associated with this service
- List<ConfigurationRequest> requestsPerService = new LinkedList<ConfigurationRequest>();
- for (BlueprintServiceConfigElement blueprintElement : blueprintConfigRequest.getConfigElements()) {
- Map<String, Object> clusterProperties = new HashMap<String, Object>();
- clusterProperties.put(CLUSTER_NAME_PROPERTY_ID, clusterName);
- clusterProperties.put(CLUSTER_DESIRED_CONFIGS_PROPERTY_ID + "/type", blueprintElement.getTypeName());
- clusterProperties.put(CLUSTER_DESIRED_CONFIGS_PROPERTY_ID + "/tag", "1");
- for (Map.Entry<String, String> entry : blueprintElement.getConfiguration().entrySet()) {
- clusterProperties.put(CLUSTER_DESIRED_CONFIGS_PROPERTY_ID +
- "/properties/" + entry.getKey(), entry.getValue());
- }
- if (blueprintElement.getAttributes() != null) {
- for (Map.Entry<String, Map<String, String>> attribute : blueprintElement.getAttributes().entrySet()) {
- String attributeName = attribute.getKey();
- for (Map.Entry<String, String> attributeOccurrence : attribute.getValue().entrySet()) {
- clusterProperties.put(CLUSTER_DESIRED_CONFIGS_PROPERTY_ID + "/properties_attributes/"
- + attributeName + "/" + attributeOccurrence.getKey(), attributeOccurrence.getValue());
- }
- }
- }
-
- // only create one cluster request per service, which includes
- // all the configuration types for that service
- if (clusterRequest == null) {
- SecurityType securityType;
- String requestedSecurityType = (String) clusterProperties.get(CLUSTER_SECURITY_TYPE_PROPERTY_ID);
- if(requestedSecurityType == null)
- securityType = null;
- else {
- try {
- securityType = SecurityType.valueOf(requestedSecurityType.toUpperCase());
- } catch (IllegalArgumentException e) {
- throw new IllegalArgumentException(String.format("Cannot set cluster security type to invalid value: %s", requestedSecurityType));
- }
- }
-
- clusterRequest = new ClusterRequest(
- (Long) clusterProperties.get(CLUSTER_ID_PROPERTY_ID),
- (String) clusterProperties.get(CLUSTER_NAME_PROPERTY_ID),
- (String) clusterProperties.get(CLUSTER_PROVISIONING_STATE_PROPERTY_ID),
- securityType,
- (String) clusterProperties.get(CLUSTER_VERSION_PROPERTY_ID),
- null);
- }
-
- List<ConfigurationRequest> listOfRequests =
- getConfigurationRequests("Clusters", clusterProperties);
- requestsPerService.addAll(listOfRequests);
- }
-
- // set total list of config requests, including all config types
- // for this service
- if (clusterRequest != null) {
- clusterRequest.setDesiredConfig(requestsPerService);
-
- LOG.info("About to send cluster config update request for service = " + blueprintConfigRequest.getServiceName());
-
- // send the request update for this service as a whole
- getManagementController().updateClusters(
- Collections.singleton(clusterRequest), null);
- } else {
- LOG.error("ClusterRequest should not be null for service = " + blueprintConfigRequest.getServiceName());
- }
-
- }
- }
-
- /**
- * Apply the information contained in the cluster request body such as host an configuration properties to
- * the associated blueprint.
- *
- * @param properties request properties
- * @param blueprintHostGroups blueprint host groups
- *
- * @throws IllegalArgumentException a host_group in the request doesn't match a host-group in the blueprint
- */
- @SuppressWarnings("unchecked")
- private void applyRequestInfoToHostGroups(Map<String, Object> properties,
- Map<String, HostGroupImpl> blueprintHostGroups)
- throws IllegalArgumentException {
-
- @SuppressWarnings("unchecked")
- Collection<Map<String, Object>> hostGroups =
- (Collection<Map<String, Object>>) properties.get("host_groups");
-
- if (hostGroups == null || hostGroups.isEmpty()) {
- throw new IllegalArgumentException("'host_groups' element must be included in cluster create body");
+ createClusterRequest = topologyRequestFactory.createProvisionClusterRequest(properties);
+ } catch (InvalidTopologyTemplateException e) {
+ throw new IllegalArgumentException("Invalid Cluster Creation Template: " + e, e);
}
- // iterate over host groups provided in request body
- for (Map<String, Object> hostGroupProperties : hostGroups) {
- String name = (String) hostGroupProperties.get("name");
- if (name == null || name.isEmpty()) {
- throw new IllegalArgumentException("Every host_group must include a non-null 'name' property");
- }
- HostGroupImpl hostGroup = blueprintHostGroups.get(name);
-
- if (hostGroup == null) {
- throw new IllegalArgumentException("Invalid host_group specified: " + name +
- ". All request host groups must have a corresponding host group in the specified blueprint");
- }
-
- Collection hosts = (Collection) hostGroupProperties.get("hosts");
- if (hosts == null || hosts.isEmpty()) {
- throw new IllegalArgumentException("Host group '" + name + "' must contain a 'hosts' element");
- }
- for (Object oHost : hosts) {
- Map<String, String> mapHostProperties = (Map<String, String>) oHost;
- //add host information to host group
- String fqdn = mapHostProperties.get("fqdn");
- if (fqdn == null || fqdn.isEmpty()) {
- throw new IllegalArgumentException("Host group '" + name + "' hosts element must include at least one fqdn");
- }
- hostGroup.addHostInfo(fqdn);
- }
- Map<String, Map<String, String>> existingConfigurations = hostGroup.getConfigurationProperties();
- overrideExistingProperties(existingConfigurations, (Collection<Map<String, String>>)
- hostGroupProperties.get("configurations"));
-
+ try {
+ return topologyManager.provisionCluster(createClusterRequest);
+ } catch (InvalidTopologyException e) {
+ throw new IllegalArgumentException("Topology validation failed: " + e, e);
+ } catch (AmbariException e) {
+ e.printStackTrace();
+ throw new SystemException("Unknown exception when asking TopologyManager to provision cluster", e);
}
- validateHostMappings(blueprintHostGroups);
}
/**
@@ -934,317 +502,6 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
}
/**
- * Persist cluster state for the ambari UI. Setting this state informs that UI that a cluster has been
- * installed and started and that the monitoring screen for the cluster should be displayed to the user.
- *
- * @param clusterName name of cluster
- *
- * @throws SystemException if unable to update the cluster with the UI installed flag
- */
- private void persistInstallStateForUI(String clusterName) throws SystemException {
- Map<String, Object> clusterProperties = new HashMap<String, Object>();
- clusterProperties.put(CLUSTER_PROVISIONING_STATE_PROPERTY_ID, "INSTALLED");
- clusterProperties.put(CLUSTER_NAME_PROPERTY_ID, clusterName);
-
- try {
- getManagementController().updateClusters(
- Collections.singleton(getRequest(clusterProperties)), null);
- } catch (AmbariException e) {
- throw new SystemException("Unable to finalize state of cluster for UI.");
- }
- }
-
- /**
- * Process cluster configurations. This includes obtaining the default configuration properties
- * from the stack,overlaying configuration properties specified in the blueprint and cluster
- * create request and updating properties with topology specific information.
- *
- * @param stack associated stack
- * @param blueprintHostGroups host groups contained in the blueprint
- */
- private void processConfigurations(Map<String, Map<String, String>> blueprintConfigurations,
- Map<String, Map<String, Map<String, String>>> blueprintAttributes,
- Stack stack, Map<String, HostGroupImpl> blueprintHostGroups) {
-
-
- for (String service : getServicesToDeploy(stack, blueprintHostGroups)) {
- for (String type : stack.getConfigurationTypes(service)) {
- Map<String, String> typeProps = mapClusterConfigurations.get(type);
- if (typeProps == null) {
- typeProps = new HashMap<String, String>();
- mapClusterConfigurations.put(type, typeProps);
- }
- typeProps.putAll(stack.getConfigurationProperties(service, type));
- Map<String, Map<String, String>> stackTypeAttributes = stack.getConfigurationAttributes(service, type);
- if (!stackTypeAttributes.isEmpty()) {
- if (!mapClusterAttributes.containsKey(type)) {
- mapClusterAttributes.put(type, new HashMap<String, Map<String, String>>());
- }
- Map<String, Map<String, String>> typeAttrs = mapClusterAttributes.get(type);
- for (Map.Entry<String, Map<String, String>> attribute : stackTypeAttributes.entrySet()) {
- String attributeName = attribute.getKey();
- Map<String, String> attributes = typeAttrs.get(attributeName);
- if (attributes == null) {
- attributes = new HashMap<String, String>();
- typeAttrs.put(attributeName, attributes);
- }
- attributes.putAll(attribute.getValue());
- }
- }
- }
- }
- processBlueprintClusterConfigurations(blueprintConfigurations);
- processBlueprintClusterConfigAttributes(blueprintAttributes);
-
- BlueprintConfigurationProcessor configurationProcessor = new BlueprintConfigurationProcessor(mapClusterConfigurations);
- configurationProcessor.doUpdateForClusterCreate(blueprintHostGroups, stack);
- setMissingConfigurations(blueprintHostGroups);
- }
-
- /**
- * Since global configs are deprecated since 1.7.0, but still supported.
- * We should automatically map any globals used, to *-env dictionaries.
- *
- * @param blueprintConfigurations map of blueprint configurations keyed by type
- */
- private void handleGlobalsBackwardsCompability(Stack stack,
- Map<String, Map<String, String>> blueprintConfigurations, String clusterName) {
- StackId stackId = new StackId(stack.getName(), stack.getVersion());
- configHelper.moveDeprecatedGlobals(stackId, blueprintConfigurations, clusterName);
- }
-
- /**
- * Process cluster scoped configurations provided in blueprint.
- *
- * @param blueprintConfigurations map of blueprint configurations keyed by type
- */
- private void processBlueprintClusterConfigurations(Map<String, Map<String, String>> blueprintConfigurations) {
- for (Map.Entry<String, Map<String, String>> entry : blueprintConfigurations.entrySet()) {
- Map<String, String> properties = entry.getValue();
- if (properties != null && !properties.isEmpty()) {
- String type = entry.getKey();
- Map<String, String> typeProps = mapClusterConfigurations.get(type);
- if (typeProps == null) {
- typeProps = new HashMap<String, String>();
- mapClusterConfigurations.put(type, typeProps);
- }
- // override default properties
- typeProps.putAll(properties);
- }
- }
- }
-
- /**
- * Process cluster scoped configuration attributes provided in blueprint.
- *
- * @param blueprintAttributes map of configuration type to configuration attributes and their values
- */
- private void processBlueprintClusterConfigAttributes(Map<String, Map<String, Map<String, String>>> blueprintAttributes) {
- for (Map.Entry<String, Map<String, Map<String, String>>> entry : blueprintAttributes.entrySet()) {
- Map<String, Map<String, String>> attributes = entry.getValue();
- if (attributes != null && !attributes.isEmpty()) {
- String type = entry.getKey();
- if (!mapClusterAttributes.containsKey(type)) {
- mapClusterAttributes.put(type, new HashMap<String, Map<String, String>>());
- }
- Map<String, Map<String, String>> typeAttrs = mapClusterAttributes.get(type);
- for (Map.Entry<String, Map<String, String>> attribute : attributes.entrySet()) {
- String attributeName = attribute.getKey();
- if (!typeAttrs.containsKey(attributeName)) {
- typeAttrs.put(attributeName, new HashMap<String, String>());
- }
- typeAttrs.get(attributeName).putAll(attribute.getValue());
- }
- }
- }
- }
-
- /**
- * Explicitly set any properties that are required but not currently provided in the stack definition.
- */
- void setMissingConfigurations(Map<String, HostGroupImpl> blueprintHostGroups) {
- // AMBARI-5206
- final Map<String , String> userProps = new HashMap<String , String>();
-
- // only add user properties to the map for
- // services actually included in the blueprint definition
- if (isServiceIncluded("OOZIE", blueprintHostGroups)) {
- userProps.put("oozie_user", "oozie-env");
- }
-
- if (isServiceIncluded("HIVE", blueprintHostGroups)) {
- userProps.put("hive_user", "hive-env");
- userProps.put("hcat_user", "hive-env");
- }
-
- if (isServiceIncluded("HBASE", blueprintHostGroups)) {
- userProps.put("hbase_user", "hbase-env");
- }
-
- if (isServiceIncluded("FALCON", blueprintHostGroups)) {
- userProps.put("falcon_user", "falcon-env");
- }
-
-
- String proxyUserHosts = "hadoop.proxyuser.%s.hosts";
- String proxyUserGroups = "hadoop.proxyuser.%s.groups";
-
- for (String property : userProps.keySet()) {
- String configType = userProps.get(property);
- Map<String, String> configs = mapClusterConfigurations.get(configType);
- if (configs != null) {
- String user = configs.get(property);
- if (user != null && !user.isEmpty()) {
- ensureProperty("core-site", String.format(proxyUserHosts, user), "*");
- ensureProperty("core-site", String.format(proxyUserGroups, user), "users");
- }
- } else {
- LOG.debug("setMissingConfigurations: no user configuration found for type = " + configType + ". This may be caused by an error in the blueprint configuration.");
- }
-
- }
- }
-
-
- /**
- * Determines if any components in the specified service are
- * included in the current blueprint's host group definitions.
- *
- * @param serviceName the Hadoop service name to query on
- * @param blueprintHostGroups the map of Host Groups in the current blueprint
- * @return true if the named service is included in the blueprint
- * false if the named service it not included in the blueprint
- */
- protected boolean isServiceIncluded(String serviceName, Map<String, HostGroupImpl> blueprintHostGroups) {
- for (String hostGroupName : blueprintHostGroups.keySet()) {
- HostGroupImpl hostGroup = blueprintHostGroups.get(hostGroupName);
- if (hostGroup.getServices().contains(serviceName)) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Ensure that the specified property exists.
- * If not, set a default value.
- *
- * @param type config type
- * @param property property name
- * @param defaultValue default value
- */
- private void ensureProperty(String type, String property, String defaultValue) {
- Map<String, String> properties = mapClusterConfigurations.get(type);
- if (properties == null) {
- properties = new HashMap<String, String>();
- mapClusterConfigurations.put(type, properties);
- }
-
- if (! properties.containsKey(property)) {
- properties.put(property, defaultValue);
- }
- }
-
- /**
- * Get set of services which are to be deployed.
- *
- * @param stack stack information
- * @param blueprintHostGroups host groups contained in blueprint
- *
- * @return set of service names which will be deployed
- */
- private Set<String> getServicesToDeploy(Stack stack, Map<String, HostGroupImpl> blueprintHostGroups) {
- Set<String> services = new HashSet<String>();
- for (HostGroupImpl group : blueprintHostGroups.values()) {
- if (! group.getHostInfo().isEmpty()) {
- services.addAll(stack.getServicesForComponents(group.getComponents()));
- }
- }
- //remove entry associated with Ambari Server since this isn't recognized by Ambari
- services.remove(null);
-
- return services;
- }
-
- /**
- * Register config groups for host group scoped configuration.
- * For each host group with configuration specified in the blueprint, a config group is created
- * and the hosts associated with the host group are assigned to the config group.
- *
- * @param clusterName name of cluster
- * @param hostGroups map of host group name to host group
- * @param stack associated stack information
- *
- * @throws ResourceAlreadyExistsException attempt to create a config group that already exists
- * @throws SystemException an unexpected exception occurs
- * @throws UnsupportedPropertyException an invalid property is provided when creating a config group
- * @throws NoSuchParentResourceException attempt to create a config group for a non-existing cluster
- */
- private void registerConfigGroups(String clusterName, Map<String, HostGroupImpl> hostGroups, Stack stack) throws
- ResourceAlreadyExistsException, SystemException,
- UnsupportedPropertyException, NoSuchParentResourceException {
-
- for (HostGroupImpl group : hostGroups.values()) {
- HostGroupEntity entity = group.getEntity();
- Map<String, Map<String, Config>> groupConfigs = new HashMap<String, Map<String, Config>>();
-
- handleGlobalsBackwardsCompability(stack, group.getConfigurationProperties(), clusterName);
- for (Map.Entry<String, Map<String, String>> entry: group.getConfigurationProperties().entrySet()) {
- String type = entry.getKey();
- String service = stack.getServiceForConfigType(type);
- Config config = new ConfigImpl(type);
- config.setTag(entity.getName());
- config.setProperties(entry.getValue());
- Map<String, Config> serviceConfigs = groupConfigs.get(service);
- if (serviceConfigs == null) {
- serviceConfigs = new HashMap<String, Config>();
- groupConfigs.put(service, serviceConfigs);
- }
- serviceConfigs.put(type, config);
- }
-
- for (Map.Entry<String, Map<String, Config>> entry : groupConfigs.entrySet()) {
- String service = entry.getKey();
- Map<String, Config> serviceConfigs = entry.getValue();
- String hostGroupName = getConfigurationGroupName(entity.getBlueprintName(), entity.getName());
- ConfigGroupRequest request = new ConfigGroupRequest(
- null, clusterName, hostGroupName, service, "Host Group Configuration",
- new HashSet<String>(group.getHostInfo()), serviceConfigs);
-
- ((ConfigGroupResourceProvider) getResourceProvider(Resource.Type.ConfigGroup)).
- createResources(Collections.singleton(request));
- }
- }
- }
-
- /**
- * Validate that a host is only mapped to a single host group.
- *
- * @param hostGroups map of host group name to host group
- */
- private void validateHostMappings(Map<String, HostGroupImpl> hostGroups) {
- Collection<String> mappedHosts = new HashSet<String>();
- Collection<String> flaggedHosts = new HashSet<String>();
-
- for (HostGroupImpl hostgroup : hostGroups.values()) {
- for (String host : hostgroup.getHostInfo()) {
- if (mappedHosts.contains(host)) {
- flaggedHosts.add(host);
- } else {
- mappedHosts.add(host);
- }
- }
- }
-
- if (! flaggedHosts.isEmpty()) {
- throw new IllegalArgumentException("A host may only be mapped to a single host group at this time." +
- " The following hosts are mapped to more than one host group: " +
- flaggedHosts);
- }
- }
-
- /**
* Determine whether or not the cluster resource identified
* by the given cluster name should be included based on the
* permissions granted to the current user.
@@ -1258,69 +515,5 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor {
return getManagementController().getClusters().checkPermission(clusterName, readOnly);
}
-
- /**
- * Internal class meant to represent the collection of configuration
- * items and configuration attributes that are associated with a given service.
- *
- * This class is used to support proper configuration versioning when
- * Ambari Blueprints is used to deploy a cluster.
- */
- private static class BlueprintServiceConfigRequest {
-
- private final String serviceName;
-
- private List<BlueprintServiceConfigElement> configElements =
- new LinkedList<BlueprintServiceConfigElement>();
-
- BlueprintServiceConfigRequest(String serviceName) {
- this.serviceName = serviceName;
- }
-
- void addConfigElement(String typeName, Map<String, String> configuration, Map<String, Map<String, String>> attributes) {
- configElements.add(new BlueprintServiceConfigElement(typeName, configuration, attributes));
- }
-
- public String getServiceName() {
- return serviceName;
- }
-
- List<BlueprintServiceConfigElement> getConfigElements() {
- return configElements;
- }
-
- }
-
- /**
- * Internal class that represents the configuration
- * and attributes for a given configuration type.
- */
- private static class BlueprintServiceConfigElement {
- private final String typeName;
-
- private final Map<String, String> configuration;
-
- private final Map<String, Map<String, String>> attributes;
-
- BlueprintServiceConfigElement(String typeName, Map<String, String> configuration, Map<String, Map<String, String>> attributes) {
- this.typeName = typeName;
- this.configuration = configuration;
- this.attributes = attributes;
- }
-
- public String getTypeName() {
- return typeName;
- }
-
- public Map<String, String> getConfiguration() {
- return configuration;
- }
-
- public Map<String, Map<String, String>> getAttributes() {
- return attributes;
- }
-
- }
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
index dea90f6..147ab8e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
@@ -32,7 +32,6 @@ import org.apache.ambari.server.DuplicateResourceException;
import org.apache.ambari.server.ObjectNotFoundException;
import org.apache.ambari.server.ParentObjectNotFoundException;
import org.apache.ambari.server.ServiceNotFoundException;
-import org.apache.ambari.server.StackAccessException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.MaintenanceStateHelper;
@@ -51,7 +50,6 @@ import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.ComponentInfo;
-import org.apache.ambari.server.state.MaintenanceState;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.ServiceComponent;
import org.apache.ambari.server.state.ServiceComponentFactory;
@@ -211,7 +209,6 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
requests.add(getRequest(propertyMap));
}
- final Predicate finalPredicate = predicate;
RequestStatusResponse response = modifyResources(new Command<RequestStatusResponse>() {
@Override
public RequestStatusResponse invoke() throws AmbariException {
@@ -251,7 +248,7 @@ public class ComponentResourceProvider extends AbstractControllerResourceProvide
}
// Create the components for the given requests.
- protected synchronized void createComponents(
+ public synchronized void createComponents(
Set<ServiceComponentRequest> requests) throws AmbariException {
if (requests.isEmpty()) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/c9f0dd0b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationTopologyException.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationTopologyException.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationTopologyException.java
new file mode 100644
index 0000000..48b54a3
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationTopologyException.java
@@ -0,0 +1,39 @@
+/**
+ * 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 distribut
+ * ed 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.controller.internal;
+
+import java.util.Collection;
+
+/**
+ * Indicates that there is a problem with the cluster topology configuration.
+ */
+public class ConfigurationTopologyException extends Exception {
+ public ConfigurationTopologyException(Collection<String> properties) {
+ super(String.format("Unable to resolve host names for the following configuration properties %s", properties));
+ }
+
+ public ConfigurationTopologyException(String s) {
+ super(s);
+ }
+
+ public ConfigurationTopologyException(String s, Throwable throwable) {
+ super(s, throwable);
+ }
+}