├── .gitignore ├── README.adoc ├── build.gradle ├── ci ├── config-concourse-master.yml ├── pipeline.yml ├── scripts │ ├── run-tests.sh │ └── set-pipelines.sh └── tasks │ └── run-tests.yml ├── creating-workflows ├── build.gradle └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── cloud │ │ │ └── appbroker │ │ │ └── samples │ │ │ └── creatingworkflows │ │ │ ├── AppBrokerApplication.java │ │ │ ├── AppBrokerApplicationConfiguration.java │ │ │ ├── ServiceInstanceParametersValidatorWorkflow.java │ │ │ ├── ServiceInstanceServiceOrder.java │ │ │ └── services │ │ │ ├── NoOpCreateServiceInstanceWorkflow.java │ │ │ ├── NoOpDeleteServiceInstanceWorkflow.java │ │ │ ├── NoOpServiceInstanceBindingService.java │ │ │ └── NoOpUpdateServiceInstanceWorkflow.java │ └── resources │ │ ├── application.yml │ │ └── demo.jar │ └── test │ └── java │ └── org │ └── springframework │ └── cloud │ └── appbroker │ └── samples │ └── creatingworkflows │ └── AppBrokerApplicationTests.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── parameter-transformer ├── build.gradle └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── cloud │ │ │ └── appbroker │ │ │ └── samples │ │ │ └── parametertransformer │ │ │ ├── AppBrokerApplication.java │ │ │ ├── AppBrokerApplicationConfiguration.java │ │ │ ├── ParameterTransformerConfiguration.java │ │ │ ├── RequestTimeoutParameterTransformer.java │ │ │ └── services │ │ │ ├── NoOpCreateServiceInstanceWorkflow.java │ │ │ ├── NoOpDeleteServiceInstanceWorkflow.java │ │ │ ├── NoOpServiceInstanceBindingService.java │ │ │ └── NoOpUpdateServiceInstanceWorkflow.java │ └── resources │ │ ├── application.yml │ │ └── demo.jar │ └── test │ └── java │ └── org │ └── springframework │ └── cloud │ └── appbroker │ └── samples │ └── parametertransformer │ ├── AppBrokerApplicationTests.java │ └── RequestTimeoutParameterTransformerTest.java ├── settings.gradle ├── src ├── checkstyle │ ├── checkstyle-nohttp.xml │ ├── checkstyle-suppressions.xml │ ├── checkstyle.xml │ └── license.header ├── idea │ └── spring.xml └── pmd │ ├── pmdRuleSet.xml │ └── pmdTestRuleSet.xml ├── state-repository ├── build.gradle └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── cloud │ │ │ └── appbroker │ │ │ └── samples │ │ │ └── staterepository │ │ │ ├── AppBrokerApplication.java │ │ │ ├── AppBrokerApplicationConfiguration.java │ │ │ ├── data │ │ │ ├── DataConfiguration.java │ │ │ ├── DefaultServiceInstanceBindingStateRepository.java │ │ │ ├── DefaultServiceInstanceStateRepository.java │ │ │ ├── ServiceInstance.java │ │ │ ├── ServiceInstanceBinding.java │ │ │ ├── ServiceInstanceBindingRepository.java │ │ │ └── ServiceInstanceRepository.java │ │ │ └── services │ │ │ ├── NoOpCreateServiceInstanceWorkflow.java │ │ │ ├── NoOpDeleteServiceInstanceWorkflow.java │ │ │ ├── NoOpServiceInstanceBindingService.java │ │ │ └── NoOpUpdateServiceInstanceWorkflow.java │ └── resources │ │ ├── application.yml │ │ ├── data.sql │ │ ├── demo.jar │ │ └── schema.sql │ └── test │ └── java │ └── org │ └── springframework │ └── cloud │ └── appbroker │ └── samples │ └── staterepository │ ├── AppBrokerApplicationTests.java │ └── data │ └── ServiceInstanceStateRepositoryTest.java └── target-service ├── build.gradle └── src ├── main ├── java │ └── org │ │ └── springframework │ │ └── cloud │ │ └── appbroker │ │ └── samples │ │ └── targetservice │ │ ├── AppBrokerApplication.java │ │ ├── AppBrokerApplicationConfiguration.java │ │ ├── CustomSpaceService.java │ │ ├── CustomSpaceTarget.java │ │ ├── TargetServiceConfiguration.java │ │ └── services │ │ ├── NoOpCreateServiceInstanceWorkflow.java │ │ ├── NoOpDeleteServiceInstanceWorkflow.java │ │ ├── NoOpServiceInstanceBindingService.java │ │ └── NoOpUpdateServiceInstanceWorkflow.java └── resources │ ├── application.yml │ └── demo.jar └── test └── java └── org └── springframework └── cloud └── appbroker └── samples └── targetservice └── AppBrokerApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/** 6 | !**/src/test/** 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = Spring Cloud App Broker Samples 2 | 3 | 4 | == Parameters transformers 5 | 6 | One of the very first things every broker will need to do is handle user input parameters. 7 | For that, `spring-cloud-app-broker` comes with two `parameter-transformer` out of the box and a mechanism to implement your own: 8 | 9 | [source, yml, indent=0] 10 | ---- 11 | parameters-transformers: 12 | - name: EnvironmentMapping 13 | args: 14 | include: lang 15 | - name: PropertyMapping 16 | args: 17 | include: count,upgrade,memory 18 | - name: RequestTimeoutParameterTransformer 19 | ---- 20 | 21 | The first transformer is `PropertyMapping` where we can specify some deployment properties. We included three properties: 22 | `count` to allow our backing app to be scaled 23 | `upgrade` to upgrade the backing app to a new version 24 | `memory` to modify the default memory used by the backing app 25 | 26 | A full list of supported properties can be found in: 27 | https://docs.spring.io/spring-cloud-app-broker/docs/current/reference/html5/#_properties_configuration 28 | 29 | The second transformer is `EnvironmentMapping`, where we can list which properties we want to be passed from parameters to environment variables in the backing app. 30 | 31 | It is typical that we want to have some business logic on the way we handle the parameters, for that, we can create our own `ParameterTransformer`. 32 | On this example, we created a custom `RequestTimeoutParameterTransformer` where we are going to map a parameter from `request-timeout-ms` to an environment variable `my-app.httpclient.connect-timeout`. 33 | 34 | To achieve that we have to create our class: 35 | 36 | [source, java, indent=0] 37 | ---- 38 | public class RequestTimeoutParameterTransformer extends ParametersTransformerFactory { 39 | 40 | @Override 41 | public ParametersTransformer create(Object config) { 42 | return this::transform; 43 | } 44 | 45 | private Mono transform( 46 | BackingApplication backingApplication, Map parameters) { 47 | if (parameters.containsKey("request-timeout-ms")) { 48 | backingApplication 49 | .addEnvironment("my-app.httpclient.connect-timeout", parameters.get("request-timeout-ms")); 50 | parameters.remove("request-timeout-ms"); 51 | } 52 | return Mono.just(backingApplication); 53 | } 54 | 55 | } 56 | ---- 57 | 58 | And then register it as a bean: 59 | [source, java, indent=0] 60 | ---- 61 | @Bean 62 | public ParametersTransformerFactory requestTimeoutParameterTransformerFactory() { 63 | return new RequestTimeoutParameterTransformer(); 64 | } 65 | ---- 66 | 67 | == Creating workflows 68 | 69 | With the default configuration, `spring-cloud-app-broker` handles the implementation of the basic operations a broker can handle: create, update, delete, bind, and unbind. 70 | However, there are going to be times where we want to perform actions before or after some of those operations. 71 | To help with that, `spring-cloud-app-broker` provides `https://docs.spring.io/spring-cloud-app-broker/docs/current/reference/html5/#_creating_a_service_instance[Workflows]`. 72 | Every Workflow can have an `@Order` associated with it so that we can decide when to execute it. 73 | 74 | A good practice is to keep the order in the same class so that we can easily read the order of all our workflows. 75 | 76 | We created one for Service Instances: 77 | 78 | [source,java,indent=0] 79 | ---- 80 | public class ServiceInstanceServiceOrder { 81 | private static final int CREATE_SI_WORKFLOW_ORDER = 0; 82 | 83 | public static final int VALIDATE_CREATE_PARAMETERS = CREATE_SI_WORKFLOW_ORDER - 400; 84 | } 85 | ---- 86 | 87 | An example of Workflow that runs before creating a Service Instance is validating the parameters: 88 | 89 | [source,java,indent=0] 90 | ---- 91 | @Component 92 | @Order(VALIDATE_CREATE_PARAMETERS) 93 | public class ServiceInstanceParametersValidatorWorkflow implements CreateServiceInstanceWorkflow { 94 | 95 | private static final String SERVICE_NAME = "example"; 96 | 97 | private static final List SUPPORTED_PARAMETERS = Arrays.asList("count", "memory", "routes"); // TODO java 14 98 | 99 | @Override 100 | public Mono accept(CreateServiceInstanceRequest request) { 101 | return Mono.just(SERVICE_NAME.equals(request.getServiceDefinition().getName())); 102 | } 103 | 104 | @Override 105 | public Mono buildResponse( 106 | CreateServiceInstanceRequest request, 107 | CreateServiceInstanceResponseBuilder responseBuilder) { 108 | 109 | for (String parameter : request.getParameters().keySet()) { 110 | if (!SUPPORTED_PARAMETERS.contains(parameter)) { 111 | String errorMessage = String.format("Invalid parameter {%s}", parameter); 112 | return Mono.error(new ServiceBrokerInvalidParametersException(errorMessage)); 113 | } 114 | } 115 | 116 | return Mono.just(responseBuilder); 117 | } 118 | 119 | } 120 | ---- 121 | 122 | == Service Instance state repositories 123 | 124 | Service brokers are not stateless. 125 | While creating, updating, deleting or binding and unbinding new service instances, there is a time-gap while that operation is in progress. 126 | By default, `spring-cloud-app-broker` provides some `InMemory` implementations of the `ServiceInstanceStateRepository` and `ServiceInstanceBindingStateRepository`, which are a great starting point but it is not a great idea to use them in production. 127 | Since, if the broker restarts, that state will be lost, leading to orphan Service Instances. 128 | 129 | To avoid that problem, we have to implement a Repository to persist the state in a database and not in memory. 130 | 131 | To achieve that we have are going to use https://spring.io/projects/spring-data-r2dbc[spring-data-r2dbc]. 132 | 133 | First, we need to create our Service Instance data class 134 | 135 | [source,java,indent=0] 136 | ---- 137 | @Data 138 | @NoArgsConstructor 139 | @AllArgsConstructor 140 | class ServiceInstance { 141 | @Id 142 | private Long id; 143 | private String serviceInstanceId; 144 | private String description; 145 | private OperationState operationState; 146 | } 147 | ---- 148 | 149 | And a Repository using the new `ReactiveCrudRepository`: 150 | [source,java,indent=0] 151 | ---- 152 | interface ServiceInstanceRepository extends ReactiveCrudRepository { 153 | 154 | @Query("select * from service_instance where service_instance_id = :service_instance_id") 155 | Mono findByServiceInstanceId(@Param("service_instance_id") String serviceInstanceId); 156 | 157 | @Query("delete from service_instance where service_instance_id = :service_instance_id") 158 | Mono deleteByServiceInstanceId(@Param("service_instance_id") String serviceInstanceId); 159 | 160 | } 161 | ---- 162 | 163 | Now that we have our reactive Repository in place, we can implement the `ServiceInstanceStateRepository` class methods: 164 | 165 | [source,java,indent=0] 166 | ---- 167 | class DefaultServiceInstanceStateRepository implements ServiceInstanceStateRepository { 168 | 169 | private final ServiceInstanceRepository serviceInstanceRepository; 170 | 171 | DefaultServiceInstanceStateRepository(ServiceInstanceRepository serviceInstanceRepository) { 172 | this.serviceInstanceRepository = serviceInstanceRepository; 173 | } 174 | 175 | @Override 176 | public Mono saveState(String serviceInstanceId, OperationState state, String description) { 177 | return serviceInstanceRepository.findByServiceInstanceId(serviceInstanceId) 178 | .flatMap(serviceInstance -> { 179 | if (serviceInstance == null) { 180 | serviceInstance = new ServiceInstance(); 181 | } 182 | 183 | serviceInstance.setServiceInstanceId(serviceInstanceId); 184 | serviceInstance.setOperationState(state); 185 | serviceInstance.setDescription(description); 186 | 187 | return Mono.just(serviceInstance); 188 | }) 189 | .flatMap(serviceInstanceRepository::save) 190 | .map(DefaultServiceInstanceStateRepository::toServiceInstanceState); 191 | } 192 | 193 | @Override 194 | public Mono getState(String serviceInstanceId) { 195 | return serviceInstanceRepository.findByServiceInstanceId(serviceInstanceId) 196 | .flatMap(serviceInstance -> { 197 | if (serviceInstance == null) { 198 | return Mono.error(new IllegalArgumentException("Unknown service instance ID " + serviceInstanceId)); 199 | } 200 | return Mono.just(serviceInstance); 201 | }) 202 | .map(DefaultServiceInstanceStateRepository::toServiceInstanceState); 203 | } 204 | 205 | @Override 206 | public Mono removeState(String serviceInstanceId) { 207 | return getState(serviceInstanceId) 208 | .doOnNext(serviceInstanceState -> serviceInstanceRepository.deleteByServiceInstanceId(serviceInstanceId)); 209 | } 210 | 211 | private static ServiceInstanceState toServiceInstanceState(ServiceInstance serviceInstance) { 212 | return new ServiceInstanceState(serviceInstance.getOperationState(), serviceInstance.getDescription(), null); 213 | } 214 | 215 | } 216 | ---- 217 | The same applies to Service Instance Binding states. 218 | 219 | For those to be considered by Spring, we have to add them to our Configuration class: 220 | 221 | [source,java,indent=0] 222 | ---- 223 | @Configuration 224 | @EnableR2dbcRepositories 225 | @EnableTransactionManagement 226 | public class DataConfiguration { 227 | 228 | @Bean 229 | DefaultServiceInstanceStateRepository serviceInstanceStateRepository( 230 | ServiceInstanceRepository serviceInstanceRepository) { 231 | return new DefaultServiceInstanceStateRepository(serviceInstanceRepository); 232 | } 233 | 234 | @Bean 235 | DefaultServiceInstanceBindingStateRepository serviceInstanceBindingStateRepository( 236 | ServiceInstanceBindingRepository serviceInstanceBindingRepository) { 237 | return new DefaultServiceInstanceBindingStateRepository(serviceInstanceBindingRepository); 238 | } 239 | 240 | } 241 | ---- 242 | 243 | Since our broker is fully reactive, we went for an implementation based on R2DBC. 244 | 245 | A not recommended alternative, not fully reactive, is wrapping a blocking database call into a `Mono.fromCallable(() -> ...)`. 246 | However, this can easily lead to a thread exhaustion and subsequent memory problems if there are enough calls being made to the database. 247 | 248 | An example of this approach is: 249 | 250 | [source,java,indent=0] 251 | ---- 252 | @Override 253 | public Mono getState(String serviceInstanceId) { 254 | return Mono.fromCallable(() -> crudRepository.findByServiceInstanceId(serviceInstanceId)) 255 | .flatMap(optionalServiceInstance -> Mono.defer(() -> Mono.just(optionalServiceInstance.get()))) 256 | .map(DefaultServiceInstanceStateRepository::toServiceInstanceState); 257 | } 258 | ---- 259 | 260 | == Backing application Targets 261 | 262 | Different brokers will have different strategies on where to deploy every backing application. 263 | 264 | By default, `spring-cloud-app-broker` provides the two most common implementations on how and where to deploy the backing applications 265 | * `SpacePerServiceInstance` will deploy backing applications to a unique target location that is named using the service instance GUID provided by the platform at service instance create time. 266 | For Cloud Foundry, this target location will be the org named by `spring.cloud.appbroker.deployer.cloudfoundry.default-org` and a new space created using the service instance GUID as the space name. 267 | * `ServiceInstanceGuidSuffix` will deploy backing applications using a unique name and hostname that incorporates the service instance GUID provided by the platform at service instance create time. 268 | For Cloud Foundry, the target location will be the org named by `spring.cloud.appbroker.deployer.cloudfoundry.default-org`, the space named by `spring.cloud.appbroker.deployer.cloudfoundry.default-space`, and an application name as `[APP-NAME]-[SI-GUID]`, where `[APP-NAME]` is the `name` listed for the application under `spring.cloud.appbroker.services.apps` and `[SI-GUID]` is the service instance GUID. The application will also use a hostname incorporating the service instance GUID as a suffix, as `[APP-NAME]-[SI-GUID]`. 269 | 270 | However, it is possible to create a custom Target with custom business logic by creating a class that extends `TargetFactory`. 271 | 272 | [source,java] 273 | ---- 274 | public class CustomSpaceTarget extends TargetFactory { 275 | 276 | private CustomSpaceService customSpaceService; 277 | 278 | public CustomSpaceTarget(CustomSpaceService customSpaceService) { 279 | super(Config.class); 280 | this.customSpaceService = customSpaceService; 281 | } 282 | 283 | @Override 284 | public Target create(Config config) { 285 | return this::apply; 286 | } 287 | 288 | private ArtifactDetails apply(Map properties, String name, String serviceInstanceId) { 289 | String space = customSpaceService.retrieveSpaceName(); 290 | properties.put(DeploymentProperties.TARGET_PROPERTY_KEY, space); 291 | 292 | return ArtifactDetails.builder() 293 | .name(name) 294 | .properties(properties) 295 | .build(); 296 | } 297 | 298 | public static class Config { 299 | } 300 | 301 | } 302 | ---- 303 | 304 | For these to be considered by Spring, we have to add them to our Configuration class: 305 | 306 | [source,java] 307 | ---- 308 | @Configuration 309 | public class TargetServiceConfiguration { 310 | 311 | @Bean 312 | public CustomSpaceService customSpaceService() { 313 | return new CustomSpaceService(); 314 | } 315 | 316 | @Bean 317 | public CustomSpaceTarget customSpaceTarget(CustomSpaceService customSpaceService) { 318 | return new CustomSpaceTarget(customSpaceService); 319 | } 320 | 321 | } 322 | ---- 323 | 324 | Once configured, we can specify in our service the new custom Target: 325 | 326 | [source, yml, indent=0] 327 | ---- 328 | spring: 329 | cloud: 330 | appbroker: 331 | services: 332 | - service-name: example 333 | plan-name: standard 334 | target: 335 | name: CustomSpaceTarget 336 | ---- 337 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | buildscript { 18 | repositories { 19 | maven { url "https://repo.spring.io/plugins-release" } 20 | } 21 | dependencies { 22 | classpath("io.spring.gradle:dependency-management-plugin:1.0.8.RELEASE") 23 | classpath("io.spring.nohttp:nohttp-gradle:0.0.3.RELEASE") 24 | } 25 | } 26 | 27 | plugins { 28 | id "io.franzbecker.gradle-lombok" version '3.2.0' 29 | } 30 | 31 | ext { 32 | springCloudAppBrokerVersion = project.findProperty("springCloudAppBrokerVersion") ?: "1.0.4.RELEASE" 33 | springBootVersion = project.findProperty("springBootVersion") ?: "2.2.2.RELEASE" 34 | checkstyleVersion = "8.21" 35 | pmdVersion = "6.19.0" 36 | } 37 | 38 | // NoHttp has to be applied at the root level 39 | // so that it reads all the root files, including the gradle ones. 40 | apply plugin: "io.spring.nohttp" 41 | 42 | // nohttp requires a valid checkstyle configuration 43 | checkstyle { 44 | configFile = file("${project.rootDir}/src/checkstyle/checkstyle-nohttp.xml") 45 | toolVersion = "${checkstyleVersion}" 46 | } 47 | 48 | configure(allprojects) { 49 | group = "org.springframework.cloud" 50 | 51 | apply plugin: "java" 52 | apply plugin: "eclipse" 53 | apply plugin: "idea" 54 | apply plugin: "pmd" 55 | apply plugin: "checkstyle" 56 | apply plugin: "io.spring.dependency-management" 57 | apply plugin: "io.franzbecker.gradle-lombok" 58 | 59 | repositories { 60 | mavenCentral() 61 | maven { url "https://repo.spring.io/libs-release" } 62 | maven { url "https://repo.spring.io/libs-snapshot" } 63 | maven { url "https://repo.spring.io/milestone" } 64 | } 65 | 66 | dependencies { 67 | testRuntimeOnly("io.spring.nohttp:nohttp:0.0.3.RELEASE") 68 | } 69 | 70 | checkstyle { 71 | configFile = file("${project.rootDir}/src/checkstyle/checkstyle.xml") 72 | toolVersion = "${checkstyleVersion}" 73 | } 74 | checkstyleMain { 75 | source = "src/main/java" 76 | } 77 | checkstyleTest { 78 | source = "src/test/java" 79 | } 80 | 81 | pmd { 82 | toolVersion = "${pmdVersion}" 83 | } 84 | pmdMain { 85 | ruleSets = [] 86 | ruleSetFiles = files("${project.rootDir}/src/pmd/pmdRuleSet.xml") 87 | source = "src/main/java" 88 | } 89 | pmdTest { 90 | ruleSets = [] 91 | ruleSetFiles = files("${project.rootDir}/src/pmd/pmdTestRuleSet.xml") 92 | source = "src/test/java" 93 | } 94 | 95 | lombok { 96 | version = '1.18.2' 97 | sha256 = "524e0a697e9d62950b2f763d88d35cd8dc82a9a1" 98 | } 99 | 100 | test { 101 | // enable JUnit 5 102 | useJUnitPlatform() 103 | 104 | testLogging { 105 | // display all the events 106 | events 'PASSED', 'FAILED', 'SKIPPED' 107 | // display stdout and stderr 108 | showStandardStreams = true 109 | } 110 | 111 | // create a summary after the execution 112 | afterSuite { desc, result -> 113 | if (!desc.parent) { 114 | println "\nTest result: ${result.resultType}" 115 | println "Test summary: ${result.testCount} tests, " + 116 | "${result.successfulTestCount} succeeded, " + 117 | "${result.failedTestCount} failed, " + 118 | "${result.skippedTestCount} skipped" 119 | } 120 | } 121 | 122 | // print failed tests after the execution 123 | def failedTests = [] 124 | 125 | afterTest { test, result -> 126 | if (result.resultType == TestResult.ResultType.FAILURE) { 127 | failedTests << test 128 | } 129 | } 130 | 131 | afterSuite { 132 | failedTests.each { test -> println "FAILED test: ${test.className} > ${test.name}" } 133 | } 134 | } 135 | 136 | } 137 | 138 | subprojects { 139 | task allDependencyInsight(type: DependencyInsightReportTask) 140 | task dependencyReport(type: DependencyReportTask) 141 | } 142 | 143 | configure(subprojects) { 144 | sourceCompatibility = 1.8 145 | targetCompatibility = 1.8 146 | [compileJava, compileTestJava]*.options*.encoding = "UTF-8" 147 | 148 | [compileJava, compileTestJava]*.options*.compilerArgs = [ 149 | "-Xlint:serial", 150 | "-Xlint:varargs", 151 | "-Xlint:cast", 152 | "-Xlint:classfile", 153 | "-Xlint:dep-ann", 154 | "-Xlint:divzero", 155 | "-Xlint:empty", 156 | "-Xlint:finally", 157 | "-Xlint:overrides", 158 | "-Xlint:path", 159 | "-Xlint:-processing", 160 | "-Xlint:static", 161 | "-Xlint:try", 162 | "-Xlint:fallthrough", 163 | "-Xlint:rawtypes", 164 | "-Xlint:deprecation", 165 | "-Xlint:unchecked", 166 | "-Xlint:-options", 167 | "-Werror" 168 | ] 169 | 170 | configurations { 171 | // exclude JUnit 4 globally, in favor of JUnit 5 172 | testImplementation.exclude group: "junit", module: "junit" 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /ci/config-concourse-master.yml: -------------------------------------------------------------------------------- 1 | scs-slack-failure-channel: "#sc-app-broker" 2 | branch: master 3 | samples-repo: https://github.com/spring-cloud-samples/spring-cloud-app-broker-samples 4 | -------------------------------------------------------------------------------- /ci/pipeline.yml: -------------------------------------------------------------------------------- 1 | --- 2 | aliases: 3 | - &slack-failure-notification 4 | put: alert 5 | params: 6 | icon_emoji: ":animal:" 7 | username: concourse 8 | channel: {{scs-slack-failure-channel}} 9 | text: Build of job $BUILD_JOB_NAME in the $BUILD_PIPELINE_NAME pipeline has failed! 10 | 11 | jobs: 12 | - name: build 13 | serial: true 14 | public: true 15 | plan: 16 | - get: samples-repo 17 | trigger: true 18 | - task: run-tests 19 | file: samples-repo/ci/tasks/run-tests.yml 20 | on_failure: 21 | *slack-failure-notification 22 | 23 | resource_types: 24 | - name: slack-notification 25 | type: docker-image 26 | source: 27 | repository: cfcommunity/slack-notification-resource 28 | tag: latest 29 | 30 | resources: 31 | - name: samples-repo 32 | type: git 33 | source: 34 | uri: ((samples-repo)) 35 | branch: ((branch)) 36 | 37 | - name: alert 38 | type: slack-notification 39 | source: 40 | url: {{scs-slack-webhook}} 41 | groups: 42 | - name: "Build" 43 | jobs: ["build"] 44 | -------------------------------------------------------------------------------- /ci/scripts/run-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | pushd samples-repo >/dev/null 5 | ./gradlew --no-daemon clean check -Dorg.gradle.jvmargs="-Xmx512m -Xmx2048m" 6 | popd >/dev/null 7 | -------------------------------------------------------------------------------- /ci/scripts/set-pipelines.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | readonly SCS_SECRETS_LAST_PASS_ID="1938546022346916823" 5 | 6 | secrets_file=$(mktemp).yml 7 | 8 | fetch_secrets() { 9 | lpass show --notes "${SCS_SECRETS_LAST_PASS_ID}" >>"${secrets_file}" 10 | } 11 | 12 | set_app_broker_pipeline() { 13 | echo "Setting app-broker-samples pipeline..." 14 | fly -t scs set-pipeline -p app-broker-samples -c pipeline.yml -l config-concourse-master.yml -l "${secrets_file}" 15 | } 16 | 17 | cleanup() { 18 | rm "${secrets_file}" 19 | } 20 | 21 | trap "cleanup" EXIT 22 | 23 | main() { 24 | fly -t scs sync 25 | 26 | pushd "$(dirname $0)/.." >/dev/null 27 | fetch_secrets 28 | set_app_broker_pipeline 29 | popd >/dev/null 30 | } 31 | 32 | main 33 | -------------------------------------------------------------------------------- /ci/tasks/run-tests.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | image_resource: 4 | type: docker-image 5 | source: 6 | repository: openjdk 7 | tag: 8 8 | 9 | inputs: 10 | - name: samples-repo 11 | caches: 12 | - path: maven 13 | - path: gradle 14 | 15 | run: 16 | path: samples-repo/ci/scripts/run-tests.sh 17 | -------------------------------------------------------------------------------- /creating-workflows/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | buildscript { 18 | repositories { 19 | mavenCentral() 20 | maven { url "https://plugins.gradle.org/m2/" } 21 | } 22 | 23 | dependencies { 24 | classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 25 | } 26 | } 27 | 28 | apply plugin: 'org.springframework.boot' 29 | 30 | dependencies { 31 | implementation "org.springframework.boot:spring-boot-starter-webflux" 32 | implementation "org.springframework.cloud:spring-cloud-starter-app-broker-cloudfoundry:${springCloudAppBrokerVersion}" 33 | 34 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 35 | exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /creating-workflows/src/main/java/org/springframework/cloud/appbroker/samples/creatingworkflows/AppBrokerApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.creatingworkflows; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | 22 | @SuppressWarnings({"PMD.UseUtilityClass"}) 23 | @SpringBootApplication 24 | public class AppBrokerApplication { 25 | 26 | public static void main(String[] args) { 27 | SpringApplication.run(AppBrokerApplication.class, args); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /creating-workflows/src/main/java/org/springframework/cloud/appbroker/samples/creatingworkflows/AppBrokerApplicationConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.creatingworkflows; 18 | 19 | import org.springframework.cloud.appbroker.samples.creatingworkflows.services.NoOpCreateServiceInstanceWorkflow; 20 | import org.springframework.cloud.appbroker.samples.creatingworkflows.services.NoOpDeleteServiceInstanceWorkflow; 21 | import org.springframework.cloud.appbroker.samples.creatingworkflows.services.NoOpServiceInstanceBindingService; 22 | import org.springframework.cloud.appbroker.samples.creatingworkflows.services.NoOpUpdateServiceInstanceWorkflow; 23 | import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow; 24 | import org.springframework.cloud.appbroker.service.DeleteServiceInstanceWorkflow; 25 | import org.springframework.cloud.appbroker.service.UpdateServiceInstanceWorkflow; 26 | import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.Configuration; 29 | 30 | @Configuration 31 | public class AppBrokerApplicationConfiguration { 32 | 33 | @Bean 34 | public CreateServiceInstanceWorkflow createServiceInstanceWorkflow() { 35 | return new NoOpCreateServiceInstanceWorkflow(); 36 | } 37 | 38 | @Bean 39 | public UpdateServiceInstanceWorkflow updateServiceInstanceWorkflow() { 40 | return new NoOpUpdateServiceInstanceWorkflow(); 41 | } 42 | 43 | @Bean 44 | public DeleteServiceInstanceWorkflow deleteServiceInstanceWorkflow() { 45 | return new NoOpDeleteServiceInstanceWorkflow(); 46 | } 47 | 48 | @Bean 49 | public ServiceInstanceBindingService serviceInstanceBindingService() { 50 | return new NoOpServiceInstanceBindingService(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /creating-workflows/src/main/java/org/springframework/cloud/appbroker/samples/creatingworkflows/ServiceInstanceParametersValidatorWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.creatingworkflows; 18 | 19 | import java.util.Arrays; 20 | import java.util.List; 21 | 22 | import reactor.core.publisher.Mono; 23 | 24 | import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow; 25 | import org.springframework.cloud.servicebroker.exception.ServiceBrokerInvalidParametersException; 26 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest; 27 | import org.springframework.core.annotation.Order; 28 | import org.springframework.stereotype.Component; 29 | 30 | import static org.springframework.cloud.appbroker.samples.creatingworkflows.ServiceInstanceServiceOrder.VALIDATE_CREATE_PARAMETERS; 31 | import static org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse.CreateServiceInstanceResponseBuilder; 32 | 33 | @Component 34 | @Order(VALIDATE_CREATE_PARAMETERS) 35 | class ServiceInstanceParametersValidatorWorkflow implements CreateServiceInstanceWorkflow { 36 | 37 | private static final String SERVICE_NAME = "example"; 38 | 39 | private static final List SUPPORTED_PARAMETERS = Arrays.asList("count", "memory", "routes"); // TODO java 14 40 | 41 | @Override 42 | public Mono accept(CreateServiceInstanceRequest request) { 43 | return Mono.just(SERVICE_NAME.equals(request.getServiceDefinition().getName())); 44 | } 45 | 46 | @Override 47 | public Mono buildResponse( 48 | CreateServiceInstanceRequest request, 49 | CreateServiceInstanceResponseBuilder responseBuilder) { 50 | 51 | for (String parameter : request.getParameters().keySet()) { 52 | if (!SUPPORTED_PARAMETERS.contains(parameter)) { 53 | String errorMessage = String.format("Invalid parameter {%s}", parameter); 54 | return Mono.error(new ServiceBrokerInvalidParametersException(errorMessage)); 55 | } 56 | } 57 | 58 | return Mono.just(responseBuilder); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /creating-workflows/src/main/java/org/springframework/cloud/appbroker/samples/creatingworkflows/ServiceInstanceServiceOrder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.creatingworkflows; 18 | 19 | final class ServiceInstanceServiceOrder { 20 | 21 | private static final int CREATE_SI_WORKFLOW_ORDER = 0; 22 | 23 | public static final int VALIDATE_CREATE_PARAMETERS = CREATE_SI_WORKFLOW_ORDER - 400; 24 | 25 | private ServiceInstanceServiceOrder() { 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /creating-workflows/src/main/java/org/springframework/cloud/appbroker/samples/creatingworkflows/services/NoOpCreateServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.creatingworkflows.services; 18 | 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | import reactor.core.publisher.Mono; 22 | 23 | import org.springframework.beans.factory.annotation.Value; 24 | import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow; 25 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest; 26 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse; 27 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse.CreateServiceInstanceResponseBuilder; 28 | 29 | /** 30 | * A no-op implementation of {@link CreateServiceInstanceWorkflow} 31 | */ 32 | public class NoOpCreateServiceInstanceWorkflow implements CreateServiceInstanceWorkflow { 33 | 34 | private static final Logger LOG = LoggerFactory.getLogger(NoOpCreateServiceInstanceWorkflow.class); 35 | 36 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 37 | private String backingServiceId; 38 | 39 | @Override 40 | public Mono create(CreateServiceInstanceRequest request, CreateServiceInstanceResponse response) { 41 | return Mono.empty(); 42 | } 43 | 44 | @Override 45 | public Mono accept(CreateServiceInstanceRequest request) { 46 | if (LOG.isInfoEnabled()) { 47 | LOG.info("Got request to create service instance: " + request); 48 | } 49 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 50 | } 51 | 52 | @Override 53 | public Mono buildResponse(CreateServiceInstanceRequest request, 54 | CreateServiceInstanceResponseBuilder responseBuilder) { 55 | if (LOG.isInfoEnabled()) { 56 | LOG.info("Got request to create service instance: " + request); 57 | } 58 | return Mono.just(responseBuilder); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /creating-workflows/src/main/java/org/springframework/cloud/appbroker/samples/creatingworkflows/services/NoOpDeleteServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.creatingworkflows.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.beans.factory.annotation.Value; 22 | import org.springframework.cloud.appbroker.service.DeleteServiceInstanceWorkflow; 23 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceRequest; 24 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse; 25 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse.DeleteServiceInstanceResponseBuilder; 26 | 27 | /** 28 | * A no-op implementation of {@link DeleteServiceInstanceWorkflow} 29 | */ 30 | public class NoOpDeleteServiceInstanceWorkflow implements DeleteServiceInstanceWorkflow { 31 | 32 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 33 | private String backingServiceId; 34 | 35 | @Override 36 | public Mono delete(DeleteServiceInstanceRequest request, DeleteServiceInstanceResponse response) { 37 | return Mono.empty(); 38 | } 39 | 40 | @Override 41 | public Mono accept(DeleteServiceInstanceRequest request) { 42 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 43 | } 44 | 45 | @Override 46 | public Mono buildResponse(DeleteServiceInstanceRequest request, 47 | DeleteServiceInstanceResponseBuilder responseBuilder) { 48 | return Mono.just(responseBuilder); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /creating-workflows/src/main/java/org/springframework/cloud/appbroker/samples/creatingworkflows/services/NoOpServiceInstanceBindingService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.creatingworkflows.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceAppBindingResponse; 22 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingRequest; 23 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingResponse; 24 | import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingRequest; 25 | import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingResponse; 26 | import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; 27 | 28 | /** 29 | * A no-op implementation of {@link ServiceInstanceBindingService} 30 | */ 31 | public class NoOpServiceInstanceBindingService implements ServiceInstanceBindingService { 32 | 33 | @Override 34 | public Mono createServiceInstanceBinding( 35 | CreateServiceInstanceBindingRequest request) { 36 | return Mono.just(CreateServiceInstanceAppBindingResponse.builder().build()); 37 | } 38 | 39 | @Override 40 | public Mono deleteServiceInstanceBinding( 41 | DeleteServiceInstanceBindingRequest request) { 42 | return Mono.just(DeleteServiceInstanceBindingResponse.builder().build()); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /creating-workflows/src/main/java/org/springframework/cloud/appbroker/samples/creatingworkflows/services/NoOpUpdateServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.creatingworkflows.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.beans.factory.annotation.Value; 22 | import org.springframework.cloud.appbroker.service.UpdateServiceInstanceWorkflow; 23 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceRequest; 24 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse; 25 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse.UpdateServiceInstanceResponseBuilder; 26 | 27 | /** 28 | * A no-op implementation of {@link UpdateServiceInstanceWorkflow} 29 | */ 30 | public class NoOpUpdateServiceInstanceWorkflow implements UpdateServiceInstanceWorkflow { 31 | 32 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 33 | private String backingServiceId; 34 | 35 | @Override 36 | public Mono update(UpdateServiceInstanceRequest request, UpdateServiceInstanceResponse response) { 37 | return Mono.empty(); 38 | } 39 | 40 | @Override 41 | public Mono accept(UpdateServiceInstanceRequest request) { 42 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 43 | } 44 | 45 | @Override 46 | public Mono buildResponse(UpdateServiceInstanceRequest request, 47 | UpdateServiceInstanceResponseBuilder responseBuilder) { 48 | return Mono.just(responseBuilder); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /creating-workflows/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | openservicebroker: 4 | catalog: 5 | services: 6 | - id: example-service-id 7 | name: example 8 | description: A simple example 9 | bindable: true 10 | tags: 11 | - example 12 | tags 13 | plans: 14 | - id: standard-plan-id 15 | bindable: true 16 | name: standard 17 | description: A simple plan 18 | free: true 19 | 20 | appbroker: 21 | services: 22 | - service-name: example 23 | plan-name: standard 24 | apps: 25 | - name: example-service-app1 26 | path: classpath:demo.jar 27 | parameters-transformers: 28 | - name: EnvironmentMapping 29 | args: 30 | include: lang 31 | - name: PropertyMapping 32 | args: 33 | include: count,upgrade,memory 34 | - name: RequestTimeoutParameterTransformer 35 | 36 | deployer: 37 | cloudfoundry: 38 | api-host: api.sys.example.com 39 | api-port: 443 40 | username: admin 41 | password: adminpass 42 | default-org: test 43 | default-space: development 44 | -------------------------------------------------------------------------------- /creating-workflows/src/main/resources/demo.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-app-broker-samples/e941b21c0171f8b4506600b8e892c471aaa2af80/creating-workflows/src/main/resources/demo.jar -------------------------------------------------------------------------------- /creating-workflows/src/test/java/org/springframework/cloud/appbroker/samples/creatingworkflows/AppBrokerApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.creatingworkflows; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import org.springframework.boot.test.context.SpringBootTest; 22 | 23 | @SpringBootTest 24 | class AppBrokerApplicationTests { 25 | 26 | @Test 27 | void contextLoads() { 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-app-broker-samples/e941b21c0171f8b4506600b8e892c471aaa2af80/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /parameter-transformer/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | buildscript { 18 | repositories { 19 | mavenCentral() 20 | maven { url "https://plugins.gradle.org/m2/" } 21 | } 22 | 23 | dependencies { 24 | classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 25 | } 26 | } 27 | 28 | apply plugin: 'org.springframework.boot' 29 | 30 | dependencies { 31 | implementation "org.springframework.boot:spring-boot-starter-webflux" 32 | implementation "org.springframework.cloud:spring-cloud-starter-app-broker-cloudfoundry:${springCloudAppBrokerVersion}" 33 | 34 | testImplementation "io.projectreactor:reactor-test" 35 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 36 | exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /parameter-transformer/src/main/java/org/springframework/cloud/appbroker/samples/parametertransformer/AppBrokerApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.parametertransformer; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | 22 | @SuppressWarnings({"PMD.UseUtilityClass"}) 23 | @SpringBootApplication 24 | public class AppBrokerApplication { 25 | 26 | public static void main(String[] args) { 27 | SpringApplication.run(AppBrokerApplication.class, args); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /parameter-transformer/src/main/java/org/springframework/cloud/appbroker/samples/parametertransformer/AppBrokerApplicationConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.parametertransformer; 18 | 19 | import org.springframework.cloud.appbroker.samples.parametertransformer.services.NoOpCreateServiceInstanceWorkflow; 20 | import org.springframework.cloud.appbroker.samples.parametertransformer.services.NoOpDeleteServiceInstanceWorkflow; 21 | import org.springframework.cloud.appbroker.samples.parametertransformer.services.NoOpServiceInstanceBindingService; 22 | import org.springframework.cloud.appbroker.samples.parametertransformer.services.NoOpUpdateServiceInstanceWorkflow; 23 | import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow; 24 | import org.springframework.cloud.appbroker.service.DeleteServiceInstanceWorkflow; 25 | import org.springframework.cloud.appbroker.service.UpdateServiceInstanceWorkflow; 26 | import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.Configuration; 29 | 30 | @Configuration 31 | public class AppBrokerApplicationConfiguration { 32 | 33 | @Bean 34 | public CreateServiceInstanceWorkflow createServiceInstanceWorkflow() { 35 | return new NoOpCreateServiceInstanceWorkflow(); 36 | } 37 | 38 | @Bean 39 | public UpdateServiceInstanceWorkflow updateServiceInstanceWorkflow() { 40 | return new NoOpUpdateServiceInstanceWorkflow(); 41 | } 42 | 43 | @Bean 44 | public DeleteServiceInstanceWorkflow deleteServiceInstanceWorkflow() { 45 | return new NoOpDeleteServiceInstanceWorkflow(); 46 | } 47 | 48 | @Bean 49 | public ServiceInstanceBindingService serviceInstanceBindingService() { 50 | return new NoOpServiceInstanceBindingService(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /parameter-transformer/src/main/java/org/springframework/cloud/appbroker/samples/parametertransformer/ParameterTransformerConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.parametertransformer; 18 | 19 | import org.springframework.cloud.appbroker.deployer.BackingApplication; 20 | import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformerFactory; 21 | import org.springframework.context.annotation.Bean; 22 | import org.springframework.context.annotation.Configuration; 23 | 24 | @Configuration 25 | public class ParameterTransformerConfiguration { 26 | 27 | @Bean 28 | public ParametersTransformerFactory requestTimeoutParameterTransformerFactory() { 29 | return new RequestTimeoutParameterTransformer(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /parameter-transformer/src/main/java/org/springframework/cloud/appbroker/samples/parametertransformer/RequestTimeoutParameterTransformer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.appbroker.samples.parametertransformer; 17 | 18 | import java.util.Map; 19 | 20 | import reactor.core.publisher.Mono; 21 | 22 | import org.springframework.cloud.appbroker.deployer.BackingApplication; 23 | import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformer; 24 | import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformerFactory; 25 | 26 | public class RequestTimeoutParameterTransformer extends ParametersTransformerFactory { 27 | 28 | @Override 29 | public ParametersTransformer create(Object config) { 30 | return this::transform; 31 | } 32 | 33 | private Mono transform( 34 | BackingApplication backingApplication, Map parameters) { 35 | if (parameters.containsKey("request-timeout-ms")) { 36 | backingApplication 37 | .addEnvironment("my-app.httpclient.connect-timeout", parameters.get("request-timeout-ms")); 38 | parameters.remove("request-timeout-ms"); 39 | } 40 | return Mono.just(backingApplication); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /parameter-transformer/src/main/java/org/springframework/cloud/appbroker/samples/parametertransformer/services/NoOpCreateServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.parametertransformer.services; 18 | 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | import reactor.core.publisher.Mono; 22 | 23 | import org.springframework.beans.factory.annotation.Value; 24 | import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow; 25 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest; 26 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse; 27 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse.CreateServiceInstanceResponseBuilder; 28 | 29 | /** 30 | * A no-op implementation of {@link CreateServiceInstanceWorkflow} 31 | */ 32 | public class NoOpCreateServiceInstanceWorkflow implements CreateServiceInstanceWorkflow { 33 | 34 | private static final Logger LOG = LoggerFactory.getLogger(NoOpCreateServiceInstanceWorkflow.class); 35 | 36 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 37 | private String backingServiceId; 38 | 39 | @Override 40 | public Mono create(CreateServiceInstanceRequest request, CreateServiceInstanceResponse response) { 41 | return Mono.empty(); 42 | } 43 | 44 | @Override 45 | public Mono accept(CreateServiceInstanceRequest request) { 46 | if (LOG.isInfoEnabled()) { 47 | LOG.info("Got request to create service instance: " + request); 48 | } 49 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 50 | } 51 | 52 | @Override 53 | public Mono buildResponse(CreateServiceInstanceRequest request, 54 | CreateServiceInstanceResponseBuilder responseBuilder) { 55 | if (LOG.isInfoEnabled()) { 56 | LOG.info("Got request to create service instance: " + request); 57 | } 58 | return Mono.just(responseBuilder); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /parameter-transformer/src/main/java/org/springframework/cloud/appbroker/samples/parametertransformer/services/NoOpDeleteServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.parametertransformer.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.beans.factory.annotation.Value; 22 | import org.springframework.cloud.appbroker.service.DeleteServiceInstanceWorkflow; 23 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceRequest; 24 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse; 25 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse.DeleteServiceInstanceResponseBuilder; 26 | 27 | /** 28 | * A no-op implementation of {@link DeleteServiceInstanceWorkflow} 29 | */ 30 | public class NoOpDeleteServiceInstanceWorkflow implements DeleteServiceInstanceWorkflow { 31 | 32 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 33 | private String backingServiceId; 34 | 35 | @Override 36 | public Mono delete(DeleteServiceInstanceRequest request, DeleteServiceInstanceResponse response) { 37 | return Mono.empty(); 38 | } 39 | 40 | @Override 41 | public Mono accept(DeleteServiceInstanceRequest request) { 42 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 43 | } 44 | 45 | @Override 46 | public Mono buildResponse(DeleteServiceInstanceRequest request, 47 | DeleteServiceInstanceResponseBuilder responseBuilder) { 48 | return Mono.just(responseBuilder); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /parameter-transformer/src/main/java/org/springframework/cloud/appbroker/samples/parametertransformer/services/NoOpServiceInstanceBindingService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.parametertransformer.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceAppBindingResponse; 22 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingRequest; 23 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingResponse; 24 | import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingRequest; 25 | import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingResponse; 26 | import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; 27 | 28 | /** 29 | * A no-op implementation of {@link ServiceInstanceBindingService} 30 | */ 31 | public class NoOpServiceInstanceBindingService implements ServiceInstanceBindingService { 32 | 33 | @Override 34 | public Mono createServiceInstanceBinding( 35 | CreateServiceInstanceBindingRequest request) { 36 | return Mono.just(CreateServiceInstanceAppBindingResponse.builder().build()); 37 | } 38 | 39 | @Override 40 | public Mono deleteServiceInstanceBinding( 41 | DeleteServiceInstanceBindingRequest request) { 42 | return Mono.just(DeleteServiceInstanceBindingResponse.builder().build()); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /parameter-transformer/src/main/java/org/springframework/cloud/appbroker/samples/parametertransformer/services/NoOpUpdateServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.parametertransformer.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.beans.factory.annotation.Value; 22 | import org.springframework.cloud.appbroker.service.UpdateServiceInstanceWorkflow; 23 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceRequest; 24 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse; 25 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse.UpdateServiceInstanceResponseBuilder; 26 | 27 | /** 28 | * A no-op implementation of {@link UpdateServiceInstanceWorkflow} 29 | */ 30 | public class NoOpUpdateServiceInstanceWorkflow implements UpdateServiceInstanceWorkflow { 31 | 32 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 33 | private String backingServiceId; 34 | 35 | @Override 36 | public Mono update(UpdateServiceInstanceRequest request, UpdateServiceInstanceResponse response) { 37 | return Mono.empty(); 38 | } 39 | 40 | @Override 41 | public Mono accept(UpdateServiceInstanceRequest request) { 42 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 43 | } 44 | 45 | @Override 46 | public Mono buildResponse(UpdateServiceInstanceRequest request, 47 | UpdateServiceInstanceResponseBuilder responseBuilder) { 48 | return Mono.just(responseBuilder); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /parameter-transformer/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | openservicebroker: 4 | catalog: 5 | services: 6 | - id: example-service-id 7 | name: example 8 | description: A simple example 9 | bindable: true 10 | tags: 11 | - example 12 | tags 13 | plans: 14 | - id: standard-plan-id 15 | bindable: true 16 | name: standard 17 | description: A simple plan 18 | free: true 19 | 20 | appbroker: 21 | services: 22 | - service-name: example 23 | plan-name: standard 24 | apps: 25 | - name: example-service-app1 26 | path: classpath:demo.jar 27 | parameters-transformers: 28 | - name: EnvironmentMapping 29 | args: 30 | include: lang 31 | - name: PropertyMapping 32 | args: 33 | include: count,upgrade,memory 34 | - name: RequestTimeoutParameterTransformer 35 | 36 | deployer: 37 | cloudfoundry: 38 | api-host: api.sys.example.com 39 | api-port: 443 40 | username: admin 41 | password: adminpass 42 | default-org: test 43 | default-space: development 44 | -------------------------------------------------------------------------------- /parameter-transformer/src/main/resources/demo.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-app-broker-samples/e941b21c0171f8b4506600b8e892c471aaa2af80/parameter-transformer/src/main/resources/demo.jar -------------------------------------------------------------------------------- /parameter-transformer/src/test/java/org/springframework/cloud/appbroker/samples/parametertransformer/AppBrokerApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.parametertransformer; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import org.springframework.boot.test.context.SpringBootTest; 22 | 23 | @SpringBootTest 24 | class AppBrokerApplicationTests { 25 | 26 | @Test 27 | void contextLoads() { 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /parameter-transformer/src/test/java/org/springframework/cloud/appbroker/samples/parametertransformer/RequestTimeoutParameterTransformerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.appbroker.samples.parametertransformer; 17 | 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | 21 | import org.junit.jupiter.api.BeforeEach; 22 | import org.junit.jupiter.api.Test; 23 | import reactor.test.StepVerifier; 24 | 25 | import org.springframework.cloud.appbroker.deployer.BackingApplication; 26 | import org.springframework.cloud.appbroker.extensions.parameters.ParametersTransformer; 27 | 28 | import static org.assertj.core.api.Assertions.assertThat; 29 | 30 | class RequestTimeoutParameterTransformerTest { 31 | 32 | private ParametersTransformer transformer; 33 | 34 | @BeforeEach 35 | void setUp() { 36 | RequestTimeoutParameterTransformer gatewayServerParameterTransformer = new RequestTimeoutParameterTransformer(); 37 | transformer = gatewayServerParameterTransformer.create(null); 38 | } 39 | 40 | @Test 41 | void shouldTransformRequestAndResponseTimeouts() { 42 | Map parameters = new HashMap<>(); 43 | parameters.put("request-timeout-ms", 10_000); 44 | 45 | StepVerifier 46 | .create(transformer 47 | .transform(BackingApplication.builder() 48 | .environment(new HashMap<>()) 49 | .build(), parameters) 50 | ).assertNext(backingApplication -> { 51 | assertThat(backingApplication).isNotNull(); 52 | assertThat(backingApplication.getEnvironment() 53 | .get("my-app.httpclient.connect-timeout")) 54 | .isEqualTo(10_000); 55 | }).verifyComplete(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "spring-cloud-app-broker-samples" 2 | 3 | include "parameter-transformer" 4 | include "creating-workflows" 5 | include "state-repository" 6 | include "target-service" 7 | -------------------------------------------------------------------------------- /src/checkstyle/checkstyle-nohttp.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/checkstyle/checkstyle-suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/checkstyle/checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 135 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | -------------------------------------------------------------------------------- /src/checkstyle/license.header: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/idea/spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | 25 | 26 | 28 | 29 | 372 | -------------------------------------------------------------------------------- /src/pmd/pmdRuleSet.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | Main Ruleset 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/pmd/pmdTestRuleSet.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | Test Ruleset 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /state-repository/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | buildscript { 18 | repositories { 19 | mavenCentral() 20 | maven { url "https://plugins.gradle.org/m2/" } 21 | } 22 | 23 | dependencies { 24 | classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 25 | } 26 | } 27 | 28 | apply plugin: 'org.springframework.boot' 29 | 30 | dependencies { 31 | implementation "org.springframework.boot:spring-boot-starter-webflux" 32 | implementation "org.springframework.cloud:spring-cloud-starter-app-broker-cloudfoundry:${springCloudAppBrokerVersion}" 33 | 34 | implementation "org.springframework.boot.experimental:spring-boot-starter-r2dbc:0.1.0.M3" 35 | implementation "org.springframework.boot.experimental:spring-boot-starter-data-r2dbc:0.1.0.M3" 36 | implementation "io.r2dbc:r2dbc-h2:0.8.0.RELEASE" 37 | 38 | testImplementation "io.projectreactor:reactor-test" 39 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 40 | exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/AppBrokerApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | 22 | @SuppressWarnings({"PMD.UseUtilityClass"}) 23 | @SpringBootApplication 24 | public class AppBrokerApplication { 25 | 26 | public static void main(String[] args) { 27 | SpringApplication.run(AppBrokerApplication.class, args); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/AppBrokerApplicationConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository; 18 | 19 | import org.springframework.cloud.appbroker.samples.staterepository.services.NoOpCreateServiceInstanceWorkflow; 20 | import org.springframework.cloud.appbroker.samples.staterepository.services.NoOpDeleteServiceInstanceWorkflow; 21 | import org.springframework.cloud.appbroker.samples.staterepository.services.NoOpServiceInstanceBindingService; 22 | import org.springframework.cloud.appbroker.samples.staterepository.services.NoOpUpdateServiceInstanceWorkflow; 23 | import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow; 24 | import org.springframework.cloud.appbroker.service.DeleteServiceInstanceWorkflow; 25 | import org.springframework.cloud.appbroker.service.UpdateServiceInstanceWorkflow; 26 | import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.Configuration; 29 | 30 | @Configuration 31 | public class AppBrokerApplicationConfiguration { 32 | 33 | @Bean 34 | public CreateServiceInstanceWorkflow createServiceInstanceWorkflow() { 35 | return new NoOpCreateServiceInstanceWorkflow(); 36 | } 37 | 38 | @Bean 39 | public UpdateServiceInstanceWorkflow updateServiceInstanceWorkflow() { 40 | return new NoOpUpdateServiceInstanceWorkflow(); 41 | } 42 | 43 | @Bean 44 | public DeleteServiceInstanceWorkflow deleteServiceInstanceWorkflow() { 45 | return new NoOpDeleteServiceInstanceWorkflow(); 46 | } 47 | 48 | @Bean 49 | public ServiceInstanceBindingService serviceInstanceBindingService() { 50 | return new NoOpServiceInstanceBindingService(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/data/DataConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.data; 18 | 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.Configuration; 21 | import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories; 22 | import org.springframework.transaction.annotation.EnableTransactionManagement; 23 | 24 | @Configuration 25 | @EnableR2dbcRepositories 26 | @EnableTransactionManagement 27 | public class DataConfiguration { 28 | 29 | @Bean 30 | DefaultServiceInstanceStateRepository serviceInstanceStateRepository( 31 | ServiceInstanceRepository serviceInstanceRepository) { 32 | return new DefaultServiceInstanceStateRepository(serviceInstanceRepository); 33 | } 34 | 35 | @Bean 36 | DefaultServiceInstanceBindingStateRepository serviceInstanceBindingStateRepository( 37 | ServiceInstanceBindingRepository serviceInstanceBindingRepository) { 38 | return new DefaultServiceInstanceBindingStateRepository(serviceInstanceBindingRepository); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/data/DefaultServiceInstanceBindingStateRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.data; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.cloud.appbroker.state.ServiceInstanceBindingStateRepository; 22 | import org.springframework.cloud.appbroker.state.ServiceInstanceState; 23 | import org.springframework.cloud.servicebroker.model.instance.OperationState; 24 | 25 | class DefaultServiceInstanceBindingStateRepository implements ServiceInstanceBindingStateRepository { 26 | 27 | private final ServiceInstanceBindingRepository serviceInstanceBindingRepository; 28 | 29 | DefaultServiceInstanceBindingStateRepository(ServiceInstanceBindingRepository serviceInstanceBindingRepository) { 30 | this.serviceInstanceBindingRepository = serviceInstanceBindingRepository; 31 | } 32 | 33 | @Override 34 | public Mono saveState(String serviceInstanceId, String bindingId, OperationState state, 35 | String description) { 36 | return serviceInstanceBindingRepository.findByServiceInstanceIdAndBindingId(serviceInstanceId, bindingId) 37 | .switchIfEmpty(Mono.just(new ServiceInstanceBinding())) 38 | .flatMap(binding -> { 39 | binding.setServiceInstanceId(serviceInstanceId); 40 | binding.setBindingId(bindingId); 41 | binding.setOperationState(state); 42 | binding.setDescription(description); 43 | return Mono.just(binding); 44 | }) 45 | .flatMap(serviceInstanceBindingRepository::save) 46 | .map(DefaultServiceInstanceBindingStateRepository::toServiceInstanceState); 47 | } 48 | 49 | @Override 50 | public Mono getState(String serviceInstanceId, String bindingId) { 51 | return serviceInstanceBindingRepository.findByServiceInstanceIdAndBindingId(serviceInstanceId, bindingId) 52 | .switchIfEmpty(Mono.error(new IllegalArgumentException( 53 | "Unknown binding: serviceInstanceId=" + serviceInstanceId + ", bindingId=" + bindingId))) 54 | .map(DefaultServiceInstanceBindingStateRepository::toServiceInstanceState); 55 | } 56 | 57 | @Override 58 | public Mono removeState(String serviceInstanceId, String bindingId) { 59 | return getState(serviceInstanceId, bindingId) 60 | .doOnNext( 61 | serviceInstanceState -> serviceInstanceBindingRepository 62 | .deleteByServiceInstanceIdAndBindingId(serviceInstanceId, bindingId)); 63 | } 64 | 65 | private static ServiceInstanceState toServiceInstanceState(ServiceInstanceBinding binding) { 66 | return new ServiceInstanceState(binding.getOperationState(), binding.getDescription(), null); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/data/DefaultServiceInstanceStateRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.data; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.cloud.appbroker.state.ServiceInstanceState; 22 | import org.springframework.cloud.appbroker.state.ServiceInstanceStateRepository; 23 | import org.springframework.cloud.servicebroker.model.instance.OperationState; 24 | 25 | class DefaultServiceInstanceStateRepository implements ServiceInstanceStateRepository { 26 | 27 | private final ServiceInstanceRepository serviceInstanceRepository; 28 | 29 | DefaultServiceInstanceStateRepository(ServiceInstanceRepository serviceInstanceRepository) { 30 | this.serviceInstanceRepository = serviceInstanceRepository; 31 | } 32 | 33 | @Override 34 | public Mono saveState(String serviceInstanceId, OperationState state, String description) { 35 | return serviceInstanceRepository.findByServiceInstanceId(serviceInstanceId) 36 | .switchIfEmpty(Mono.just(new ServiceInstance())) 37 | .flatMap(serviceInstance -> { 38 | serviceInstance.setServiceInstanceId(serviceInstanceId); 39 | serviceInstance.setOperationState(state); 40 | serviceInstance.setDescription(description); 41 | return Mono.just(serviceInstance); 42 | }) 43 | .flatMap(serviceInstanceRepository::save) 44 | .map(DefaultServiceInstanceStateRepository::toServiceInstanceState); 45 | } 46 | 47 | @Override 48 | public Mono getState(String serviceInstanceId) { 49 | return serviceInstanceRepository.findByServiceInstanceId(serviceInstanceId) 50 | .switchIfEmpty(Mono.error(new IllegalArgumentException("Unknown service instance ID " + serviceInstanceId))) 51 | .map(DefaultServiceInstanceStateRepository::toServiceInstanceState); 52 | } 53 | 54 | @Override 55 | public Mono removeState(String serviceInstanceId) { 56 | return getState(serviceInstanceId) 57 | .doOnNext(serviceInstanceState -> serviceInstanceRepository.deleteByServiceInstanceId(serviceInstanceId)); 58 | } 59 | 60 | private static ServiceInstanceState toServiceInstanceState(ServiceInstance serviceInstance) { 61 | return new ServiceInstanceState(serviceInstance.getOperationState(), serviceInstance.getDescription(), null); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/data/ServiceInstance.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.data; 18 | 19 | import lombok.AllArgsConstructor; 20 | import lombok.Data; 21 | import lombok.NoArgsConstructor; 22 | 23 | import org.springframework.cloud.servicebroker.model.instance.OperationState; 24 | import org.springframework.data.annotation.Id; 25 | 26 | @Data 27 | @NoArgsConstructor 28 | @AllArgsConstructor 29 | class ServiceInstance { 30 | 31 | @Id 32 | private Long id; 33 | 34 | private String serviceInstanceId; 35 | 36 | private String description; 37 | 38 | private OperationState operationState; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/data/ServiceInstanceBinding.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.data; 18 | 19 | import lombok.AllArgsConstructor; 20 | import lombok.Data; 21 | import lombok.NoArgsConstructor; 22 | 23 | import org.springframework.cloud.servicebroker.model.instance.OperationState; 24 | import org.springframework.data.annotation.Id; 25 | 26 | @Data 27 | @NoArgsConstructor 28 | @AllArgsConstructor 29 | class ServiceInstanceBinding { 30 | 31 | @Id 32 | private Long id; 33 | 34 | private String bindingId; 35 | 36 | private String serviceInstanceId; 37 | 38 | private String description; 39 | 40 | private OperationState operationState; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/data/ServiceInstanceBindingRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.data; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.data.r2dbc.repository.Query; 22 | import org.springframework.data.repository.query.Param; 23 | import org.springframework.data.repository.reactive.ReactiveCrudRepository; 24 | 25 | interface ServiceInstanceBindingRepository extends ReactiveCrudRepository { 26 | 27 | @Query("select * from service_instance_binding " + 28 | "where service_instance_id = :service_instance_id " + 29 | "and binding_id = :binding_id") 30 | Mono findByServiceInstanceIdAndBindingId( 31 | @Param("service_instance_id") String serviceInstanceId, 32 | @Param("binding_id") String bindingId); 33 | 34 | 35 | @Query("delete from service_instance_binding " + 36 | "where service_instance_id = :service_instance_id " + 37 | "and binding_id = :binding_id") 38 | Mono deleteByServiceInstanceIdAndBindingId( 39 | @Param("service_instance_id") String serviceInstanceId, 40 | @Param("binding_id") String bindingId); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/data/ServiceInstanceRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.data; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.data.r2dbc.repository.Query; 22 | import org.springframework.data.repository.query.Param; 23 | import org.springframework.data.repository.reactive.ReactiveCrudRepository; 24 | 25 | interface ServiceInstanceRepository extends ReactiveCrudRepository { 26 | 27 | @Query("select * from service_instance where service_instance_id = :service_instance_id") 28 | Mono findByServiceInstanceId(@Param("service_instance_id") String serviceInstanceId); 29 | 30 | @Query("delete from service_instance where service_instance_id = :service_instance_id") 31 | Mono deleteByServiceInstanceId(@Param("service_instance_id") String serviceInstanceId); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/services/NoOpCreateServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.services; 18 | 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | import reactor.core.publisher.Mono; 22 | 23 | import org.springframework.beans.factory.annotation.Value; 24 | import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow; 25 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest; 26 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse; 27 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse.CreateServiceInstanceResponseBuilder; 28 | 29 | /** 30 | * A no-op implementation of {@link CreateServiceInstanceWorkflow} 31 | */ 32 | public class NoOpCreateServiceInstanceWorkflow implements CreateServiceInstanceWorkflow { 33 | 34 | private static final Logger LOG = LoggerFactory.getLogger(NoOpCreateServiceInstanceWorkflow.class); 35 | 36 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 37 | private String backingServiceId; 38 | 39 | @Override 40 | public Mono create(CreateServiceInstanceRequest request, CreateServiceInstanceResponse response) { 41 | return Mono.empty(); 42 | } 43 | 44 | @Override 45 | public Mono accept(CreateServiceInstanceRequest request) { 46 | if (LOG.isInfoEnabled()) { 47 | LOG.info("Got request to create service instance: " + request); 48 | } 49 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 50 | } 51 | 52 | @Override 53 | public Mono buildResponse(CreateServiceInstanceRequest request, 54 | CreateServiceInstanceResponseBuilder responseBuilder) { 55 | if (LOG.isInfoEnabled()) { 56 | LOG.info("Got request to create service instance: " + request); 57 | } 58 | return Mono.just(responseBuilder); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/services/NoOpDeleteServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.beans.factory.annotation.Value; 22 | import org.springframework.cloud.appbroker.service.DeleteServiceInstanceWorkflow; 23 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceRequest; 24 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse; 25 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse.DeleteServiceInstanceResponseBuilder; 26 | 27 | /** 28 | * A no-op implementation of {@link DeleteServiceInstanceWorkflow} 29 | */ 30 | public class NoOpDeleteServiceInstanceWorkflow implements DeleteServiceInstanceWorkflow { 31 | 32 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 33 | private String backingServiceId; 34 | 35 | @Override 36 | public Mono delete(DeleteServiceInstanceRequest request, DeleteServiceInstanceResponse response) { 37 | return Mono.empty(); 38 | } 39 | 40 | @Override 41 | public Mono accept(DeleteServiceInstanceRequest request) { 42 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 43 | } 44 | 45 | @Override 46 | public Mono buildResponse(DeleteServiceInstanceRequest request, 47 | DeleteServiceInstanceResponseBuilder responseBuilder) { 48 | return Mono.just(responseBuilder); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/services/NoOpServiceInstanceBindingService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceAppBindingResponse; 22 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingRequest; 23 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingResponse; 24 | import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingRequest; 25 | import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingResponse; 26 | import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; 27 | 28 | /** 29 | * A no-op implementation of {@link ServiceInstanceBindingService} 30 | */ 31 | public class NoOpServiceInstanceBindingService implements ServiceInstanceBindingService { 32 | 33 | @Override 34 | public Mono createServiceInstanceBinding( 35 | CreateServiceInstanceBindingRequest request) { 36 | return Mono.just(CreateServiceInstanceAppBindingResponse.builder().build()); 37 | } 38 | 39 | @Override 40 | public Mono deleteServiceInstanceBinding( 41 | DeleteServiceInstanceBindingRequest request) { 42 | return Mono.just(DeleteServiceInstanceBindingResponse.builder().build()); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /state-repository/src/main/java/org/springframework/cloud/appbroker/samples/staterepository/services/NoOpUpdateServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.beans.factory.annotation.Value; 22 | import org.springframework.cloud.appbroker.service.UpdateServiceInstanceWorkflow; 23 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceRequest; 24 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse; 25 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse.UpdateServiceInstanceResponseBuilder; 26 | 27 | /** 28 | * A no-op implementation of {@link UpdateServiceInstanceWorkflow} 29 | */ 30 | public class NoOpUpdateServiceInstanceWorkflow implements UpdateServiceInstanceWorkflow { 31 | 32 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 33 | private String backingServiceId; 34 | 35 | @Override 36 | public Mono update(UpdateServiceInstanceRequest request, UpdateServiceInstanceResponse response) { 37 | return Mono.empty(); 38 | } 39 | 40 | @Override 41 | public Mono accept(UpdateServiceInstanceRequest request) { 42 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 43 | } 44 | 45 | @Override 46 | public Mono buildResponse(UpdateServiceInstanceRequest request, 47 | UpdateServiceInstanceResponseBuilder responseBuilder) { 48 | return Mono.just(responseBuilder); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /state-repository/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | openservicebroker: 4 | catalog: 5 | services: 6 | - id: example-service-id 7 | name: example 8 | description: A simple example 9 | bindable: true 10 | tags: 11 | - example 12 | tags 13 | plans: 14 | - id: standard-plan-id 15 | bindable: true 16 | name: standard 17 | description: A simple plan 18 | free: true 19 | 20 | appbroker: 21 | services: 22 | - service-name: example 23 | plan-name: standard 24 | apps: 25 | - name: example-service-app1 26 | path: classpath:demo.jar 27 | parameters-transformers: 28 | - name: EnvironmentMapping 29 | args: 30 | include: lang 31 | - name: PropertyMapping 32 | args: 33 | include: count,upgrade,memory 34 | - name: RequestTimeoutParameterTransformer 35 | 36 | deployer: 37 | cloudfoundry: 38 | api-host: api.sys.example.com 39 | api-port: 443 40 | username: admin 41 | password: adminpass 42 | default-org: test 43 | default-space: development 44 | 45 | logging: 46 | level: 47 | org: 48 | springframework: 49 | transaction: TRACE 50 | data: 51 | r2dbc: 52 | connectionfactory: DEBUG 53 | -------------------------------------------------------------------------------- /state-repository/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO service_instance (id, service_instance_id, description, operation_state) 2 | VALUES (2000, '1', 'CREATING', 'SUCCEEDED'); 3 | -------------------------------------------------------------------------------- /state-repository/src/main/resources/demo.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-app-broker-samples/e941b21c0171f8b4506600b8e892c471aaa2af80/state-repository/src/main/resources/demo.jar -------------------------------------------------------------------------------- /state-repository/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS service_instance ( 2 | id BIGINT PRIMARY KEY AUTO_INCREMENT, 3 | service_instance_id VARCHAR(36) UNIQUE NOT NULL, 4 | description VARCHAR(255), 5 | operation_state VARCHAR(50), 6 | last_updated datetime 7 | ); 8 | 9 | CREATE TABLE IF NOT EXISTS service_instance_binding ( 10 | id BIGINT PRIMARY KEY AUTO_INCREMENT, 11 | service_instance_id VARCHAR(36) NOT NULL, 12 | binding_id VARCHAR(36) NOT NULL, 13 | description VARCHAR(255), 14 | operation_state VARCHAR(50), 15 | last_updated DATETIME, 16 | UNIQUE (service_instance_id, binding_id) 17 | ); 18 | -------------------------------------------------------------------------------- /state-repository/src/test/java/org/springframework/cloud/appbroker/samples/staterepository/AppBrokerApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import org.springframework.boot.test.context.SpringBootTest; 22 | 23 | @SpringBootTest 24 | class AppBrokerApplicationTests { 25 | 26 | @Test 27 | void contextLoads() { 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /state-repository/src/test/java/org/springframework/cloud/appbroker/samples/staterepository/data/ServiceInstanceStateRepositoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.staterepository.data; 18 | 19 | import org.junit.jupiter.api.Test; 20 | import reactor.test.StepVerifier; 21 | 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.boot.test.context.SpringBootTest; 24 | import org.springframework.cloud.servicebroker.model.instance.OperationState; 25 | 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | @SpringBootTest 29 | class ServiceInstanceStateRepositoryTest { 30 | 31 | @Autowired 32 | private DefaultServiceInstanceStateRepository defaultServiceInstanceStateRepository; 33 | 34 | @Test 35 | void getState() { 36 | defaultServiceInstanceStateRepository.getState("1") 37 | .as(StepVerifier::create) 38 | .expectNextCount(1) 39 | .verifyComplete(); 40 | } 41 | 42 | @Test 43 | void getStateInstanceNotFound() { 44 | defaultServiceInstanceStateRepository.getState("abc123") 45 | .as(StepVerifier::create) 46 | .verifyErrorMessage("Unknown service instance ID abc123"); 47 | } 48 | 49 | @Test 50 | void saveState() { 51 | defaultServiceInstanceStateRepository.saveState("1", OperationState.IN_PROGRESS, "let's do this") 52 | .as(StepVerifier::create) 53 | .consumeNextWith(serviceInstanceState -> { 54 | assertThat(serviceInstanceState.getOperationState()).isEqualTo(OperationState.IN_PROGRESS); 55 | assertThat(serviceInstanceState.getDescription()).isEqualTo("let's do this"); 56 | }) 57 | .verifyComplete(); 58 | } 59 | 60 | @Test 61 | void saveStateInstanceNotFound() { 62 | defaultServiceInstanceStateRepository.saveState("2", OperationState.FAILED, "let's do this") 63 | .as(StepVerifier::create) 64 | .consumeNextWith(serviceInstanceState -> { 65 | assertThat(serviceInstanceState.getOperationState()).isEqualTo(OperationState.FAILED); 66 | assertThat(serviceInstanceState.getDescription()).isEqualTo("let's do this"); 67 | }) 68 | .verifyComplete(); 69 | } 70 | 71 | @Test 72 | void removeState() { 73 | defaultServiceInstanceStateRepository.saveState("99", OperationState.IN_PROGRESS, null) 74 | .then(defaultServiceInstanceStateRepository.removeState("99")) 75 | .as(StepVerifier::create) 76 | .expectNextCount(1) 77 | .verifyComplete(); 78 | } 79 | 80 | @Test 81 | void removeStateInstanceNotFound() { 82 | defaultServiceInstanceStateRepository.removeState("999") 83 | .as(StepVerifier::create) 84 | .verifyErrorMessage("Unknown service instance ID 999"); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /target-service/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | buildscript { 18 | repositories { 19 | mavenCentral() 20 | maven { url "https://plugins.gradle.org/m2/" } 21 | } 22 | 23 | dependencies { 24 | classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 25 | } 26 | } 27 | 28 | apply plugin: 'org.springframework.boot' 29 | 30 | dependencies { 31 | implementation "org.springframework.boot:spring-boot-starter-webflux" 32 | implementation "org.springframework.cloud:spring-cloud-starter-app-broker-cloudfoundry:${springCloudAppBrokerVersion}" 33 | 34 | testImplementation "io.projectreactor:reactor-test" 35 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 36 | exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /target-service/src/main/java/org/springframework/cloud/appbroker/samples/targetservice/AppBrokerApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.targetservice; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | 22 | @SuppressWarnings({"PMD.UseUtilityClass"}) 23 | @SpringBootApplication 24 | public class AppBrokerApplication { 25 | 26 | public static void main(String[] args) { 27 | SpringApplication.run(AppBrokerApplication.class, args); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /target-service/src/main/java/org/springframework/cloud/appbroker/samples/targetservice/AppBrokerApplicationConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.targetservice; 18 | 19 | import org.springframework.cloud.appbroker.samples.targetservice.services.NoOpCreateServiceInstanceWorkflow; 20 | import org.springframework.cloud.appbroker.samples.targetservice.services.NoOpDeleteServiceInstanceWorkflow; 21 | import org.springframework.cloud.appbroker.samples.targetservice.services.NoOpServiceInstanceBindingService; 22 | import org.springframework.cloud.appbroker.samples.targetservice.services.NoOpUpdateServiceInstanceWorkflow; 23 | import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow; 24 | import org.springframework.cloud.appbroker.service.DeleteServiceInstanceWorkflow; 25 | import org.springframework.cloud.appbroker.service.UpdateServiceInstanceWorkflow; 26 | import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.Configuration; 29 | 30 | @Configuration 31 | public class AppBrokerApplicationConfiguration { 32 | 33 | @Bean 34 | public CreateServiceInstanceWorkflow createServiceInstanceWorkflow() { 35 | return new NoOpCreateServiceInstanceWorkflow(); 36 | } 37 | 38 | @Bean 39 | public UpdateServiceInstanceWorkflow updateServiceInstanceWorkflow() { 40 | return new NoOpUpdateServiceInstanceWorkflow(); 41 | } 42 | 43 | @Bean 44 | public DeleteServiceInstanceWorkflow deleteServiceInstanceWorkflow() { 45 | return new NoOpDeleteServiceInstanceWorkflow(); 46 | } 47 | 48 | @Bean 49 | public ServiceInstanceBindingService serviceInstanceBindingService() { 50 | return new NoOpServiceInstanceBindingService(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /target-service/src/main/java/org/springframework/cloud/appbroker/samples/targetservice/CustomSpaceService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.targetservice; 18 | 19 | public class CustomSpaceService { 20 | 21 | String retrieveSpaceName() { 22 | return "customspace"; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /target-service/src/main/java/org/springframework/cloud/appbroker/samples/targetservice/CustomSpaceTarget.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.targetservice; 18 | 19 | import java.util.Map; 20 | 21 | import org.springframework.cloud.appbroker.deployer.DeploymentProperties; 22 | import org.springframework.cloud.appbroker.extensions.targets.ArtifactDetails; 23 | import org.springframework.cloud.appbroker.extensions.targets.Target; 24 | import org.springframework.cloud.appbroker.extensions.targets.TargetFactory; 25 | 26 | public class CustomSpaceTarget extends TargetFactory { 27 | 28 | private final CustomSpaceService customSpaceService; 29 | 30 | public CustomSpaceTarget(CustomSpaceService customSpaceService) { 31 | super(Config.class); 32 | this.customSpaceService = customSpaceService; 33 | } 34 | 35 | @Override 36 | public Target create(Config config) { 37 | return this::apply; 38 | } 39 | 40 | private ArtifactDetails apply(Map properties, String name, String serviceInstanceId) { 41 | String space = customSpaceService.retrieveSpaceName(); 42 | properties.put(DeploymentProperties.TARGET_PROPERTY_KEY, space); 43 | 44 | return ArtifactDetails.builder() 45 | .name(name) 46 | .properties(properties) 47 | .build(); 48 | } 49 | 50 | public static class Config { 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /target-service/src/main/java/org/springframework/cloud/appbroker/samples/targetservice/TargetServiceConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.targetservice; 18 | 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.Configuration; 21 | 22 | @Configuration 23 | public class TargetServiceConfiguration { 24 | 25 | @Bean 26 | public CustomSpaceService customSpaceService() { 27 | return new CustomSpaceService(); 28 | } 29 | 30 | @Bean 31 | public CustomSpaceTarget customSpaceTarget(CustomSpaceService customSpaceService) { 32 | return new CustomSpaceTarget(customSpaceService); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /target-service/src/main/java/org/springframework/cloud/appbroker/samples/targetservice/services/NoOpCreateServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.targetservice.services; 18 | 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | import reactor.core.publisher.Mono; 22 | 23 | import org.springframework.beans.factory.annotation.Value; 24 | import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow; 25 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest; 26 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse; 27 | import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse.CreateServiceInstanceResponseBuilder; 28 | 29 | /** 30 | * A no-op implementation of {@link CreateServiceInstanceWorkflow} 31 | */ 32 | public class NoOpCreateServiceInstanceWorkflow implements CreateServiceInstanceWorkflow { 33 | 34 | private static final Logger LOG = LoggerFactory.getLogger(NoOpCreateServiceInstanceWorkflow.class); 35 | 36 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 37 | private String backingServiceId; 38 | 39 | @Override 40 | public Mono create(CreateServiceInstanceRequest request, CreateServiceInstanceResponse response) { 41 | return Mono.empty(); 42 | } 43 | 44 | @Override 45 | public Mono accept(CreateServiceInstanceRequest request) { 46 | if (LOG.isInfoEnabled()) { 47 | LOG.info("Got request to create service instance: " + request); 48 | } 49 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 50 | } 51 | 52 | @Override 53 | public Mono buildResponse(CreateServiceInstanceRequest request, 54 | CreateServiceInstanceResponseBuilder responseBuilder) { 55 | if (LOG.isInfoEnabled()) { 56 | LOG.info("Got request to create service instance: " + request); 57 | } 58 | return Mono.just(responseBuilder); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /target-service/src/main/java/org/springframework/cloud/appbroker/samples/targetservice/services/NoOpDeleteServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.targetservice.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.beans.factory.annotation.Value; 22 | import org.springframework.cloud.appbroker.service.DeleteServiceInstanceWorkflow; 23 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceRequest; 24 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse; 25 | import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse.DeleteServiceInstanceResponseBuilder; 26 | 27 | /** 28 | * A no-op implementation of {@link DeleteServiceInstanceWorkflow} 29 | */ 30 | public class NoOpDeleteServiceInstanceWorkflow implements DeleteServiceInstanceWorkflow { 31 | 32 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 33 | private String backingServiceId; 34 | 35 | @Override 36 | public Mono delete(DeleteServiceInstanceRequest request, DeleteServiceInstanceResponse response) { 37 | return Mono.empty(); 38 | } 39 | 40 | @Override 41 | public Mono accept(DeleteServiceInstanceRequest request) { 42 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 43 | } 44 | 45 | @Override 46 | public Mono buildResponse(DeleteServiceInstanceRequest request, 47 | DeleteServiceInstanceResponseBuilder responseBuilder) { 48 | return Mono.just(responseBuilder); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /target-service/src/main/java/org/springframework/cloud/appbroker/samples/targetservice/services/NoOpServiceInstanceBindingService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.targetservice.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceAppBindingResponse; 22 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingRequest; 23 | import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingResponse; 24 | import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingRequest; 25 | import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingResponse; 26 | import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService; 27 | 28 | /** 29 | * A no-op implementation of {@link ServiceInstanceBindingService} 30 | */ 31 | public class NoOpServiceInstanceBindingService implements ServiceInstanceBindingService { 32 | 33 | @Override 34 | public Mono createServiceInstanceBinding( 35 | CreateServiceInstanceBindingRequest request) { 36 | return Mono.just(CreateServiceInstanceAppBindingResponse.builder().build()); 37 | } 38 | 39 | @Override 40 | public Mono deleteServiceInstanceBinding( 41 | DeleteServiceInstanceBindingRequest request) { 42 | return Mono.just(DeleteServiceInstanceBindingResponse.builder().build()); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /target-service/src/main/java/org/springframework/cloud/appbroker/samples/targetservice/services/NoOpUpdateServiceInstanceWorkflow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.targetservice.services; 18 | 19 | import reactor.core.publisher.Mono; 20 | 21 | import org.springframework.beans.factory.annotation.Value; 22 | import org.springframework.cloud.appbroker.service.UpdateServiceInstanceWorkflow; 23 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceRequest; 24 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse; 25 | import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse.UpdateServiceInstanceResponseBuilder; 26 | 27 | /** 28 | * A no-op implementation of {@link UpdateServiceInstanceWorkflow} 29 | */ 30 | public class NoOpUpdateServiceInstanceWorkflow implements UpdateServiceInstanceWorkflow { 31 | 32 | @Value("${spring.cloud.openservicebroker.catalog.services[0].id}") 33 | private String backingServiceId; 34 | 35 | @Override 36 | public Mono update(UpdateServiceInstanceRequest request, UpdateServiceInstanceResponse response) { 37 | return Mono.empty(); 38 | } 39 | 40 | @Override 41 | public Mono accept(UpdateServiceInstanceRequest request) { 42 | return Mono.just(request.getServiceDefinitionId().equals(backingServiceId)); 43 | } 44 | 45 | @Override 46 | public Mono buildResponse(UpdateServiceInstanceRequest request, 47 | UpdateServiceInstanceResponseBuilder responseBuilder) { 48 | return Mono.just(responseBuilder); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /target-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | openservicebroker: 4 | catalog: 5 | services: 6 | - id: example-service-id 7 | name: example 8 | description: A simple example 9 | bindable: true 10 | tags: 11 | - example 12 | tags 13 | plans: 14 | - id: standard-plan-id 15 | bindable: true 16 | name: standard 17 | description: A simple plan 18 | free: true 19 | 20 | appbroker: 21 | services: 22 | - service-name: example 23 | plan-name: standard 24 | apps: 25 | - name: example-service-app1 26 | path: classpath:demo.jar 27 | parameters-transformers: 28 | - name: EnvironmentMapping 29 | args: 30 | include: lang 31 | - name: PropertyMapping 32 | args: 33 | include: count,upgrade,memory 34 | - name: RequestTimeoutParameterTransformer 35 | 36 | deployer: 37 | cloudfoundry: 38 | api-host: api.sys.example.com 39 | api-port: 443 40 | username: admin 41 | password: adminpass 42 | default-org: test 43 | default-space: development 44 | -------------------------------------------------------------------------------- /target-service/src/main/resources/demo.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-app-broker-samples/e941b21c0171f8b4506600b8e892c471aaa2af80/target-service/src/main/resources/demo.jar -------------------------------------------------------------------------------- /target-service/src/test/java/org/springframework/cloud/appbroker/samples/targetservice/AppBrokerApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.appbroker.samples.targetservice; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import org.springframework.boot.test.context.SpringBootTest; 22 | 23 | @SpringBootTest 24 | class AppBrokerApplicationTests { 25 | 26 | @Test 27 | void contextLoads() { 28 | } 29 | 30 | } 31 | --------------------------------------------------------------------------------