From d78e6cf73cfe4751c5344f41c4a64d5cf5850e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20R=C3=ADos?= Date: Mon, 12 Nov 2018 20:32:36 +0100 Subject: [PATCH] Adding parameter transformer to backing services (#147) * Adding parameters transformer for backing services * Generalizing ParametersTransformers Finishes #139 --- .../CloudFoundryAcceptanceTest.java | 14 ++- .../AppBrokerAutoConfiguration.java | 30 ++++- .../AppBrokerAutoConfigurationTest.java | 6 +- .../appbroker/deployer/BackingService.java | 52 +++++++-- ...tionsParametersTransformationService.java} | 29 ++--- ...rvicesParametersTransformationService.java | 60 ++++++++++ ...ntMappingParametersTransformerFactory.java | 15 +-- ...erMappingParametersTransformerFactory.java | 67 +++++++++++ .../parameters/ParametersTransformer.java | 7 +- .../ParametersTransformerFactory.java | 4 +- ...tyMappingParametersTransformerFactory.java | 19 ++-- ...ploymentCreateServiceInstanceWorkflow.java | 19 ++-- ...ploymentUpdateServiceInstanceWorkflow.java | 6 +- ...sParametersTransformationServiceTest.java} | 69 ++++++----- ...esParametersTransformationServiceTest.java | 87 ++++++++++++++ ...ppingParametersTransformerFactoryTest.java | 13 ++- ...ppingParametersTransformerFactoryTest.java | 68 +++++++++++ ...ppingParametersTransformerFactoryTest.java | 2 +- ...mentCreateServiceInstanceWorkflowTest.java | 21 +++- ...mentUpdateServiceInstanceWorkflowTest.java | 16 +-- .../CreateServiceInstanceRequest.java | 10 +- ...CustomCreationParametersComponentTest.java | 18 +-- ...ceWithServicesParametersComponentTest.java | 107 ++++++++++++++++++ .../fixtures/CloudControllerStubFixture.java | 11 ++ .../responses/cloudcontroller/get-info.json | 5 +- 25 files changed, 623 insertions(+), 132 deletions(-) rename spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/{ParametersTransformationService.java => BackingApplicationsParametersTransformationService.java} (67%) create mode 100644 spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/BackingServicesParametersTransformationService.java create mode 100644 spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParameterMappingParametersTransformerFactory.java rename spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/{ParametersTransformationServiceTest.java => BackingApplicationsParametersTransformationServiceTest.java} (74%) create mode 100644 spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/BackingServicesParametersTransformationServiceTest.java create mode 100644 spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/ParameterMappingParametersTransformerFactoryTest.java create mode 100644 spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithServicesParametersComponentTest.java diff --git a/spring-cloud-app-broker-acceptance-tests/src/test/java/org.springframework.cloud.appbroker.acceptance/CloudFoundryAcceptanceTest.java b/spring-cloud-app-broker-acceptance-tests/src/test/java/org.springframework.cloud.appbroker.acceptance/CloudFoundryAcceptanceTest.java index 28bed10..3e54dca 100644 --- a/spring-cloud-app-broker-acceptance-tests/src/test/java/org.springframework.cloud.appbroker.acceptance/CloudFoundryAcceptanceTest.java +++ b/spring-cloud-app-broker-acceptance-tests/src/test/java/org.springframework.cloud.appbroker.acceptance/CloudFoundryAcceptanceTest.java @@ -69,12 +69,14 @@ class CloudFoundryAcceptanceTest { } private Mono initializeBroker(String... backingAppProperties) { - return cloudFoundryService - .getOrCreateDefaultOrganization() - .then(cloudFoundryService.getOrCreateDefaultSpace()) - .then(cloudFoundryService.pushBrokerApp(SAMPLE_BROKER_APP_NAME, getSampleBrokerAppPath(), backingAppProperties)) - .then(cloudFoundryService.createServiceBroker(SERVICE_BROKER_NAME, SAMPLE_BROKER_APP_NAME)) - .then(cloudFoundryService.enableServiceBrokerAccess(SERVICE_NAME)); + return cleanup() + .then( + cloudFoundryService + .getOrCreateDefaultOrganization() + .then(cloudFoundryService.getOrCreateDefaultSpace()) + .then(cloudFoundryService.pushBrokerApp(SAMPLE_BROKER_APP_NAME, getSampleBrokerAppPath(), backingAppProperties)) + .then(cloudFoundryService.createServiceBroker(SERVICE_BROKER_NAME, SAMPLE_BROKER_APP_NAME)) + .then(cloudFoundryService.enableServiceBrokerAccess(SERVICE_NAME))); } private Mono cleanup() { diff --git a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfiguration.java b/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfiguration.java index 76e1319..6c133b9 100644 --- a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfiguration.java +++ b/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfiguration.java @@ -25,6 +25,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.appbroker.deployer.AppDeployer; import org.springframework.cloud.appbroker.deployer.BackingAppDeploymentService; +import org.springframework.cloud.appbroker.deployer.BackingApplication; +import org.springframework.cloud.appbroker.deployer.BackingService; import org.springframework.cloud.appbroker.deployer.BackingServicesProvisionService; import org.springframework.cloud.appbroker.deployer.BrokeredServices; import org.springframework.cloud.appbroker.deployer.DeployerClient; @@ -33,8 +35,10 @@ import org.springframework.cloud.appbroker.extensions.credentials.CredentialProv import org.springframework.cloud.appbroker.extensions.credentials.CredentialProviderService; import org.springframework.cloud.appbroker.extensions.credentials.SimpleCredentialGenerator; import org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityBasicAuthCredentialProviderFactory; +import org.springframework.cloud.appbroker.extensions.parameters.BackingApplicationsParametersTransformationService; +import org.springframework.cloud.appbroker.extensions.parameters.BackingServicesParametersTransformationService; import org.springframework.cloud.appbroker.extensions.parameters.EnvironmentMappingParametersTransformerFactory; -import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformationService; +import org.springframework.cloud.appbroker.extensions.parameters.ParameterMappingParametersTransformerFactory; import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformerFactory; import org.springframework.cloud.appbroker.extensions.parameters.PropertyMappingParametersTransformerFactory; import org.springframework.cloud.appbroker.extensions.targets.SpacePerServiceInstance; @@ -102,8 +106,20 @@ public class AppBrokerAutoConfiguration { } @Bean - public ParametersTransformationService parametersTransformerService(List> transformers) { - return new ParametersTransformationService(transformers); + public ParameterMappingParametersTransformerFactory parameterMappingParametersTransformerFactory() { + return new ParameterMappingParametersTransformerFactory(); + } + + @Bean + public BackingApplicationsParametersTransformationService backingApplicationsParametersTransformationService( + List> transformers) { + return new BackingApplicationsParametersTransformationService(transformers); + } + + @Bean + public BackingServicesParametersTransformationService backingServicesParametersTransformationService( + List> transformers) { + return new BackingServicesParametersTransformationService(transformers); } @ConditionalOnMissingBean(CredentialGenerator.class) @@ -140,14 +156,16 @@ public class AppBrokerAutoConfiguration { @Bean public CreateServiceInstanceWorkflow appDeploymentCreateServiceInstanceWorkflow(BrokeredServices brokeredServices, BackingAppDeploymentService backingAppDeploymentService, - ParametersTransformationService parametersTransformationService, + BackingApplicationsParametersTransformationService applicationsParametersTransformationService, + BackingServicesParametersTransformationService servicesParametersTransformationService, CredentialProviderService credentialProviderService, TargetService targetService, BackingServicesProvisionService backingServicesProvisionService) { return new AppDeploymentCreateServiceInstanceWorkflow( brokeredServices, backingAppDeploymentService, - parametersTransformationService, + applicationsParametersTransformationService, + servicesParametersTransformationService, credentialProviderService, targetService, backingServicesProvisionService); @@ -170,7 +188,7 @@ public class AppBrokerAutoConfiguration { @Bean public UpdateServiceInstanceWorkflow updateServiceInstanceWorkflow(BrokeredServices brokeredServices, BackingAppDeploymentService backingAppDeploymentService, - ParametersTransformationService parametersTransformationService, + BackingApplicationsParametersTransformationService parametersTransformationService, TargetService targetService) { return new AppDeploymentUpdateServiceInstanceWorkflow(brokeredServices, backingAppDeploymentService, parametersTransformationService, targetService); } diff --git a/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfigurationTest.java b/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfigurationTest.java index 27f4174..bfb084e 100644 --- a/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfigurationTest.java +++ b/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfigurationTest.java @@ -26,13 +26,14 @@ import org.springframework.cloud.appbroker.deployer.BackingServicesProvisionServ import org.springframework.cloud.appbroker.deployer.BrokeredServices; import org.springframework.cloud.appbroker.deployer.DeployerClient; import org.springframework.cloud.appbroker.extensions.credentials.CredentialProviderService; +import org.springframework.cloud.appbroker.extensions.parameters.BackingApplicationsParametersTransformationService; +import org.springframework.cloud.appbroker.extensions.parameters.BackingServicesParametersTransformationService; import org.springframework.cloud.appbroker.extensions.targets.TargetService; import org.springframework.cloud.appbroker.service.WorkflowServiceInstanceBindingService; import org.springframework.cloud.appbroker.service.WorkflowServiceInstanceService; import org.springframework.cloud.appbroker.state.ServiceInstanceBindingStateRepository; import org.springframework.cloud.appbroker.state.ServiceInstanceStateRepository; import org.springframework.cloud.appbroker.workflow.instance.AppDeploymentCreateServiceInstanceWorkflow; -import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformationService; import org.springframework.cloud.appbroker.workflow.instance.AppDeploymentDeleteServiceInstanceWorkflow; import org.springframework.cloud.appbroker.workflow.instance.AppDeploymentUpdateServiceInstanceWorkflow; @@ -99,7 +100,8 @@ class AppBrokerAutoConfigurationTest { assertThat(context).hasSingleBean(ServiceInstanceStateRepository.class); assertThat(context).hasSingleBean(ServiceInstanceBindingStateRepository.class); assertThat(context).hasSingleBean(BackingAppDeploymentService.class); - assertThat(context).hasSingleBean(ParametersTransformationService.class); + assertThat(context).hasSingleBean(BackingApplicationsParametersTransformationService.class); + assertThat(context).hasSingleBean(BackingServicesParametersTransformationService.class); assertThat(context).hasSingleBean(CredentialProviderService.class); assertThat(context).hasSingleBean(TargetService.class); assertThat(context).hasSingleBean(BackingServicesProvisionService.class); diff --git a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/deployer/BackingService.java b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/deployer/BackingService.java index 45c4eaf..6f2e306 100644 --- a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/deployer/BackingService.java +++ b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/deployer/BackingService.java @@ -16,7 +16,10 @@ package org.springframework.cloud.appbroker.deployer; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -25,18 +28,25 @@ public class BackingService { private String serviceInstanceName; private String name; private String plan; - private Map parameters; + private Map parameters; private Map properties; + private List parametersTransformers; private BackingService() { } - BackingService(String serviceInstanceName, String name, String plan, Map parameters, Map properties) { + BackingService(String serviceInstanceName, + String name, + String plan, + Map parameters, + Map properties, + List parametersTransformers) { this.serviceInstanceName = serviceInstanceName; this.name = name; this.plan = plan; this.parameters = parameters; this.properties = properties; + this.parametersTransformers = parametersTransformers; } BackingService(BackingService backingServiceToCopy) { @@ -49,6 +59,9 @@ public class BackingService { this.properties = backingServiceToCopy.properties == null ? new HashMap<>() : new HashMap<>(backingServiceToCopy.properties); + this.parametersTransformers = backingServiceToCopy.parametersTransformers == null + ? new ArrayList<>() + : new ArrayList<>(backingServiceToCopy.parametersTransformers); } public String getServiceInstanceName() { @@ -75,11 +88,11 @@ public class BackingService { this.plan = plan; } - public Map getParameters() { + public Map getParameters() { return parameters; } - public void setParameters(Map parameters) { + public void setParameters(Map parameters) { this.parameters = parameters; } @@ -91,6 +104,18 @@ public class BackingService { this.properties = properties; } + public List getParametersTransformers() { + return parametersTransformers; + } + + public void setParametersTransformers(List parametersTransformers) { + this.parametersTransformers = parametersTransformers; + } + + public void addParameter(String key, Object value) { + parameters.put(key, value); + } + @Override public boolean equals(Object o) { if (this == o) { @@ -104,12 +129,13 @@ public class BackingService { Objects.equals(name, that.name) && Objects.equals(plan, that.plan) && Objects.equals(parameters, that.parameters) && - Objects.equals(properties, that.properties); + Objects.equals(properties, that.properties) && + Objects.equals(parametersTransformers, that.parametersTransformers); } @Override public int hashCode() { - return Objects.hash(serviceInstanceName, name, plan, parameters, properties); + return Objects.hash(serviceInstanceName, name, plan, parameters, properties, parametersTransformers); } @Override @@ -120,6 +146,7 @@ public class BackingService { ", plan='" + plan + '\'' + ", parameters=" + parameters + ", properties=" + properties + + ", parametersTransformers=" + parametersTransformers + '}'; } @@ -132,14 +159,15 @@ public class BackingService { private String serviceInstanceName; private String name; private String plan; - private Map parameters = new HashMap<>(); + private Map parameters = new HashMap<>(); private Map properties = new HashMap<>(); + private final List parameterTransformers = new ArrayList<>(); BackingServiceBuilder() { } public BackingService build() { - return new BackingService(serviceInstanceName, name, plan, parameters, properties); + return new BackingService(serviceInstanceName, name, plan, parameters, properties, parameterTransformers); } public BackingServiceBuilder serviceInstanceName(String serviceInstanceName) { @@ -157,7 +185,7 @@ public class BackingService { return this; } - public BackingServiceBuilder parameters(Map parameters) { + public BackingServiceBuilder parameters(Map parameters) { this.parameters = parameters; return this; } @@ -166,6 +194,12 @@ public class BackingService { this.properties = properties; return this; } + + public BackingServiceBuilder parameterTransformers(ParametersTransformerSpec... parameterTransformers) { + this.parameterTransformers.addAll(Arrays.asList(parameterTransformers)); + return this; + } + } } diff --git a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformationService.java b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/BackingApplicationsParametersTransformationService.java similarity index 67% rename from spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformationService.java rename to spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/BackingApplicationsParametersTransformationService.java index 8ea8894..f5bf542 100644 --- a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformationService.java +++ b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/BackingApplicationsParametersTransformationService.java @@ -20,35 +20,36 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import org.springframework.cloud.appbroker.extensions.ExtensionLocator; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.springframework.cloud.appbroker.deployer.BackingApplication; import org.springframework.cloud.appbroker.deployer.ParametersTransformerSpec; +import org.springframework.cloud.appbroker.extensions.ExtensionLocator; -public class ParametersTransformationService { +public class BackingApplicationsParametersTransformationService { - private final ExtensionLocator locator; + private final ExtensionLocator> locator; - public ParametersTransformationService(List> factories) { + public BackingApplicationsParametersTransformationService( + List> factories) { locator = new ExtensionLocator<>(factories); } public Mono> transformParameters(List backingApplications, Map parameters) { return Flux.fromIterable(backingApplications) - .flatMap(backingApplication -> { - List specs = getTransformerSpecsForApplication(backingApplication); + .flatMap(backingApplication -> { + List specs = getTransformerSpecsForApplication(backingApplication); - return Flux.fromIterable(specs) - .flatMap(spec -> { - ParametersTransformer transformer = locator.getByName(spec.getName(), spec.getArgs()); - return transformer.transform(backingApplication, parameters); - }) - .then(Mono.just(backingApplication)); - }) - .collectList(); + return Flux.fromIterable(specs) + .flatMap(spec -> { + ParametersTransformer transformer = locator.getByName(spec.getName(), spec.getArgs()); + return transformer.transform(backingApplication, parameters); + }) + .then(Mono.just(backingApplication)); + }) + .collectList(); } private List getTransformerSpecsForApplication(BackingApplication backingApplication) { diff --git a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/BackingServicesParametersTransformationService.java b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/BackingServicesParametersTransformationService.java new file mode 100644 index 0000000..5371be8 --- /dev/null +++ b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/BackingServicesParametersTransformationService.java @@ -0,0 +1,60 @@ +/* + * Copyright 2016-2018 the original author or authors. + * + * 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.springframework.cloud.appbroker.extensions.parameters; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.appbroker.deployer.BackingService; +import org.springframework.cloud.appbroker.deployer.ParametersTransformerSpec; +import org.springframework.cloud.appbroker.extensions.ExtensionLocator; + +public class BackingServicesParametersTransformationService { + + private final ExtensionLocator> locator; + + public BackingServicesParametersTransformationService( + List> factories) { + locator = new ExtensionLocator<>(factories); + } + + public Mono> transformParameters(List backingServices, + Map parameters) { + return Flux.fromIterable(backingServices) + .flatMap(backingService -> { + List specs = getTransformerSpecsForService(backingService); + + return Flux.fromIterable(specs) + .flatMap(spec -> { + ParametersTransformer transformer = locator.getByName(spec.getName(), spec.getArgs()); + return transformer.transform(backingService, parameters); + }) + .then(Mono.just(backingService)); + }) + .collectList(); + } + + private List getTransformerSpecsForService(BackingService backingService) { + return backingService.getParametersTransformers() == null + ? Collections.emptyList() + : backingService.getParametersTransformers(); + } +} diff --git a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/EnvironmentMappingParametersTransformerFactory.java b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/EnvironmentMappingParametersTransformerFactory.java index 9275529..ad7908f 100644 --- a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/EnvironmentMappingParametersTransformerFactory.java +++ b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/EnvironmentMappingParametersTransformerFactory.java @@ -20,20 +20,20 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -import org.springframework.cloud.appbroker.deployer.BackingApplication; import reactor.core.publisher.Mono; +import org.springframework.cloud.appbroker.deployer.BackingApplication; + public class EnvironmentMappingParametersTransformerFactory extends - ParametersTransformerFactory { + ParametersTransformerFactory { public EnvironmentMappingParametersTransformerFactory() { super(Config.class); } @Override - public ParametersTransformer create(Config config) { - return (backingApplication, parameters) -> - transform(backingApplication, parameters, config.getIncludes()); + public ParametersTransformer create(Config config) { + return (backingType, parameters) -> transform(backingType, parameters, config.getIncludes()); } private Mono transform(BackingApplication backingApplication, @@ -41,8 +41,8 @@ public class EnvironmentMappingParametersTransformerFactory extends List include) { if (parameters != null) { parameters.keySet().stream() - .filter(include::contains) - .forEach(key -> backingApplication.addEnvironment(key, parameters.get(key).toString())); + .filter(include::contains) + .forEach(key -> backingApplication.addEnvironment(key, parameters.get(key).toString())); } return Mono.just(backingApplication); @@ -50,6 +50,7 @@ public class EnvironmentMappingParametersTransformerFactory extends @SuppressWarnings("WeakerAccess") public static class Config { + private String include; public Config() { diff --git a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParameterMappingParametersTransformerFactory.java b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParameterMappingParametersTransformerFactory.java new file mode 100644 index 0000000..a656132 --- /dev/null +++ b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParameterMappingParametersTransformerFactory.java @@ -0,0 +1,67 @@ +/* + * Copyright 2016-2018 the original author or authors. + * + * 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.springframework.cloud.appbroker.extensions.parameters; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import reactor.core.publisher.Mono; + +import org.springframework.cloud.appbroker.deployer.BackingService; + +public class ParameterMappingParametersTransformerFactory extends + ParametersTransformerFactory { + + public ParameterMappingParametersTransformerFactory() { + super(Config.class); + } + + @Override + public ParametersTransformer create(Config config) { + return (backingType, parameters) -> transform(backingType, parameters, config.getIncludes()); + } + + private Mono transform(BackingService backingService, + Map parameters, + List include) { + if (parameters != null) { + parameters.keySet().stream() + .filter(include::contains) + .forEach(key -> backingService.addParameter(key, parameters.get(key))); + } + + return Mono.just(backingService); + } + + @SuppressWarnings("WeakerAccess") + public static class Config { + + private String include; + + public Config() { + } + + public List getIncludes() { + return Arrays.asList(include.split(",")); + } + + public void setInclude(String include) { + this.include = include; + } + } +} diff --git a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformer.java b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformer.java index ef1a25f..695a4a3 100644 --- a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformer.java +++ b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformer.java @@ -18,10 +18,11 @@ package org.springframework.cloud.appbroker.extensions.parameters; import java.util.Map; -import org.springframework.cloud.appbroker.deployer.BackingApplication; import reactor.core.publisher.Mono; @FunctionalInterface -public interface ParametersTransformer { - Mono transform(BackingApplication backingApplication, Map parameters); +public interface ParametersTransformer { + + Mono transform(T backingType, Map parameters); + } diff --git a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformerFactory.java b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformerFactory.java index d6f244c..b7454b8 100644 --- a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformerFactory.java +++ b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformerFactory.java @@ -18,7 +18,7 @@ package org.springframework.cloud.appbroker.extensions.parameters; import org.springframework.cloud.appbroker.extensions.AbstractExtensionFactory; -public abstract class ParametersTransformerFactory extends AbstractExtensionFactory { +public abstract class ParametersTransformerFactory extends AbstractExtensionFactory, C> { protected ParametersTransformerFactory() { super(); } @@ -28,7 +28,7 @@ public abstract class ParametersTransformerFactory extends AbstractExtensionF } @Override - public abstract ParametersTransformer create(C config); + public abstract ParametersTransformer create(C config); public String getName() { return getShortName(ParametersTransformerFactory.class); diff --git a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/PropertyMappingParametersTransformerFactory.java b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/PropertyMappingParametersTransformerFactory.java index 1b4e9f0..81741f9 100644 --- a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/PropertyMappingParametersTransformerFactory.java +++ b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/parameters/PropertyMappingParametersTransformerFactory.java @@ -16,24 +16,24 @@ package org.springframework.cloud.appbroker.extensions.parameters; -import org.springframework.cloud.appbroker.deployer.BackingApplication; -import reactor.core.publisher.Mono; - import java.util.Arrays; import java.util.List; import java.util.Map; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.appbroker.deployer.BackingApplication; + public class PropertyMappingParametersTransformerFactory extends - ParametersTransformerFactory { + ParametersTransformerFactory { public PropertyMappingParametersTransformerFactory() { super(Config.class); } @Override - public ParametersTransformer create(Config config) { - return (backingApplication, parameters) -> - transform(backingApplication, parameters, config.getIncludes()); + public ParametersTransformer create(Config config) { + return (backingApplication, parameters) -> transform(backingApplication, parameters, config.getIncludes()); } private Mono transform(BackingApplication backingApplication, @@ -41,14 +41,15 @@ public class PropertyMappingParametersTransformerFactory extends List include) { if (parameters != null) { parameters.keySet().stream() - .filter(include::contains) - .forEach(key -> backingApplication.addProperty(key, parameters.get(key).toString())); + .filter(include::contains) + .forEach(key -> backingApplication.addProperty(key, parameters.get(key).toString())); } return Mono.just(backingApplication); } @SuppressWarnings("WeakerAccess") public static class Config { + private String include; public Config() { diff --git a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentCreateServiceInstanceWorkflow.java b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentCreateServiceInstanceWorkflow.java index 44d1166..93f86bb 100644 --- a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentCreateServiceInstanceWorkflow.java +++ b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentCreateServiceInstanceWorkflow.java @@ -25,7 +25,8 @@ import org.springframework.cloud.appbroker.deployer.BackingAppDeploymentService; import org.springframework.cloud.appbroker.deployer.BackingServicesProvisionService; import org.springframework.cloud.appbroker.deployer.BrokeredServices; import org.springframework.cloud.appbroker.extensions.credentials.CredentialProviderService; -import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformationService; +import org.springframework.cloud.appbroker.extensions.parameters.BackingApplicationsParametersTransformationService; +import org.springframework.cloud.appbroker.extensions.parameters.BackingServicesParametersTransformationService; import org.springframework.cloud.appbroker.extensions.targets.TargetService; import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow; import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest; @@ -40,20 +41,23 @@ public class AppDeploymentCreateServiceInstanceWorkflow private final Logger log = Loggers.getLogger(AppDeploymentCreateServiceInstanceWorkflow.class); private final BackingAppDeploymentService deploymentService; - private final ParametersTransformationService parametersTransformationService; + private final BackingApplicationsParametersTransformationService appsParametersTransformationService; + private final BackingServicesParametersTransformationService servicesParametersTransformationService; private final CredentialProviderService credentialProviderService; private final TargetService targetService; private final BackingServicesProvisionService backingServicesProvisionService; public AppDeploymentCreateServiceInstanceWorkflow(BrokeredServices brokeredServices, BackingAppDeploymentService deploymentService, - ParametersTransformationService parametersTransformationService, + BackingApplicationsParametersTransformationService appsParametersTransformationService, + BackingServicesParametersTransformationService servicesParametersTransformationService, CredentialProviderService credentialProviderService, TargetService targetService, BackingServicesProvisionService backingServicesProvisionService) { super(brokeredServices); this.deploymentService = deploymentService; - this.parametersTransformationService = parametersTransformationService; + this.appsParametersTransformationService = appsParametersTransformationService; + this.servicesParametersTransformationService = servicesParametersTransformationService; this.credentialProviderService = credentialProviderService; this.targetService = targetService; this.backingServicesProvisionService = backingServicesProvisionService; @@ -63,12 +67,13 @@ public class AppDeploymentCreateServiceInstanceWorkflow public Flux create(CreateServiceInstanceRequest request) { return getBackingServicesForService(request.getServiceDefinition(), request.getPlanId()) - .flatMapMany(backingService -> targetService.addToBackingServices(backingService, getTargetForService(request.getServiceDefinition(), request.getPlanId()) , request.getServiceInstanceId())) - .flatMap(backingServicesProvisionService::createServiceInstance) + .flatMap(backingService -> targetService.addToBackingServices(backingService, getTargetForService(request.getServiceDefinition(), request.getPlanId()) , request.getServiceInstanceId())) + .flatMap(backingServices -> servicesParametersTransformationService.transformParameters(backingServices, request.getParameters())) + .flatMapMany(backingServicesProvisionService::createServiceInstance) .thenMany( getBackingApplicationsForService(request.getServiceDefinition(), request.getPlanId()) .flatMap(backingApps -> targetService.addToBackingApplications(backingApps, getTargetForService(request.getServiceDefinition(), request.getPlanId()) , request.getServiceInstanceId())) - .flatMap(backingApps -> parametersTransformationService.transformParameters(backingApps, request.getParameters())) + .flatMap(backingApps -> appsParametersTransformationService.transformParameters(backingApps, request.getParameters())) .flatMap(backingApplications -> credentialProviderService.addCredentials(backingApplications, request.getServiceInstanceId())) .flatMapMany(deploymentService::deploy) .doOnRequest(l -> log.info("Deploying applications {}", brokeredServices)) diff --git a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentUpdateServiceInstanceWorkflow.java b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentUpdateServiceInstanceWorkflow.java index 7d807f7..50e9988 100644 --- a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentUpdateServiceInstanceWorkflow.java +++ b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentUpdateServiceInstanceWorkflow.java @@ -23,7 +23,7 @@ import reactor.util.Loggers; import org.springframework.cloud.appbroker.deployer.BackingAppDeploymentService; import org.springframework.cloud.appbroker.deployer.BrokeredServices; -import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformationService; +import org.springframework.cloud.appbroker.extensions.parameters.BackingApplicationsParametersTransformationService; import org.springframework.cloud.appbroker.extensions.targets.TargetService; import org.springframework.cloud.appbroker.service.UpdateServiceInstanceWorkflow; import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceRequest; @@ -38,12 +38,12 @@ public class AppDeploymentUpdateServiceInstanceWorkflow private final Logger log = Loggers.getLogger(AppDeploymentUpdateServiceInstanceWorkflow.class); private final BackingAppDeploymentService deploymentService; - private final ParametersTransformationService parametersTransformationService; + private final BackingApplicationsParametersTransformationService parametersTransformationService; private final TargetService targetService; public AppDeploymentUpdateServiceInstanceWorkflow(BrokeredServices brokeredServices, BackingAppDeploymentService deploymentService, - ParametersTransformationService parametersTransformationService, + BackingApplicationsParametersTransformationService parametersTransformationService, TargetService targetService) { super(brokeredServices); this.deploymentService = deploymentService; diff --git a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformationServiceTest.java b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/BackingApplicationsParametersTransformationServiceTest.java similarity index 74% rename from spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformationServiceTest.java rename to spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/BackingApplicationsParametersTransformationServiceTest.java index 052d63c..6717f41 100644 --- a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/ParametersTransformationServiceTest.java +++ b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/BackingApplicationsParametersTransformationServiceTest.java @@ -34,14 +34,15 @@ import org.springframework.cloud.servicebroker.exception.ServiceBrokerException; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -class ParametersTransformationServiceTest { +class BackingApplicationsParametersTransformationServiceTest { @Test void transformParametersWithNoBackingApps() { - ParametersTransformationService service = new ParametersTransformationService(Collections.emptyList()); + BackingApplicationsParametersTransformationService service = + new BackingApplicationsParametersTransformationService(Collections.emptyList()); BackingApplications backingApplications = BackingApplications.builder() - .build(); + .build(); StepVerifier .create(service.transformParameters(backingApplications, new HashMap<>())) @@ -51,9 +52,11 @@ class ParametersTransformationServiceTest { @Test void transformParametersWithNoTransformers() { - ParametersTransformationService service = new ParametersTransformationService(Collections.emptyList()); + BackingApplicationsParametersTransformationService service = + new BackingApplicationsParametersTransformationService(Collections.emptyList()); - BackingApplications backingApplications = BackingApplications.builder() + BackingApplications backingApplications = BackingApplications + .builder() .backingApplication(BackingApplication.builder().build()) .build(); @@ -65,14 +68,17 @@ class ParametersTransformationServiceTest { @Test void transformParametersWithUnknownTransformer() { - ParametersTransformationService service = new ParametersTransformationService(Collections.emptyList()); + BackingApplicationsParametersTransformationService service = + new BackingApplicationsParametersTransformationService(Collections.emptyList()); - BackingApplications backingApplications = BackingApplications.builder() - .backingApplication(BackingApplication.builder() + BackingApplications backingApplications = BackingApplications + .builder() + .backingApplication(BackingApplication + .builder() .name("misconfigured-app") .parameterTransformers(ParametersTransformerSpec.builder() - .name("unknown-transformer") - .build()) + .name("unknown-transformer") + .build()) .build()) .build(); @@ -91,32 +97,37 @@ class ParametersTransformationServiceTest { parameters.put("key2", "value2"); BackingApplication app1 = BackingApplication.builder() - .name("app1") - .parameterTransformers(ParametersTransformerSpec.builder() - .name("transformer1") - .build()) - .build(); - BackingApplication app2 = BackingApplication.builder() + .name("app1") + .parameterTransformers(ParametersTransformerSpec + .builder() + .name("transformer1") + .build()) + .build(); + BackingApplication app2 = BackingApplication + .builder() .name("app2") - .parameterTransformers(ParametersTransformerSpec.builder() + .parameterTransformers(ParametersTransformerSpec + .builder() .name("transformer1") .arg("arg1", "value1") .arg("arg2", 5) .build(), - ParametersTransformerSpec.builder() + ParametersTransformerSpec + .builder() .name("transformer2") .build()) .build(); BackingApplications backingApplications = BackingApplications.builder() - .backingApplication(app1) - .backingApplication(app2) - .build(); + .backingApplication(app1) + .backingApplication(app2) + .build(); TestFactory factory1 = new TestFactory("transformer1"); TestFactory factory2 = new TestFactory("transformer2"); - ParametersTransformationService service = new ParametersTransformationService( - Arrays.asList(factory1, factory2)); + BackingApplicationsParametersTransformationService service = + new BackingApplicationsParametersTransformationService( + Arrays.asList(factory1, factory2)); StepVerifier .create(service.transformParameters(backingApplications, parameters)) @@ -129,9 +140,9 @@ class ParametersTransformationServiceTest { app2ExpectedTransformedEnvironment.put("1", "transformer2"); assertAll("unexpected transformation results", - () -> assertThat(transformedBackingApplications.size()).isEqualTo(backingApplications.size()), - () -> assertThat(transformedBackingApplications.get(0).getEnvironment()).isEqualTo(app1ExpectedTransformedEnvironment), - () -> assertThat(transformedBackingApplications.get(1).getEnvironment()).isEqualTo(app2ExpectedTransformedEnvironment) + () -> assertThat(transformedBackingApplications.size()).isEqualTo(backingApplications.size()), + () -> assertThat(transformedBackingApplications.get(0).getEnvironment()).isEqualTo(app1ExpectedTransformedEnvironment), + () -> assertThat(transformedBackingApplications.get(1).getEnvironment()).isEqualTo(app2ExpectedTransformedEnvironment) ); return true; @@ -145,7 +156,8 @@ class ParametersTransformationServiceTest { assertThat(factory2.getActualConfig()).isEqualTo(new Config(null, null)); } - public static class TestFactory extends ParametersTransformerFactory { + public static class TestFactory extends ParametersTransformerFactory { + private final String name; private Map actualParameters; @@ -162,7 +174,7 @@ class ParametersTransformationServiceTest { } @Override - public ParametersTransformer create(Config config) { + public ParametersTransformer create(Config config) { this.actualConfig = config; return this::doTransform; } @@ -185,6 +197,7 @@ class ParametersTransformationServiceTest { @SuppressWarnings("unused") public static class Config { + private String arg1; private Integer arg2; diff --git a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/BackingServicesParametersTransformationServiceTest.java b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/BackingServicesParametersTransformationServiceTest.java new file mode 100644 index 0000000..2a0df1d --- /dev/null +++ b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/BackingServicesParametersTransformationServiceTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2016-2018 the original author or authors. + * + * 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.springframework.cloud.appbroker.extensions.parameters; + +import java.util.Collections; +import java.util.HashMap; + +import org.junit.jupiter.api.Test; +import reactor.test.StepVerifier; + +import org.springframework.cloud.appbroker.deployer.BackingService; +import org.springframework.cloud.appbroker.deployer.BackingServices; +import org.springframework.cloud.appbroker.deployer.ParametersTransformerSpec; +import org.springframework.cloud.servicebroker.exception.ServiceBrokerException; + +import static org.assertj.core.api.Assertions.assertThat; + +class BackingServicesParametersTransformationServiceTest { + + @Test + void transformParametersWithNoBackingServices() { + BackingServicesParametersTransformationService service = + new BackingServicesParametersTransformationService(Collections.emptyList()); + + BackingServices backingServices = BackingServices.builder() + .build(); + + StepVerifier + .create(service.transformParameters(backingServices, new HashMap<>())) + .expectNext(backingServices) + .verifyComplete(); + } + + @Test + void transformParametersWithNoTransformers() { + BackingServicesParametersTransformationService service = + new BackingServicesParametersTransformationService(Collections.emptyList()); + + BackingServices backingServices = BackingServices + .builder() + .backingService(BackingService.builder().build()) + .build(); + + StepVerifier + .create(service.transformParameters(backingServices, new HashMap<>())) + .expectNext(backingServices) + .verifyComplete(); + } + + @Test + void transformParametersWithUnknownTransformer() { + BackingServicesParametersTransformationService service = + new BackingServicesParametersTransformationService(Collections.emptyList()); + + BackingServices backingServices = BackingServices + .builder() + .backingService(BackingService.builder() + .name("misconfigured-service") + .parameterTransformers(ParametersTransformerSpec + .builder() + .name("unknown-transformer") + .build()) + .build()) + .build(); + + StepVerifier + .create(service.transformParameters(backingServices, new HashMap<>())) + .expectErrorSatisfies(e -> assertThat(e) + .isInstanceOf(ServiceBrokerException.class) + .hasMessageContaining("unknown-transformer")) + .verify(); + } +} \ No newline at end of file diff --git a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/EnvironmentMappingParametersTransformerFactoryTest.java b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/EnvironmentMappingParametersTransformerFactoryTest.java index 747e176..965b371 100644 --- a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/EnvironmentMappingParametersTransformerFactoryTest.java +++ b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/EnvironmentMappingParametersTransformerFactoryTest.java @@ -16,19 +16,20 @@ package org.springframework.cloud.appbroker.extensions.parameters; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.cloud.appbroker.deployer.BackingApplication; -import reactor.test.StepVerifier; - import java.util.HashMap; import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import reactor.test.StepVerifier; + +import org.springframework.cloud.appbroker.deployer.BackingApplication; + import static org.assertj.core.api.Assertions.assertThat; class EnvironmentMappingParametersTransformerFactoryTest { - private ParametersTransformer transformer; + private ParametersTransformer transformer; @BeforeEach void setUp() { diff --git a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/ParameterMappingParametersTransformerFactoryTest.java b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/ParameterMappingParametersTransformerFactoryTest.java new file mode 100644 index 0000000..09f08b6 --- /dev/null +++ b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/ParameterMappingParametersTransformerFactoryTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2016-2018 the original author or authors. + * + * 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.springframework.cloud.appbroker.extensions.parameters; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import reactor.test.StepVerifier; + +import org.springframework.cloud.appbroker.deployer.BackingService; + +import static org.assertj.core.api.Assertions.assertThat; + +class ParameterMappingParametersTransformerFactoryTest { + + private ParametersTransformer transformer; + + @BeforeEach + void setUp() { + transformer = new ParameterMappingParametersTransformerFactory() + .createWithConfig(config -> + config.setInclude("parameter1,parameter2")); + } + + @Test + void parametersOverrideApplicationEnvironment() { + Map inputParameters = new HashMap<>(); + inputParameters.put("parameter1", "value1"); + inputParameters.put("parameter2", "value2"); + inputParameters.put("parameter3", "value3"); + + + Map expectedParameters = new HashMap<>(); + expectedParameters.put("parameter1", "value1"); + expectedParameters.put("parameter2", "value2"); + + BackingService backingService = + BackingService.builder() + .parameters(expectedParameters) + .build(); + + StepVerifier + .create(transformer.transform(backingService, inputParameters)) + .expectNext(backingService) + .verifyComplete(); + + assertThat(backingService.getParameters()).containsEntry("parameter1", "value1"); + assertThat(backingService.getParameters()).containsEntry("parameter2", "value2"); + assertThat(backingService.getParameters()).doesNotContainEntry("parameter3", "value3"); + } + +} \ No newline at end of file diff --git a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/PropertyMappingParametersTransformerFactoryTest.java b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/PropertyMappingParametersTransformerFactoryTest.java index 6c74f65..a724805 100644 --- a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/PropertyMappingParametersTransformerFactoryTest.java +++ b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/extensions/parameters/PropertyMappingParametersTransformerFactoryTest.java @@ -27,7 +27,7 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; class PropertyMappingParametersTransformerFactoryTest { - private ParametersTransformer transformer; + private ParametersTransformer transformer; @BeforeEach void setUp() { diff --git a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentCreateServiceInstanceWorkflowTest.java b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentCreateServiceInstanceWorkflowTest.java index 863ed1c..3c91d2e 100644 --- a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentCreateServiceInstanceWorkflowTest.java +++ b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentCreateServiceInstanceWorkflowTest.java @@ -38,7 +38,8 @@ import org.springframework.cloud.appbroker.deployer.BrokeredService; import org.springframework.cloud.appbroker.deployer.BrokeredServices; import org.springframework.cloud.appbroker.deployer.TargetSpec; import org.springframework.cloud.appbroker.extensions.credentials.CredentialProviderService; -import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformationService; +import org.springframework.cloud.appbroker.extensions.parameters.BackingApplicationsParametersTransformationService; +import org.springframework.cloud.appbroker.extensions.parameters.BackingServicesParametersTransformationService; import org.springframework.cloud.appbroker.extensions.targets.TargetService; import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow; import org.springframework.cloud.servicebroker.model.catalog.Plan; @@ -58,7 +59,10 @@ class AppDeploymentCreateServiceInstanceWorkflowTest { private BackingAppDeploymentService backingAppDeploymentService; @Mock - private ParametersTransformationService parametersTransformationService; + private BackingApplicationsParametersTransformationService backingApplicationsParametersTransformationService; + + @Mock + private BackingServicesParametersTransformationService backingServicesParametersTransformationService; @Mock private CredentialProviderService credentialProviderService; @@ -117,7 +121,8 @@ class AppDeploymentCreateServiceInstanceWorkflowTest { createServiceInstanceWorkflow = new AppDeploymentCreateServiceInstanceWorkflow( brokeredServices, backingAppDeploymentService, - parametersTransformationService, + backingApplicationsParametersTransformationService, + backingServicesParametersTransformationService, credentialProviderService, targetService, backingServicesProvisionService); @@ -155,7 +160,8 @@ class AppDeploymentCreateServiceInstanceWorkflowTest { .expectNext() .verifyComplete(); - verify(parametersTransformationService).transformParameters(backingApps, singletonMap("ENV_VAR_1", "value from parameters")); + verify(backingApplicationsParametersTransformationService) + .transformParameters(backingApps, singletonMap("ENV_VAR_1", "value from parameters")); verifyNoMoreInteractionsWithServices(); } @@ -194,8 +200,10 @@ class AppDeploymentCreateServiceInstanceWorkflowTest { private void setupMocks(CreateServiceInstanceRequest request) { given(this.backingAppDeploymentService.deploy(eq(backingApps))) .willReturn(Flux.just("app1", "app2")); - given(this.parametersTransformationService.transformParameters(eq(backingApps), eq(request.getParameters()))) + given(this.backingApplicationsParametersTransformationService.transformParameters(eq(backingApps), eq(request.getParameters()))) .willReturn(Mono.just(backingApps)); + given(this.backingServicesParametersTransformationService.transformParameters(eq(backingServices), eq(request.getParameters()))) + .willReturn(Mono.just(backingServices)); given(this.credentialProviderService.addCredentials(eq(backingApps), eq(request.getServiceInstanceId()))) .willReturn(Mono.just(backingApps)); given(this.targetService.addToBackingApplications(eq(backingApps), eq(targetSpec), eq(request.getServiceInstanceId()))) @@ -208,7 +216,8 @@ class AppDeploymentCreateServiceInstanceWorkflowTest { private void verifyNoMoreInteractionsWithServices() { verifyNoMoreInteractions(this.backingAppDeploymentService); - verifyNoMoreInteractions(this.parametersTransformationService); + verifyNoMoreInteractions(this.backingApplicationsParametersTransformationService); + verifyNoMoreInteractions(this.backingServicesParametersTransformationService); verifyNoMoreInteractions(this.credentialProviderService); verifyNoMoreInteractions(this.targetService); verifyNoMoreInteractions(this.backingServicesProvisionService); diff --git a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentUpdateServiceInstanceWorkflowTest.java b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentUpdateServiceInstanceWorkflowTest.java index 8d302fe..1c99dae 100644 --- a/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentUpdateServiceInstanceWorkflowTest.java +++ b/spring-cloud-app-broker-core/src/test/java/org/springframework/cloud/appbroker/workflow/instance/AppDeploymentUpdateServiceInstanceWorkflowTest.java @@ -34,7 +34,7 @@ import org.springframework.cloud.appbroker.deployer.BackingApplications; import org.springframework.cloud.appbroker.deployer.BrokeredService; import org.springframework.cloud.appbroker.deployer.BrokeredServices; import org.springframework.cloud.appbroker.deployer.TargetSpec; -import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformationService; +import org.springframework.cloud.appbroker.extensions.parameters.BackingApplicationsParametersTransformationService; import org.springframework.cloud.appbroker.extensions.targets.TargetService; import org.springframework.cloud.servicebroker.model.catalog.Plan; import org.springframework.cloud.servicebroker.model.catalog.ServiceDefinition; @@ -52,7 +52,7 @@ class AppDeploymentUpdateServiceInstanceWorkflowTest { private BackingAppDeploymentService backingAppDeploymentService; @Mock - private ParametersTransformationService parametersTransformationService; + private BackingApplicationsParametersTransformationService backingApplicationsParametersTransformationService; @Mock private TargetService targetService; @@ -88,7 +88,7 @@ class AppDeploymentUpdateServiceInstanceWorkflowTest { updateServiceInstanceWorkflow = new AppDeploymentUpdateServiceInstanceWorkflow(brokeredServices, backingAppDeploymentService, - parametersTransformationService, + backingApplicationsParametersTransformationService, targetService); } @@ -101,7 +101,7 @@ class AppDeploymentUpdateServiceInstanceWorkflowTest { .willReturn(Flux.just("app1", "app2")); given(this.targetService.addToBackingApplications(eq(backingApps), eq(targetSpec), eq("service-instance-id"))) .willReturn(Mono.just(backingApps)); - given(this.parametersTransformationService.transformParameters(eq(backingApps), eq(request.getParameters()))) + given(this.backingApplicationsParametersTransformationService.transformParameters(eq(backingApps), eq(request.getParameters()))) .willReturn(Mono.just(backingApps)); StepVerifier @@ -111,7 +111,7 @@ class AppDeploymentUpdateServiceInstanceWorkflowTest { .verifyComplete(); verifyNoMoreInteractions(this.backingAppDeploymentService); - verifyNoMoreInteractions(this.parametersTransformationService); + verifyNoMoreInteractions(this.backingApplicationsParametersTransformationService); verifyNoMoreInteractions(this.targetService); } @@ -122,7 +122,7 @@ class AppDeploymentUpdateServiceInstanceWorkflowTest { given(this.backingAppDeploymentService.deploy(eq(backingApps))) .willReturn(Flux.just("app1", "app2")); - given(this.parametersTransformationService.transformParameters(eq(backingApps), eq(request.getParameters()))) + given(this.backingApplicationsParametersTransformationService.transformParameters(eq(backingApps), eq(request.getParameters()))) .willReturn(Mono.just(backingApps)); given(this.targetService.addToBackingApplications(eq(backingApps), eq(targetSpec), eq("service-instance-id"))) .willReturn(Mono.just(backingApps)); @@ -134,7 +134,7 @@ class AppDeploymentUpdateServiceInstanceWorkflowTest { .verifyComplete(); verifyNoMoreInteractions(this.backingAppDeploymentService); - verifyNoMoreInteractions(this.parametersTransformationService); + verifyNoMoreInteractions(this.backingApplicationsParametersTransformationService); verifyNoMoreInteractions(this.targetService); } @@ -145,7 +145,7 @@ class AppDeploymentUpdateServiceInstanceWorkflowTest { .verifyComplete(); verifyNoMoreInteractions(this.backingAppDeploymentService); - verifyNoMoreInteractions(this.parametersTransformationService); + verifyNoMoreInteractions(this.backingApplicationsParametersTransformationService); verifyNoMoreInteractions(this.targetService); } diff --git a/spring-cloud-app-broker-deployer/src/main/java/org/springframework/cloud/appbroker/deployer/CreateServiceInstanceRequest.java b/spring-cloud-app-broker-deployer/src/main/java/org/springframework/cloud/appbroker/deployer/CreateServiceInstanceRequest.java index f9f27cf..93d9a97 100644 --- a/spring-cloud-app-broker-deployer/src/main/java/org/springframework/cloud/appbroker/deployer/CreateServiceInstanceRequest.java +++ b/spring-cloud-app-broker-deployer/src/main/java/org/springframework/cloud/appbroker/deployer/CreateServiceInstanceRequest.java @@ -24,13 +24,13 @@ public class CreateServiceInstanceRequest { private final String serviceInstanceName; private final String name; private final String plan; - private final Map parameters; + private final Map parameters; private final Map properties; CreateServiceInstanceRequest(String serviceInstanceName, String name, String plan, - Map parameters, + Map parameters, Map properties) { this.serviceInstanceName = serviceInstanceName; this.name = name; @@ -57,7 +57,7 @@ public class CreateServiceInstanceRequest { return plan; } - public Map getParameters() { + public Map getParameters() { return parameters; } @@ -70,7 +70,7 @@ public class CreateServiceInstanceRequest { private String serviceInstanceName; private String name; private String plan; - private final Map parameters = new HashMap<>(); + private final Map parameters = new HashMap<>(); private final Map properties = new HashMap<>(); CreateServiceInstanceRequestBuilder() { @@ -96,7 +96,7 @@ public class CreateServiceInstanceRequest { return this; } - public CreateServiceInstanceRequestBuilder parameters(Map parameters) { + public CreateServiceInstanceRequestBuilder parameters(Map parameters) { if (parameters == null) { return this; } diff --git a/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithCustomCreationParametersComponentTest.java b/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithCustomCreationParametersComponentTest.java index 980103a..cb6c458 100644 --- a/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithCustomCreationParametersComponentTest.java +++ b/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithCustomCreationParametersComponentTest.java @@ -16,28 +16,28 @@ package org.springframework.cloud.appbroker.sample; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.appbroker.deployer.BackingApplication; +import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformer; import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformerFactory; import org.springframework.cloud.appbroker.sample.fixtures.CloudControllerStubFixture; import org.springframework.cloud.appbroker.sample.fixtures.OpenServiceBrokerApiFixture; -import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformer; import org.springframework.cloud.servicebroker.model.instance.OperationState; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; -import reactor.core.publisher.Mono; - import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath; import static io.restassured.RestAssured.given; @@ -97,17 +97,17 @@ class CreateInstanceWithCustomCreationParametersComponentTest extends WiremockCo @Configuration static class CustomConfig { @Bean - public ParametersTransformerFactory parametersTransformer() { + public ParametersTransformerFactory parametersTransformer() { return new CustomMappingParametersTransformerFactory(); } - public class CustomMappingParametersTransformerFactory extends ParametersTransformerFactory { + public class CustomMappingParametersTransformerFactory extends ParametersTransformerFactory { CustomMappingParametersTransformerFactory() { super(); } @Override - public ParametersTransformer create(Object config) { + public ParametersTransformer create(Object config) { return this::transform; } diff --git a/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithServicesParametersComponentTest.java b/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithServicesParametersComponentTest.java new file mode 100644 index 0000000..8eb710e --- /dev/null +++ b/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithServicesParametersComponentTest.java @@ -0,0 +1,107 @@ +/* + * Copyright 2016-2018. the original author or authors. + * + * 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.springframework.cloud.appbroker.sample; + +import java.util.Collections; +import java.util.HashMap; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.appbroker.sample.fixtures.CloudControllerStubFixture; +import org.springframework.cloud.appbroker.sample.fixtures.OpenServiceBrokerApiFixture; +import org.springframework.cloud.servicebroker.model.instance.OperationState; +import org.springframework.http.HttpStatus; +import org.springframework.test.context.TestPropertySource; + +import static io.restassured.RestAssured.given; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.springframework.cloud.appbroker.sample.CreateInstanceWithServicesParametersComponentTest.APP_NAME; +import static org.springframework.cloud.appbroker.sample.CreateInstanceWithServicesParametersComponentTest.SERVICE_1_NAME; +import static org.springframework.cloud.appbroker.sample.CreateInstanceWithServicesParametersComponentTest.SERVICE_INSTANCE_1_NAME; + +@TestPropertySource(properties = { + "spring.cloud.appbroker.services[0].service-name=example", + "spring.cloud.appbroker.services[0].plan-name=standard", + "spring.cloud.appbroker.services[0].apps[0].path=classpath:demo.jar", + "spring.cloud.appbroker.services[0].apps[0].name=" + APP_NAME, + "spring.cloud.appbroker.services[0].apps[0].services[0].service-instance-name=" + SERVICE_INSTANCE_1_NAME, + "spring.cloud.appbroker.services[0].services[0].service-instance-name=" + SERVICE_INSTANCE_1_NAME, + "spring.cloud.appbroker.services[0].services[0].name=" + SERVICE_1_NAME, + "spring.cloud.appbroker.services[0].services[0].plan=standard", + "spring.cloud.appbroker.services[0].services[0].parameters-transformers[0].name=ParameterMapping", + "spring.cloud.appbroker.services[0].services[0].parameters-transformers[0].args.include=paramA,paramC" +}) +class CreateInstanceWithServicesParametersComponentTest extends WiremockComponentTest { + + static final String APP_NAME = "app-services-param"; + + static final String SERVICE_INSTANCE_1_NAME = "my-db-service"; + static final String SERVICE_1_NAME = "db-service"; + + @Autowired + private OpenServiceBrokerApiFixture brokerFixture; + + @Autowired + private CloudControllerStubFixture cloudControllerFixture; + + @Test + void pushAppWithBackingServicesParameters() { + cloudControllerFixture.stubAppDoesNotExist(APP_NAME); + cloudControllerFixture.stubPushApp(APP_NAME); + + // given that service instances does not exist + cloudControllerFixture.stubServiceInstanceDoesNotExists(SERVICE_INSTANCE_1_NAME); + + // and the services are available in the marketplace + cloudControllerFixture.stubServiceExists(SERVICE_1_NAME); + + // will create with filtered parameters and bind the service instance + HashMap expectedCreationParameters = new HashMap<>(); + expectedCreationParameters.put("paramA", "valueA"); + expectedCreationParameters.put("paramC", Collections.singletonMap("paramC1", "valueC1")); + + cloudControllerFixture.stubCreateServiceInstanceWithParameters(SERVICE_INSTANCE_1_NAME, expectedCreationParameters); + cloudControllerFixture.stubCreateServiceBinding(APP_NAME, SERVICE_INSTANCE_1_NAME); + cloudControllerFixture.stubServiceInstanceExists(SERVICE_INSTANCE_1_NAME); + + // when a service instance is created with parameters + HashMap creationParameters = new HashMap<>(); + creationParameters.put("paramA", "valueA"); + creationParameters.put("paramB", "valueB"); + creationParameters.put("paramC", Collections.singletonMap("paramC1", "valueC1")); + + given(brokerFixture.serviceInstanceRequest(creationParameters)) + .when() + .put(brokerFixture.createServiceInstanceUrl(), "instance-id") + .then() + .statusCode(HttpStatus.ACCEPTED.value()); + + // when the "last_operation" API is polled + given(brokerFixture.serviceInstanceRequest()) + .when() + .get(brokerFixture.getLastInstanceOperationUrl(), "instance-id") + .then() + .statusCode(HttpStatus.OK.value()) + .body("state", is(equalTo(OperationState.IN_PROGRESS.toString()))); + + String state = brokerFixture.waitForAsyncOperationComplete("instance-id"); + assertThat(state).isEqualTo(OperationState.SUCCEEDED.toString()); + } +} \ No newline at end of file diff --git a/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/fixtures/CloudControllerStubFixture.java b/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/fixtures/CloudControllerStubFixture.java index 9cb3886..b176bf9 100644 --- a/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/fixtures/CloudControllerStubFixture.java +++ b/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/fixtures/CloudControllerStubFixture.java @@ -16,8 +16,11 @@ package org.springframework.cloud.appbroker.sample.fixtures; +import java.util.Map; + import com.github.tomakehurst.wiremock.client.MappingBuilder; import com.github.tomakehurst.wiremock.matching.ContentPattern; +import org.json.JSONObject; import org.springframework.boot.test.context.TestComponent; @@ -311,12 +314,20 @@ public class CloudControllerStubFixture extends WiremockStubFixture { .willReturn(ok() .withBody(cc("list-service-plans")))); } + public void stubCreateServiceInstance(String serviceInstanceName) { stubFor(post(urlEqualTo("/v2/service_instances?accepts_incomplete=true")) .withRequestBody(matchingJsonPath("$.[?(@.name == '" + serviceInstanceName + "')]")) .willReturn(ok())); } + public void stubCreateServiceInstanceWithParameters(String serviceInstanceName, Map params) { + stubFor(post(urlEqualTo("/v2/service_instances?accepts_incomplete=true")) + .withRequestBody(matchingJsonPath("$.[?(@.name == '" + serviceInstanceName + "')]")) + .withRequestBody(matchingJsonPath("$.[?(@.parameters == " + new JSONObject(params) + ")]")) + .willReturn(ok())); + } + public void stubCreateServiceBinding(String appName, String serviceInstanceName) { String serviceInstanceGuid = serviceInstanceName + "-GUID"; String serviceBindingGuid = appGuid(appName) + "-" + serviceInstanceGuid; diff --git a/spring-cloud-app-broker-sample/src/test/resources/responses/cloudcontroller/get-info.json b/spring-cloud-app-broker-sample/src/test/resources/responses/cloudcontroller/get-info.json index a5dee13..b708f94 100644 --- a/spring-cloud-app-broker-sample/src/test/resources/responses/cloudcontroller/get-info.json +++ b/spring-cloud-app-broker-sample/src/test/resources/responses/cloudcontroller/get-info.json @@ -4,5 +4,8 @@ "support": "https://support.pivotal.io", "version": 0, "description": "", - "authorization_endpoint": "http://localhost" + "authorization_endpoint": "http://localhost", + "min_cli_version": "6.23.0", + "min_recommended_cli_version": "6.23.0", + "api_version": "2.98.0" }