AMBARI-22487 : New endpoint service_config_version for creating new config versions via service endpoint instead of cluster update (mradhakrishnan)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c23a33fa Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c23a33fa Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c23a33fa Branch: refs/heads/branch-feature-AMBARI-14714-blueprintv2 Commit: c23a33fa4a193b68bbc4a11144367877974d66ed Parents: e99aece Author: Madhuvanthi Radhakrishnan <[email protected]> Authored: Tue Dec 5 13:35:15 2017 -0800 Committer: Madhuvanthi Radhakrishnan <[email protected]> Committed: Tue Dec 5 13:35:15 2017 -0800 ---------------------------------------------------------------------- .../api/services/ConfigurationService.java | 5 +- .../services/ServiceConfigVersionService.java | 39 +++- .../controller/AmbariManagementController.java | 13 ++ .../AmbariManagementControllerImpl.java | 194 +++++++++++++++++++ .../controller/ServiceConfigVersionRequest.java | 24 ++- .../ServiceConfigVersionResourceProvider.java | 118 +++++++---- 6 files changed, 349 insertions(+), 44 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/c23a33fa/ambari-server/src/main/java/org/apache/ambari/server/api/services/ConfigurationService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ConfigurationService.java index 79128a2..c89a506 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ConfigurationService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ConfigurationService.java @@ -24,6 +24,7 @@ import java.util.Map; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; @@ -77,8 +78,8 @@ public class ConfigurationService extends BaseService { } @Path("service_config_versions") - public ServiceConfigVersionService getServiceConfigVersionService() { - return new ServiceConfigVersionService(m_clusterName); + public ServiceConfigVersionService getServiceConfigVersionService(@Context javax.ws.rs.core.Request request, @PathParam("serviceName") String serviceName) { + return new ServiceConfigVersionService(m_clusterName, m_serviceGroupName, serviceName); } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/c23a33fa/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceConfigVersionService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceConfigVersionService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceConfigVersionService.java index c6e3201..3150d9a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceConfigVersionService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceConfigVersionService.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.Map; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; @@ -38,20 +39,54 @@ public class ServiceConfigVersionService extends BaseService { */ private String m_clusterName; + /** + * Parent service group name. + */ + private String m_serviceGroupName = null; + + /** + * Parent service name. + */ + private String m_serviceName = null; + public ServiceConfigVersionService(String m_clusterName) { this.m_clusterName = m_clusterName; } + /** + * Constructor. + * + * @param clusterName cluster name + * @param serviceGroupName service group name + * @param serviceName service name + */ + public ServiceConfigVersionService(String clusterName, String serviceGroupName, String serviceName) { + m_clusterName = clusterName; + m_serviceGroupName = serviceGroupName; + m_serviceName = serviceName; + } + + @POST @ApiIgnore // until documented + @Produces("text/plain") + public Response createConfigurations(String body,@Context HttpHeaders headers, @Context UriInfo ui) { + + return handleRequest(headers, body, ui, Request.Type.POST, createServiceConfigResource(m_clusterName, m_serviceGroupName, m_serviceName)); + } + @GET @ApiIgnore // until documented @Produces("text/plain") public Response getServiceConfigVersions(String body, @Context HttpHeaders headers, @Context UriInfo ui) { - return handleRequest(headers, body, ui, Request.Type.GET, createServiceConfigResource(m_clusterName)); + return handleRequest(headers, body, ui, Request.Type.GET, createServiceConfigResource(m_clusterName, m_serviceGroupName, m_serviceName)); } - ResourceInstance createServiceConfigResource(String clusterName) { + ResourceInstance createServiceConfigResource(String clusterName, String serviceGroupName, String serviceName) { Map<Resource.Type,String> mapIds = new HashMap<>(); mapIds.put(Resource.Type.Cluster, clusterName); mapIds.put(Resource.Type.ServiceConfigVersion, null); + if (serviceName != null && serviceGroupName != null) { + mapIds.put(Resource.Type.ServiceGroup, serviceGroupName); + mapIds.put(Resource.Type.Service, serviceName); + } return createResource(Resource.Type.ServiceConfigVersion, mapIds); } http://git-wip-us.apache.org/repos/asf/ambari/blob/c23a33fa/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java index b5bc813..6385118 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java @@ -1016,5 +1016,18 @@ public interface AmbariManagementController { */ void removeMpack(MpackEntity mpackEntity, StackEntity stackEntity) throws IOException; + /** + * Creates serviceconfigversions and corresponding new configurations if it is an initial request + * OR + * Rollbacks to an existing serviceconfigversion if request specifies. + * @param requests + * + * @return + * + * @throws AmbariException + * + * @throws AuthorizationException + */ + Set<ServiceConfigVersionResponse> createServiceConfigVersion(Set<ServiceConfigVersionRequest> requests) throws AmbariException, AuthorizationException; } http://git-wip-us.apache.org/repos/asf/ambari/blob/c23a33fa/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java index 1eaed17..59e6622 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java @@ -116,6 +116,7 @@ import org.apache.ambari.server.metadata.ActionMetadata; import org.apache.ambari.server.metadata.RoleCommandOrder; import org.apache.ambari.server.metadata.RoleCommandOrderProvider; import org.apache.ambari.server.orm.dao.ClusterDAO; +import org.apache.ambari.server.orm.dao.ClusterServiceDAO; import org.apache.ambari.server.orm.dao.ExtensionDAO; import org.apache.ambari.server.orm.dao.ExtensionLinkDAO; import org.apache.ambari.server.orm.dao.RepositoryVersionDAO; @@ -124,6 +125,7 @@ import org.apache.ambari.server.orm.dao.StackDAO; import org.apache.ambari.server.orm.dao.WidgetDAO; import org.apache.ambari.server.orm.dao.WidgetLayoutDAO; import org.apache.ambari.server.orm.entities.ClusterEntity; +import org.apache.ambari.server.orm.entities.ClusterServiceEntity; import org.apache.ambari.server.orm.entities.ExtensionLinkEntity; import org.apache.ambari.server.orm.entities.HostEntity; import org.apache.ambari.server.orm.entities.MpackEntity; @@ -333,6 +335,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle private AmbariManagementHelper helper; @Inject + private ClusterServiceDAO clusterServiceDAO; + @Inject private ExtensionDAO extensionDAO; @Inject private ExtensionLinkDAO linkDAO; @@ -5902,4 +5906,194 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle return QuickLinkVisibilityControllerFactory.get(quickLinkProfileJson); } + @Override + public Set<ServiceConfigVersionResponse> createServiceConfigVersion(Set<ServiceConfigVersionRequest> requests) throws AmbariException, AuthorizationException { + + Set<ServiceConfigVersionResponse> serviceConfigVersionResponses = new HashSet<>(); + for (ServiceConfigVersionRequest request : requests) { + request.setIsCurrent(true); + Cluster cluster = getClusters().getCluster(request.getClusterName()); + //save data to return configurations created + List<ConfigurationResponse> configurationResponses = + new LinkedList<>(); + ServiceConfigVersionResponse serviceConfigVersionResponse = null; + List<ConfigurationRequest> desiredConfigs = request.getConfigs(); + + if (desiredConfigs != null && request.getVersion() != null) { + String msg = "Unable to set desired configs and rollback at same time, request = " + request; + LOG.error(msg); + throw new IllegalArgumentException(msg); + } + + //check if desired configs are available in request and they were changed + boolean isConfigurationCreationNeeded = false; + if (desiredConfigs != null) { + for (ConfigurationRequest configurationRequest : desiredConfigs) { + Map<String, String> requestConfigProperties = configurationRequest.getProperties(); + Map<String, Map<String, String>> requestConfigAttributes = configurationRequest.getPropertiesAttributes(); + + // processing password properties + if (requestConfigProperties != null && !requestConfigProperties.isEmpty()) { + Map<PropertyInfo.PropertyType, Set<String>> propertiesTypes = cluster.getConfigPropertiesTypes( + configurationRequest.getType() + ); + for (Entry<String, String> property : requestConfigProperties.entrySet()) { + String propertyName = property.getKey(); + String propertyValue = property.getValue(); + if ((propertiesTypes.containsKey(PropertyType.PASSWORD) && + propertiesTypes.get(PropertyType.PASSWORD).contains(propertyName)) || + (requestConfigAttributes != null && requestConfigAttributes.containsKey(PASSWORD) && + requestConfigAttributes.get(PASSWORD).containsKey(propertyName) && + requestConfigAttributes.get(PASSWORD).get(propertyName).equals("true"))) { + if (SecretReference.isSecret(propertyValue)) { + SecretReference ref = new SecretReference(propertyValue, cluster); + requestConfigProperties.put(propertyName, ref.getValue()); + } + } + } + } + + Config clusterConfig = cluster.getDesiredConfigByType(configurationRequest.getType()); + Map<String, String> clusterConfigProperties = null; + Map<String, Map<String, String>> clusterConfigAttributes = null; + if (clusterConfig != null) { + clusterConfigProperties = clusterConfig.getProperties(); + clusterConfigAttributes = clusterConfig.getPropertiesAttributes(); + if (!isAttributeMapsEqual(requestConfigAttributes, clusterConfigAttributes)) { + isConfigurationCreationNeeded = true; + break; + } + } else { + isConfigurationCreationNeeded = true; + break; + } + + if (requestConfigProperties == null || requestConfigProperties.isEmpty()) { + Config existingConfig = cluster.getConfig(configurationRequest.getType(), configurationRequest.getVersionTag()); + if (existingConfig != null) { + if (!StringUtils.equals(existingConfig.getTag(), clusterConfig.getTag())) { + isConfigurationCreationNeeded = true; + break; + } + } + } + if (requestConfigProperties != null && clusterConfigProperties != null) { + if (requestConfigProperties.size() != clusterConfigProperties.size()) { + isConfigurationCreationNeeded = true; + break; + } else { + if (cluster.getServiceByConfigType(clusterConfig.getType()) != null && clusterConfig.getServiceConfigVersions().isEmpty()) { + //If there's no service config versions containing this config (except cluster configs), recreate it even if exactly equal + LOG.warn("Existing desired config doesn't belong to any service config version, " + + "forcing config recreation, " + + "clusterName={}, type = {}, tag={}", cluster.getClusterName(), clusterConfig.getType(), + clusterConfig.getTag()); + isConfigurationCreationNeeded = true; + break; + } + for (Entry<String, String> property : requestConfigProperties.entrySet()) { + if (!StringUtils.equals(property.getValue(), clusterConfigProperties.get(property.getKey()))) { + isConfigurationCreationNeeded = true; + break; + } + } + } + } + } + } + + // set or create configuration mapping (and optionally create the map of properties) + if (isConfigurationCreationNeeded) { + + if (!desiredConfigs.isEmpty()) { + Set<Config> configs = new HashSet<>(); + String note = null; + + for (ConfigurationRequest cr : desiredConfigs) { + String configType = cr.getType(); + + if (null != cr.getProperties()) { + // !!! empty property sets are supported, and need to be able to use + // previously-defined configs (revert) + Map<String, Config> all = cluster.getConfigsByType(configType); + if (null == all || // none set + !all.containsKey(cr.getVersionTag()) || // tag not set + cr.getProperties().size() > 0) { // properties to set + + cr.setClusterName(cluster.getClusterName()); + + ClusterServiceEntity clusterServiceEntity = clusterServiceDAO.findByName(cluster.getClusterName(), request.getServiceGroupName(), request.getServiceName()); + cr.setServiceId(clusterServiceEntity.getServiceId()); + cr.setServiceGroupId(clusterServiceEntity.getServiceGroupId()); + configurationResponses.add(createConfiguration(cr)); + + LOG.info(MessageFormat.format("Applying configuration with tag ''{0}'' to cluster ''{1}'' for configuration type {2}", + cr.getVersionTag(), + request.getClusterName(), + configType)); + } + } + note = request.getNote(); + Config config = cluster.getConfig(configType, cr.getVersionTag()); + if (null != config) { + configs.add(config); + } + } + if (!configs.isEmpty()) { + Map<String, Config> existingConfigTypeToConfig = new HashMap<String, Config>(); + for (Config config : configs) { + Config existingConfig = cluster.getDesiredConfigByType(config.getType()); + existingConfigTypeToConfig.put(config.getType(), existingConfig); + } + + String authName = getAuthName(); + serviceConfigVersionResponse = cluster.addDesiredConfig(authName, configs, note); + if (serviceConfigVersionResponse != null) { + List<String> hosts = serviceConfigVersionResponse.getHosts(); + int numAffectedHosts = null != hosts ? hosts.size() : 0; + configChangeLog.info("(configchange) Changing default config. cluster: '{}', changed by: '{}', service_name: '{}', config_group: '{}', num affected hosts during creation: '{}', note: '{}'", + request.getClusterName(), authName, serviceConfigVersionResponse.getServiceName(), + serviceConfigVersionResponse.getGroupName(), numAffectedHosts, serviceConfigVersionResponse.getNote()); + + for (Config config : configs) { + configChangeLog.info("(configchange) type: '{}', tag: '{}', version: '{}'", config.getType(), config.getTag(), config.getVersion()); + + Map<String, String> configKeyToAction = getConfigKeyDeltaToAction(existingConfigTypeToConfig.get(config.getType()), config.getProperties()); + Map<String, List<String>> actionToListConfigKeys = inverseMapByValue(configKeyToAction); + + if (!actionToListConfigKeys.isEmpty()) { + String configOutput = getActionToConfigListAsString(actionToListConfigKeys); + configChangeLog.info("(configchange) Config type '{}' was modified with the following keys, {}", config.getType(), configOutput); + } + } + } + } + } + } + + if (request.getVersion() != null) { + if(!AuthorizationHelper.isAuthorized(ResourceType.CLUSTER, cluster.getResourceId(), EnumSet.of(RoleAuthorization.SERVICE_MODIFY_CONFIGS))) { + throw new AuthorizationException("The authenticated user does not have authorization to modify service configurations"); + } + + if (StringUtils.isEmpty(request.getServiceName())) { + String msg = "Service name and version should be specified in service config version"; + LOG.error(msg); + throw new IllegalArgumentException(msg); + } + serviceConfigVersionResponse = cluster.setServiceConfigVersion( + cluster.getService(request.getServiceGroupName(), request.getServiceName()).getServiceId(), + request.getVersion(), getAuthName(), + request.getNote()); + } + + if (serviceConfigVersionResponse != null) { + if (!configurationResponses.isEmpty()) { + serviceConfigVersionResponse.setConfigurations(configurationResponses); + } + } + serviceConfigVersionResponses.add(serviceConfigVersionResponse); + } + return serviceConfigVersionResponses; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/c23a33fa/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceConfigVersionRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceConfigVersionRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceConfigVersionRequest.java index 29a7a42..518503f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceConfigVersionRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceConfigVersionRequest.java @@ -18,6 +18,9 @@ package org.apache.ambari.server.controller; + +import java.util.List; + public class ServiceConfigVersionRequest { private String clusterName; private String serviceName; @@ -28,11 +31,13 @@ public class ServiceConfigVersionRequest { private String userName; private String note; private Boolean isCurrent; + private List<ConfigurationRequest> configs; + private String stackId; public ServiceConfigVersionRequest() { } - public ServiceConfigVersionRequest(String clusterName, String serviceGroupName, String serviceName, Long version, Long createTime, Long applyTime, String userName, Boolean isCurrent) { + public ServiceConfigVersionRequest(String clusterName, String serviceGroupName, String serviceName, Long version, Long createTime, Long applyTime, String userName, Boolean isCurrent, String note, String stackId) { this.clusterName = clusterName; this.serviceGroupName = serviceGroupName; this.serviceName = serviceName; @@ -41,6 +46,8 @@ public class ServiceConfigVersionRequest { this.applyTime = applyTime; this.userName = userName; this.isCurrent = isCurrent; + this.note = note; + this.stackId = stackId; } public String getServiceName() { @@ -115,6 +122,21 @@ public class ServiceConfigVersionRequest { this.serviceGroupName = serviceGroupName; } + public String getStackId() { + return stackId; + } + + public void setStackId(String stackId) { + this.stackId = stackId; + } + + public void setConfigs(List<ConfigurationRequest> configRequests) { + configs = configRequests; + } + + public List<ConfigurationRequest> getConfigs() { + return configs; + } @Override public String toString() { http://git-wip-us.apache.org/repos/asf/ambari/blob/c23a33fa/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceConfigVersionResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceConfigVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceConfigVersionResourceProvider.java index cbc08eb..927f4ba 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceConfigVersionResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceConfigVersionResourceProvider.java @@ -25,6 +25,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -32,6 +33,7 @@ import java.util.TreeMap; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.controller.AmbariManagementController; +import org.apache.ambari.server.controller.ConfigurationRequest; import org.apache.ambari.server.controller.ConfigurationResponse; import org.apache.ambari.server.controller.ServiceConfigVersionRequest; import org.apache.ambari.server.controller.ServiceConfigVersionResponse; @@ -45,6 +47,7 @@ import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException; 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.security.authorization.AuthorizationException; import org.apache.ambari.server.security.authorization.RoleAuthorization; public class ServiceConfigVersionResourceProvider extends @@ -58,10 +61,10 @@ public class ServiceConfigVersionResourceProvider extends public static final String SERVICE_CONFIG_VERSION_SERVICE_ID_PROPERTY_ID = PropertyHelper.getPropertyId(null, "service_id"); public static final String SERVICE_CONFIG_VERSION_CREATE_TIME_PROPERTY_ID = PropertyHelper.getPropertyId(null, "createtime"); public static final String SERVICE_CONFIG_VERSION_USER_PROPERTY_ID = PropertyHelper.getPropertyId(null, "user"); - public static final String SERVICE_CONFIG_VERSION_NOTE_PROPERTY_ID = PropertyHelper.getPropertyId(null, "service_config_version_note"); + public static final String SERVICE_CONFIG_VERSION_NOTE_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceConfigVersion", "service_config_version_note"); public static final String SERVICE_CONFIG_VERSION_GROUP_ID_PROPERTY_ID = PropertyHelper.getPropertyId(null, "group_id"); public static final String SERVICE_CONFIG_VERSION_GROUP_NAME_PROPERTY_ID = PropertyHelper.getPropertyId(null, "group_name"); - public static final String SERVICE_CONFIG_VERSION_STACK_ID_PROPERTY_ID = PropertyHelper.getPropertyId(null, "stack_id"); + public static final String SERVICE_CONFIG_VERSION_STACK_ID_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceConfigVersion", "stack_id"); public static final String SERVICE_CONFIG_VERSION_IS_CURRENT_PROPERTY_ID = PropertyHelper.getPropertyId(null, "is_current"); public static final String SERVICE_CONFIG_VERSION_IS_COMPATIBLE_PROPERTY_ID = PropertyHelper.getPropertyId(null, "is_cluster_compatible"); public static final String SERVICE_CONFIG_VERSION_HOSTS_PROPERTY_ID = PropertyHelper.getPropertyId(null, "hosts"); @@ -92,11 +95,13 @@ public class ServiceConfigVersionResourceProvider extends PROPERTY_IDS.add(SERVICE_CONFIG_VERSION_HOSTS_PROPERTY_ID); PROPERTY_IDS.add(SERVICE_CONFIG_VERSION_CONFIGURATIONS_PROPERTY_ID); PROPERTY_IDS.add(SERVICE_CONFIG_VERSION_IS_COMPATIBLE_PROPERTY_ID); + PROPERTY_IDS.add(SERVICE_CONFIG_VERSION_SERVICE_GROUP_NAME_PROPERTY_ID); // keys - KEY_PROPERTY_IDS.put(Resource.Type.Service,SERVICE_CONFIG_VERSION_SERVICE_NAME_PROPERTY_ID); - KEY_PROPERTY_IDS.put(Resource.Type.Cluster,SERVICE_CONFIG_VERSION_CLUSTER_NAME_PROPERTY_ID); - KEY_PROPERTY_IDS.put(Resource.Type.ServiceConfigVersion,SERVICE_CONFIG_VERSION_PROPERTY_ID); + KEY_PROPERTY_IDS.put(Resource.Type.Service, SERVICE_CONFIG_VERSION_SERVICE_NAME_PROPERTY_ID); + KEY_PROPERTY_IDS.put(Resource.Type.Cluster, SERVICE_CONFIG_VERSION_CLUSTER_NAME_PROPERTY_ID); + KEY_PROPERTY_IDS.put(Resource.Type.ServiceConfigVersion, SERVICE_CONFIG_VERSION_PROPERTY_ID); + KEY_PROPERTY_IDS.put(Resource.Type.ServiceGroup, SERVICE_CONFIG_VERSION_SERVICE_GROUP_NAME_PROPERTY_ID); } @@ -106,7 +111,7 @@ public class ServiceConfigVersionResourceProvider extends private static Set<String> pkPropertyIds = new HashSet<>(Arrays.asList(new String[]{ SERVICE_CONFIG_VERSION_CLUSTER_NAME_PROPERTY_ID, - SERVICE_CONFIG_VERSION_SERVICE_NAME_PROPERTY_ID})); + SERVICE_CONFIG_VERSION_SERVICE_NAME_PROPERTY_ID, SERVICE_CONFIG_VERSION_SERVICE_GROUP_NAME_PROPERTY_ID})); // ----- Constructors ------------------------------------------------------ @@ -133,7 +138,63 @@ public class ServiceConfigVersionResourceProvider extends @Override public RequestStatus createResources(Request request) throws SystemException, UnsupportedPropertyException, ResourceAlreadyExistsException, NoSuchParentResourceException { - throw new UnsupportedOperationException("Cannot explicitly create service config version"); + final Set<ServiceConfigVersionRequest> requests = new HashSet<>(); + Set<ServiceConfigVersionResponse> responses = new HashSet<>(); + + for (Map<String, Object> propertyMap : request.getProperties()) { + requests.add(createRequest(propertyMap)); + } + responses = createResources(new Command<Set<ServiceConfigVersionResponse>>() { + @Override + public Set<ServiceConfigVersionResponse> invoke() throws AmbariException, AuthorizationException { + return getManagementController().createServiceConfigVersion(requests); + } + }); + + Set<Resource> associatedResources = new HashSet<>(); + for (ServiceConfigVersionResponse serviceConfigVersionResponse : responses) { + Resource resource = new ResourceImpl(Resource.Type.ServiceConfigVersion); + resource.setProperty(ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_SERVICE_GROUP_NAME_PROPERTY_ID, + serviceConfigVersionResponse.getServiceGroupName()); + resource.setProperty(ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_SERVICE_GROUP_ID_PROPERTY_ID, + serviceConfigVersionResponse.getServiceGroupId()); + resource.setProperty(ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_SERVICE_NAME_PROPERTY_ID, + serviceConfigVersionResponse.getServiceName()); + resource.setProperty(ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_SERVICE_ID_PROPERTY_ID, + serviceConfigVersionResponse.getServiceId()); + resource.setProperty(ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_PROPERTY_ID, + serviceConfigVersionResponse.getVersion()); + resource.setProperty(ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_NOTE_PROPERTY_ID, + serviceConfigVersionResponse.getNote()); + resource.setProperty(ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_GROUP_ID_PROPERTY_ID, + serviceConfigVersionResponse.getGroupId()); + resource.setProperty(ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_GROUP_NAME_PROPERTY_ID, + serviceConfigVersionResponse.getGroupName()); + if (serviceConfigVersionResponse.getConfigurations() != null) { + resource.setProperty( + ServiceConfigVersionResourceProvider.SERVICE_CONFIG_VERSION_CONFIGURATIONS_PROPERTY_ID, + serviceConfigVersionResponse.getConfigurations()); + } + associatedResources.add(resource); + } + + return getRequestStatus(null, associatedResources); + } + + private List<ConfigurationRequest> getConfigurationRequests(Set<Map<String, Object>> configurations) { + List<ConfigurationRequest> configs = new LinkedList<>(); + for (Map<String, Object> value: configurations) { + ConfigurationRequest newConfig = new ConfigurationRequest(); + for (Map.Entry<String, Object> e : value.entrySet()) { + String propName = + PropertyHelper.getPropertyName("Config" + '/' + e.getKey()); + String absCatategory = + PropertyHelper.getPropertyCategory("Config" + '/' + e.getKey()); + parseProperties(newConfig, absCatategory, propName, e.getValue() == null ? null : e.getValue().toString()); + } + configs.add(newConfig); + } + return configs; } @Override @@ -159,6 +220,7 @@ public class ServiceConfigVersionResourceProvider extends Resource resource = new ResourceImpl(Resource.Type.ServiceConfigVersion); resource.setProperty(SERVICE_CONFIG_VERSION_CLUSTER_NAME_PROPERTY_ID, clusterName); resource.setProperty(SERVICE_CONFIG_VERSION_SERVICE_NAME_PROPERTY_ID, response.getServiceName()); + resource.setProperty(SERVICE_CONFIG_VERSION_SERVICE_GROUP_NAME_PROPERTY_ID, response.getServiceGroupName()); resource.setProperty(SERVICE_CONFIG_VERSION_USER_PROPERTY_ID, response.getUserName()); resource.setProperty(SERVICE_CONFIG_VERSION_PROPERTY_ID, response.getVersion()); resource.setProperty(SERVICE_CONFIG_VERSION_CREATE_TIME_PROPERTY_ID, response.getCreateTime()); @@ -186,36 +248,6 @@ public class ServiceConfigVersionResourceProvider extends throw new UnsupportedOperationException("Cannot delete service config version"); } - @Override - public Set<String> checkPropertyIds(Set<String> propertyIds) { - propertyIds = super.checkPropertyIds(propertyIds); - - if (propertyIds.isEmpty()) { - return propertyIds; - } - Set<String> unsupportedProperties = new HashSet<>(); - - for (String propertyId : propertyIds) { - if (!propertyId.equals("cluster_name") && !propertyId.equals("service_config_version") && - !propertyId.equals("service_group_name")&& - !propertyId.equals("service_name") && !propertyId.equals("createtime") && - !propertyId.equals("appliedtime") && !propertyId.equals("user") && - !propertyId.equals("service_config_version_note") && - !propertyId.equals("group_id") && - !propertyId.equals("group_name") && - !propertyId.equals("stack_id") && - !propertyId.equals("is_current") && - !propertyId.equals("is_cluster_compatible") && - !propertyId.equals("hosts")) { - - unsupportedProperties.add(propertyId); - - } - } - return unsupportedProperties; - } - - private ServiceConfigVersionRequest createRequest(Map<String, Object> properties) { String clusterName = (String) properties.get(SERVICE_CONFIG_VERSION_CLUSTER_NAME_PROPERTY_ID); String serviceGroupName = (String) properties.get(SERVICE_CONFIG_VERSION_SERVICE_GROUP_NAME_PROPERTY_ID); @@ -224,8 +256,16 @@ public class ServiceConfigVersionResourceProvider extends Boolean isCurrent = Boolean.valueOf((String) properties.get(SERVICE_CONFIG_VERSION_IS_CURRENT_PROPERTY_ID)); Object versionObject = properties.get(SERVICE_CONFIG_VERSION_PROPERTY_ID); Long version = versionObject == null ? null : Long.valueOf(versionObject.toString()); - - return new ServiceConfigVersionRequest(clusterName, serviceGroupName, serviceName, version, null, null, user, isCurrent); + String note = (String) properties.get(SERVICE_CONFIG_VERSION_NOTE_PROPERTY_ID); + String stackId = (String) properties.get(SERVICE_CONFIG_VERSION_STACK_ID_PROPERTY_ID); + ServiceConfigVersionRequest scvr = new ServiceConfigVersionRequest(clusterName, serviceGroupName, serviceName, version, null, null, user, isCurrent, note, stackId); + if(version == null && properties.containsKey("configurations")) { + List<ConfigurationRequest> configRequests = getConfigurationRequests((Set<Map<String, Object>>) properties.get("configurations")); + if (!configRequests.isEmpty()) { + scvr.setConfigs(configRequests); + } + } + return scvr; } private List<Map<String, Object>> convertToSubResources(final String clusterName, List<ConfigurationResponse> configs) {
