AMBARI-21307 Implemented PUT operation, added unit tests
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4d89a000 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4d89a000 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4d89a000 Branch: refs/heads/feature-branch-AMBARI-21307 Commit: 4d89a000ed048a047c747fdf696691d3f8957bc1 Parents: 174ab7d Author: lpuskas <lpus...@apache.org> Authored: Thu Jul 13 16:20:58 2017 +0200 Committer: lpuskas <laszlo.pus...@sequenceiq.com> Committed: Mon Aug 14 13:54:23 2017 +0200 ---------------------------------------------------------------------- .../services/AmbariConfigurationService.java | 89 ++++--- .../server/controller/ControllerModule.java | 2 + .../controller/ResourceProviderFactory.java | 23 +- .../AbstractControllerResourceProvider.java | 2 + .../AmbariConfigurationResourceProvider.java | 88 +++++-- .../internal/DefaultProviderModule.java | 2 - .../server/orm/dao/AmbariConfigurationDAO.java | 4 + ...AmbariConfigurationResourceProviderTest.java | 231 +++++++++++++++++++ 8 files changed, 363 insertions(+), 78 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/4d89a000/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java index 0c159b9..0632361 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java @@ -56,16 +56,10 @@ import io.swagger.annotations.ApiResponses; * "data": [ * { * "authentication.ldap.primaryUrl": "localhost:33389" - * }, - * { - * "authentication.ldap.secondaryUrl": "localhost:333" - * }, - * { + "authentication.ldap.secondaryUrl": "localhost:333" * "authentication.ldap.baseDn": "dc=ambari,dc=apache,dc=org" - * } - * // ...... - * ] - * } + * // ...... + * ] * } * </pre> */ @@ -74,7 +68,7 @@ import io.swagger.annotations.ApiResponses; public class AmbariConfigurationService extends BaseService { private static final String AMBARI_CONFIGURATION_REQUEST_TYPE = - "org.apache.ambari.server.api.services.AmbariConfigurationRequestSwagger"; + "org.apache.ambari.server.api.services.AmbariConfigurationRequestSwagger"; /** * Creates an ambari configuration resource. @@ -87,9 +81,9 @@ public class AmbariConfigurationService extends BaseService { @POST @Produces(MediaType.TEXT_PLAIN) @ApiOperation(value = "Creates an ambari configuration resource", - nickname = "AmbariConfigurationService#createAmbariConfiguration") + nickname = "AmbariConfigurationService#createAmbariConfiguration") @ApiImplicitParams({ - @ApiImplicitParam(dataType = AMBARI_CONFIGURATION_REQUEST_TYPE, paramType = PARAM_TYPE_BODY) + @ApiImplicitParam(dataType = AMBARI_CONFIGURATION_REQUEST_TYPE, paramType = PARAM_TYPE_BODY) }) @ApiResponses({ @ApiResponse(code = HttpStatus.SC_CREATED, message = MSG_SUCCESSFUL_OPERATION), @@ -108,24 +102,24 @@ public class AmbariConfigurationService extends BaseService { @GET @Produces(MediaType.TEXT_PLAIN) @ApiOperation(value = "Retrieve all ambari configuration resources", - nickname = "AmbariConfigurationService#getAmbariConfigurations", - notes = "Returns all Ambari configurations.", - response = AmbariConfigurationResponseSwagger.class, - responseContainer = RESPONSE_CONTAINER_LIST) + nickname = "AmbariConfigurationService#getAmbariConfigurations", + notes = "Returns all Ambari configurations.", + response = AmbariConfigurationResponseSwagger.class, + responseContainer = RESPONSE_CONTAINER_LIST) @ApiImplicitParams({ - @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, - defaultValue = "AmbariConfiguration/data, AmbariConfiguration/id, AmbariConfiguration/type", - dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), - @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION, - defaultValue = "AmbariConfiguration/id", - dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), - @ApiImplicitParam(name = QUERY_PAGE_SIZE, value = QUERY_PAGE_SIZE_DESCRIPTION, defaultValue = DEFAULT_PAGE_SIZE, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY), - @ApiImplicitParam(name = QUERY_FROM, value = QUERY_FROM_DESCRIPTION, defaultValue = DEFAULT_FROM, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), - @ApiImplicitParam(name = QUERY_TO, value = QUERY_TO_DESCRIPTION, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY) + @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, + defaultValue = "AmbariConfiguration/data, AmbariConfiguration/id, AmbariConfiguration/type", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION, + defaultValue = "AmbariConfiguration/id", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_PAGE_SIZE, value = QUERY_PAGE_SIZE_DESCRIPTION, defaultValue = DEFAULT_PAGE_SIZE, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_FROM, value = QUERY_FROM_DESCRIPTION, defaultValue = DEFAULT_FROM, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_TO, value = QUERY_TO_DESCRIPTION, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY) }) @ApiResponses(value = { - @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), - @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR) + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR) }) public Response getAmbariConfigurations(String body, @Context HttpHeaders headers, @Context UriInfo uri) { return handleRequest(headers, body, uri, Request.Type.GET, createResource(Resource.Type.AmbariConfiguration, @@ -136,16 +130,16 @@ public class AmbariConfigurationService extends BaseService { @Path("{configurationId}") @Produces(MediaType.TEXT_PLAIN) @ApiOperation(value = "Retrieve the details of an ambari configuration resource", - nickname = "AmbariConfigurationService#getAmbariConfiguration", - response = AmbariConfigurationResponseSwagger.class) + nickname = "AmbariConfigurationService#getAmbariConfiguration", + response = AmbariConfigurationResponseSwagger.class) @ApiImplicitParams({ - @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, defaultValue = "AmbariConfiguration/*", - dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY) + @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, defaultValue = "AmbariConfiguration/*", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY) }) @ApiResponses(value = { - @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), - @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), - @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR) + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR) }) public Response getAmbariConfiguration(String body, @Context HttpHeaders headers, @Context UriInfo uri, @PathParam("configurationId") String configurationId) { @@ -154,30 +148,35 @@ public class AmbariConfigurationService extends BaseService { } @PUT + @Path("{configurationId}") @Produces(MediaType.TEXT_PLAIN) @ApiOperation(value = "Updates ambari configuration resources - Not implemented yet", nickname = "AmbariConfigurationService#updateAmbariConfiguration") @ApiImplicitParams({ - @ApiImplicitParam(dataType = AMBARI_CONFIGURATION_REQUEST_TYPE, paramType = PARAM_TYPE_BODY) + @ApiImplicitParam(dataType = AMBARI_CONFIGURATION_REQUEST_TYPE, paramType = PARAM_TYPE_BODY), + @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, defaultValue = "AmbariConfiguration/*", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY) }) @ApiResponses({ - @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), - @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED), - @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS), - @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), - @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED), - @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED), - @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR), + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), + @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED), + @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR), }) - public Response updateAmbariConfiguration() { - throw new UnsupportedOperationException("Not yet implemented"); + public Response updateAmbariConfiguration(String body, @Context HttpHeaders headers, @Context UriInfo uri, + @PathParam("configurationId") String configurationId) { + return handleRequest(headers, body, uri, Request.Type.PUT, createResource(Resource.Type.AmbariConfiguration, + Collections.singletonMap(Resource.Type.AmbariConfiguration, configurationId))); } @DELETE @Path("{configurationId}") @Produces(MediaType.TEXT_PLAIN) @ApiOperation(value = "Deletes an ambari configuration resource", - nickname = "AmbariConfigurationService#deleteAmbariConfiguration") + nickname = "AmbariConfigurationService#deleteAmbariConfiguration") @ApiResponses({ @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), http://git-wip-us.apache.org/repos/asf/ambari/blob/4d89a000/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java index f3c2ec8..7a248f3 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java @@ -62,6 +62,7 @@ import org.apache.ambari.server.cleanup.ClasspathScannerUtils; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.configuration.Configuration.ConnectionPoolType; import org.apache.ambari.server.configuration.Configuration.DatabaseType; +import org.apache.ambari.server.controller.internal.AmbariConfigurationResourceProvider; import org.apache.ambari.server.controller.internal.ComponentResourceProvider; import org.apache.ambari.server.controller.internal.CredentialResourceProvider; import org.apache.ambari.server.controller.internal.HostComponentResourceProvider; @@ -467,6 +468,7 @@ public class ControllerModule extends AbstractModule { .implement(ResourceProvider.class, Names.named("credential"), CredentialResourceProvider.class) .implement(ResourceProvider.class, Names.named("kerberosDescriptor"), KerberosDescriptorResourceProvider.class) .implement(ResourceProvider.class, Names.named("upgrade"), UpgradeResourceProvider.class) + .implement(ResourceProvider.class, Names.named("ambariConfiguration"), AmbariConfigurationResourceProvider.class) .build(ResourceProviderFactory.class)); install(new FactoryModuleBuilder().implement( http://git-wip-us.apache.org/repos/asf/ambari/blob/4d89a000/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java index 3912138..36dfdf9 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java @@ -22,23 +22,22 @@ package org.apache.ambari.server.controller; import java.util.Map; import java.util.Set; +import javax.inject.Named; + import org.apache.ambari.server.controller.internal.UpgradeResourceProvider; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.Resource.Type; import org.apache.ambari.server.controller.spi.ResourceProvider; -import com.google.inject.name.Named; public interface ResourceProviderFactory { @Named("host") - ResourceProvider getHostResourceProvider(Set<String> propertyIds, - Map<Type, String> keyPropertyIds, - AmbariManagementController managementController); + ResourceProvider getHostResourceProvider(Set<String> propertyIds, Map<Type, String> keyPropertyIds, + AmbariManagementController managementController); @Named("hostComponent") - ResourceProvider getHostComponentResourceProvider(Set<String> propertyIds, - Map<Type, String> keyPropertyIds, - AmbariManagementController managementController); + ResourceProvider getHostComponentResourceProvider(Set<String> propertyIds, Map<Type, String> keyPropertyIds, + AmbariManagementController managementController); @Named("service") ResourceProvider getServiceResourceProvider(AmbariManagementController managementController); @@ -47,9 +46,8 @@ public interface ResourceProviderFactory { ResourceProvider getComponentResourceProvider(AmbariManagementController managementController); @Named("member") - ResourceProvider getMemberResourceProvider(Set<String> propertyIds, - Map<Type, String> keyPropertyIds, - AmbariManagementController managementController); + ResourceProvider getMemberResourceProvider(Set<String> propertyIds, Map<Type, String> keyPropertyIds, + AmbariManagementController managementController); @Named("hostKerberosIdentity") ResourceProvider getHostKerberosIdentityResourceProvider(AmbariManagementController managementController); @@ -61,11 +59,12 @@ public interface ResourceProviderFactory { ResourceProvider getRepositoryVersionResourceProvider(); @Named("kerberosDescriptor") - ResourceProvider getKerberosDescriptorResourceProvider(AmbariManagementController managementController, - Set<String> propertyIds, + ResourceProvider getKerberosDescriptorResourceProvider(AmbariManagementController managementController, Set<String> propertyIds, Map<Resource.Type, String> keyPropertyIds); @Named("upgrade") UpgradeResourceProvider getUpgradeResourceProvider(AmbariManagementController managementController); + @Named("ambariConfiguration") + ResourceProvider getAmbariConfigurationResourceProvider(); } http://git-wip-us.apache.org/repos/asf/ambari/blob/4d89a000/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java index b35b2a8..95d33cf 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java @@ -254,6 +254,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractAuthori return new ClusterKerberosDescriptorResourceProvider(managementController); case LoggingQuery: return new LoggingResourceProvider(propertyIds, keyPropertyIds, managementController); + case AmbariConfiguration: + return resourceProviderFactory.getAmbariConfigurationResourceProvider(); default: throw new IllegalArgumentException("Unknown type " + type); } http://git-wip-us.apache.org/repos/asf/ambari/blob/4d89a000/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java index e8f186d..2302d8b 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java @@ -25,7 +25,6 @@ import java.util.Set; import javax.inject.Inject; import org.apache.ambari.server.AmbariException; -import org.apache.ambari.server.StaticallyInject; import org.apache.ambari.server.controller.spi.NoSuchParentResourceException; import org.apache.ambari.server.controller.spi.NoSuchResourceException; import org.apache.ambari.server.controller.spi.Predicate; @@ -46,11 +45,11 @@ import org.slf4j.LoggerFactory; import com.google.common.collect.Sets; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.inject.assistedinject.AssistedInject; /** * Resource provider for AmbariConfiguration resources. */ -@StaticallyInject public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResourceProvider { private static final Logger LOGGER = LoggerFactory.getLogger(AmbariConfigurationResourceProvider.class); @@ -60,7 +59,7 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou /** * Resource property id constants. */ - private enum ResourcePropertyId { + public enum ResourcePropertyId { ID("AmbariConfiguration/id"), TYPE("AmbariConfiguration/type"), @@ -112,11 +111,12 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou @Inject - private static AmbariConfigurationDAO ambariConfigurationDAO; + private AmbariConfigurationDAO ambariConfigurationDAO; private Gson gson; - protected AmbariConfigurationResourceProvider() { + @AssistedInject + public AmbariConfigurationResourceProvider() { super(PROPERTIES, PK_PROPERTY_MAP); setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_CONFIGURATION)); setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_CONFIGURATION)); @@ -134,7 +134,12 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou ResourceAlreadyExistsException, NoSuchParentResourceException { LOGGER.info("Creating new ambari configuration resource ..."); - AmbariConfigurationEntity ambariConfigurationEntity = getEntityFromRequest(request); + AmbariConfigurationEntity ambariConfigurationEntity = null; + try { + ambariConfigurationEntity = getEntityFromRequest(request); + } catch (AmbariException e) { + throw new NoSuchParentResourceException(e.getMessage()); + } LOGGER.info("Persisting new ambari configuration: {} ", ambariConfigurationEntity); ambariConfigurationDAO.create(ambariConfigurationEntity); @@ -148,6 +153,7 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException { Set<Resource> resources = Sets.newHashSet(); + // retrieves allconfigurations, filtering is done at a higher level List<AmbariConfigurationEntity> ambariConfigurationEntities = ambariConfigurationDAO.findAll(); for (AmbariConfigurationEntity ambariConfigurationEntity : ambariConfigurationEntities) { try { @@ -181,40 +187,86 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou } + @Override + protected RequestStatus updateResourcesAuthorized(Request request, Predicate predicate) throws SystemException, + UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException { + Long idFromRequest = Long.valueOf((String) PredicateHelper.getProperties(predicate).get(ResourcePropertyId.ID.getPropertyId())); + + AmbariConfigurationEntity persistedEntity = ambariConfigurationDAO.findByPK(idFromRequest); + if (persistedEntity == null) { + String errorMsg = String.format("Entity with primary key [ %s ] not found in the database.", idFromRequest); + LOGGER.error(errorMsg); + throw new NoSuchResourceException(errorMsg); + } + + try { + + AmbariConfigurationEntity entityFromRequest = getEntityFromRequest(request); + persistedEntity.getConfigurationBaseEntity().setVersionTag(entityFromRequest.getConfigurationBaseEntity().getVersionTag()); + persistedEntity.getConfigurationBaseEntity().setVersion(entityFromRequest.getConfigurationBaseEntity().getVersion()); + persistedEntity.getConfigurationBaseEntity().setType(entityFromRequest.getConfigurationBaseEntity().getType()); + persistedEntity.getConfigurationBaseEntity().setConfigurationData(entityFromRequest.getConfigurationBaseEntity().getConfigurationData()); + persistedEntity.getConfigurationBaseEntity().setConfigurationAttributes(entityFromRequest.getConfigurationBaseEntity().getConfigurationAttributes()); + + + ambariConfigurationDAO.create(persistedEntity); + } catch (AmbariException e) { + throw new NoSuchParentResourceException(e.getMessage()); + } + + return getRequestStatus(null); + + } + private Resource toResource(AmbariConfigurationEntity entity, Set<String> requestedIds) throws AmbariException { + + if (null == entity) { + throw new IllegalArgumentException("Null entity can't be transformed into a resource"); + } + + if (null == entity.getConfigurationBaseEntity()) { + throw new IllegalArgumentException("Invalid configuration entity can't be transformed into a resource"); + } Resource resource = new ResourceImpl(Resource.Type.AmbariConfiguration); Set<Map<String, String>> configurationSet = gson.fromJson(entity.getConfigurationBaseEntity().getConfigurationData(), Set.class); setResourceProperty(resource, ResourcePropertyId.ID.getPropertyId(), entity.getId(), requestedIds); setResourceProperty(resource, ResourcePropertyId.TYPE.getPropertyId(), entity.getConfigurationBaseEntity().getType(), requestedIds); setResourceProperty(resource, ResourcePropertyId.DATA.getPropertyId(), configurationSet, requestedIds); + setResourceProperty(resource, ResourcePropertyId.VERSION.getPropertyId(), entity.getConfigurationBaseEntity().getVersion(), requestedIds); + setResourceProperty(resource, ResourcePropertyId.VERSION_TAG.getPropertyId(), entity.getConfigurationBaseEntity().getVersionTag(), requestedIds); return resource; } - private AmbariConfigurationEntity getEntityFromRequest(Request request) { + private AmbariConfigurationEntity getEntityFromRequest(Request request) throws AmbariException { AmbariConfigurationEntity ambariConfigurationEntity = new AmbariConfigurationEntity(); ambariConfigurationEntity.setConfigurationBaseEntity(new ConfigurationBaseEntity()); + // set of resource properties (eache entry in the set belongs to a different resource) + Set<Map<String, Object>> resourcePropertiesSet = request.getProperties(); + + if (resourcePropertiesSet.size() != 1) { + throw new AmbariException("There must be only one resource specified in the request"); + } + for (ResourcePropertyId resourcePropertyId : ResourcePropertyId.values()) { - Object requestValue = getValueFromRequest(resourcePropertyId, request); + Object requestValue = getValueFromResourceProperties(resourcePropertyId, resourcePropertiesSet.iterator().next()); switch (resourcePropertyId) { case DATA: if (requestValue == null) { throw new IllegalArgumentException("No configuration data is provided in the request"); } - ambariConfigurationEntity.getConfigurationBaseEntity().setConfigurationData(gson.toJson(requestValue)); break; case TYPE: ambariConfigurationEntity.getConfigurationBaseEntity().setType((String) requestValue); break; - case VERSION: - Integer version = (requestValue == null) ? DEFAULT_VERSION : Integer.valueOf((Integer) requestValue); + Integer version = (requestValue == null) ? DEFAULT_VERSION : Integer.valueOf((String) requestValue); ambariConfigurationEntity.getConfigurationBaseEntity().setVersion((version)); break; case VERSION_TAG: @@ -231,15 +283,13 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou } - private Object getValueFromRequest(ResourcePropertyId resourcePropertyIdEnum, Request request) { - LOGGER.debug("Locating resource property [{}] in the request ...", resourcePropertyIdEnum); + private Object getValueFromResourceProperties(ResourcePropertyId resourcePropertyIdEnum, Map<String, Object> resourceProperties) { + LOGGER.debug("Locating resource property [{}] in the resource properties map ...", resourcePropertyIdEnum); Object requestValue = null; - for (Map<String, Object> propertyMap : request.getProperties()) { - if (propertyMap.containsKey(resourcePropertyIdEnum.getPropertyId())) { - requestValue = propertyMap.get(resourcePropertyIdEnum.getPropertyId()); - LOGGER.debug("Found resource property {} in the request, value: {} ...", resourcePropertyIdEnum, requestValue); - break; - } + + if (resourceProperties.containsKey(resourcePropertyIdEnum.getPropertyId())) { + requestValue = resourceProperties.get(resourcePropertyIdEnum.getPropertyId()); + LOGGER.debug("Found resource property {} in the resource properties map, value: {}", resourcePropertyIdEnum, requestValue); } return requestValue; } http://git-wip-us.apache.org/repos/asf/ambari/blob/4d89a000/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java index 6e7ca0a..95c7b83 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java @@ -122,8 +122,6 @@ public class DefaultProviderModule extends AbstractProviderModule { return new ArtifactResourceProvider(managementController); case RemoteCluster: return new RemoteClusterResourceProvider(); - case AmbariConfiguration: - return new AmbariConfigurationResourceProvider(); default: LOGGER.debug("Delegating creation of resource provider for: {} to the AbstractControllerResourceProvider", type.getInternalType()); return AbstractControllerResourceProvider.getResourceProvider(type, propertyIds, http://git-wip-us.apache.org/repos/asf/ambari/blob/4d89a000/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java index c29a423..5710a7f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java @@ -19,8 +19,11 @@ import javax.inject.Singleton; import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity; +import com.google.inject.persist.Transactional; + /** * DAO dealing with ambari configuration related JPA operations. + * Operations delegate to the JPA provider implementation of CRUD operations. */ @Singleton @@ -31,6 +34,7 @@ public class AmbariConfigurationDAO extends CrudDAO<AmbariConfigurationEntity, L super(AmbariConfigurationEntity.class); } + @Transactional public void create(AmbariConfigurationEntity entity) { super.create(entity); } http://git-wip-us.apache.org/repos/asf/ambari/blob/4d89a000/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java new file mode 100644 index 0000000..d974682 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java @@ -0,0 +1,231 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ambari.server.controller.internal; + +import java.util.Map; +import java.util.Set; + +import org.apache.ambari.server.controller.spi.Predicate; +import org.apache.ambari.server.controller.spi.Request; +import org.apache.ambari.server.controller.spi.Resource; +import org.apache.ambari.server.controller.utilities.PredicateBuilder; +import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO; +import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity; +import org.apache.ambari.server.orm.entities.ConfigurationBaseEntity; +import org.easymock.Capture; +import org.easymock.EasyMock; +import org.easymock.EasyMockRule; +import org.easymock.EasyMockSupport; +import org.easymock.Mock; +import org.easymock.TestSubject; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class AmbariConfigurationResourceProviderTest extends EasyMockSupport { + + @Rule + public EasyMockRule mocks = new EasyMockRule(this); + + @Mock + private Request requestMock; + + @Mock + private AmbariConfigurationDAO ambariConfigurationDAO; + + private Capture<AmbariConfigurationEntity> ambariConfigurationEntityCapture; + + private Gson gson; + + private static final String DATA_MOCK_STR = "[\n" + + " {\n" + + " \"authentication.ldap.baseDn\" : \"dc=ambari,dc=apache,dc=org\",\n" + + " \"authentication.ldap.primaryUrl\" : \"localhost:33389\",\n" + + " \"authentication.ldap.secondaryUrl\" : \"localhost:333\"\n" + + " }\n" + + " ]"; + + private static final Long PK_LONG = Long.valueOf(1); + private static final String PK_STRING = String.valueOf(1); + private static final String VERSION_TAG = "test version"; + private static final String VERSION = "1"; + + @TestSubject + private AmbariConfigurationResourceProvider ambariConfigurationResourceProvider = new AmbariConfigurationResourceProvider(); + + @Before + public void setup() { + ambariConfigurationEntityCapture = Capture.newInstance(); + gson = new GsonBuilder().create(); + } + + @Test + public void testCreateAmbariConfigurationRequestResultsInTheProperPersistenceCall() throws Exception { + + // GIVEN + // configuration properties parsed from the request + Set<Map<String, Object>> resourcePropertiesSet = Sets.newHashSet( + new PropertiesMapBuilder() + .withId(PK_LONG) + .withVersion(VERSION) + .withVersionTag(VERSION_TAG) + .withData(DATA_MOCK_STR) + .build()); + + // mock the request to return the properties + EasyMock.expect(requestMock.getProperties()).andReturn(resourcePropertiesSet); + + // capture the entity the DAO gets called with + ambariConfigurationDAO.create(EasyMock.capture(ambariConfigurationEntityCapture)); + replayAll(); + + // WHEN + ambariConfigurationResourceProvider.createResourcesAuthorized(requestMock); + + // THEN + AmbariConfigurationEntity capturedAmbariConfigurationEntity = ambariConfigurationEntityCapture.getValue(); + Assert.assertNotNull(capturedAmbariConfigurationEntity); + Assert.assertNull("The entity identifier should be null", capturedAmbariConfigurationEntity.getId()); + Assert.assertEquals("The entity version is not the expected", Integer.valueOf(VERSION), + capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getVersion()); + Assert.assertEquals("The entity version tag is not the expected", VERSION_TAG, + capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getVersionTag()); + Assert.assertEquals("The entity data is not the expected", DATA_MOCK_STR, + gson.fromJson(capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getConfigurationData(), String.class)); + } + + @Test + public void testRemoveAmbariConfigurationRequestResultsInTheProperPersistenceCall() throws Exception { + // GIVEN + Predicate predicate = new PredicateBuilder().property( + AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate(); + + Capture<Long> pkCapture = Capture.newInstance(); + ambariConfigurationDAO.removeByPK(EasyMock.capture(pkCapture)); + replayAll(); + + // WHEN + ambariConfigurationResourceProvider.deleteResourcesAuthorized(requestMock, predicate); + + // THEN + Assert.assertEquals("The pk of the entity to be removed doen't match the expected id", Long.valueOf(1), pkCapture.getValue()); + } + + + @Test + public void testRetrieveAmbariConfigurationShouldResultsInTheProperDAOCall() throws Exception { + // GIVEN + Predicate predicate = new PredicateBuilder().property( + AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate(); + + EasyMock.expect(ambariConfigurationDAO.findAll()).andReturn(Lists.newArrayList(createDummyAmbariConfigurationEntity())); + replayAll(); + + // WHEN + Set<Resource> resourceSet = ambariConfigurationResourceProvider.getResourcesAuthorized(requestMock, predicate); + + // THEN + Assert.assertNotNull(resourceSet); + Assert.assertFalse(resourceSet.isEmpty()); + } + + @Test + public void testUpdateAmbariConfigurationShouldResultInTheProperDAOCalls() throws Exception { + // GIVEN + + Predicate predicate = new PredicateBuilder().property( + AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate(); + + // properteies in the request, representing the updated configuration + Set<Map<String, Object>> resourcePropertiesSet = Sets.newHashSet(new PropertiesMapBuilder() + .withId(PK_LONG) + .withVersion("2") + .withVersionTag("version-2") + .withData(DATA_MOCK_STR).build()); + + EasyMock.expect(requestMock.getProperties()).andReturn(resourcePropertiesSet); + + AmbariConfigurationEntity persistedEntity = createDummyAmbariConfigurationEntity(); + EasyMock.expect(ambariConfigurationDAO.findByPK(PK_LONG)).andReturn(persistedEntity); + ambariConfigurationDAO.create(EasyMock.capture(ambariConfigurationEntityCapture)); + + replayAll(); + + // WHEN + ambariConfigurationResourceProvider.updateResourcesAuthorized(requestMock, predicate); + + // the captured entity should be the updated one + AmbariConfigurationEntity updatedEntity = ambariConfigurationEntityCapture.getValue(); + + // THEN + Assert.assertNotNull(updatedEntity); + Assert.assertEquals("The updated version is wrong", Integer.valueOf(2), updatedEntity.getConfigurationBaseEntity().getVersion()); + } + + private class PropertiesMapBuilder { + + private Map<String, Object> resourcePropertiesMap = Maps.newHashMap(); + + private PropertiesMapBuilder() { + } + + public PropertiesMapBuilder withId(Long id) { + resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId(), id); + return this; + } + + private PropertiesMapBuilder withVersion(String version) { + resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.VERSION.getPropertyId(), version); + return this; + } + + private PropertiesMapBuilder withVersionTag(String versionTag) { + resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.VERSION_TAG.getPropertyId(), versionTag); + return this; + } + + private PropertiesMapBuilder withData(String dataJson) { + resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.DATA.getPropertyId(), dataJson); + return this; + } + + public Map<String, Object> build() { + return this.resourcePropertiesMap; + } + + } + + private AmbariConfigurationEntity createDummyAmbariConfigurationEntity() { + AmbariConfigurationEntity acEntity = new AmbariConfigurationEntity(); + ConfigurationBaseEntity configurationBaseEntity = new ConfigurationBaseEntity(); + acEntity.setConfigurationBaseEntity(configurationBaseEntity); + acEntity.setId(PK_LONG); + acEntity.getConfigurationBaseEntity().setConfigurationData(DATA_MOCK_STR); + acEntity.getConfigurationBaseEntity().setVersion(Integer.valueOf(VERSION)); + acEntity.getConfigurationBaseEntity().setVersionTag(VERSION_TAG); + acEntity.getConfigurationBaseEntity().setType("ldap-config"); + + return acEntity; + } + + +} \ No newline at end of file