Enforce Spring formatting and style rules
- Add PMD checks and resolve failing rules - Apply Spring Checkstyle rules based on Spring Framework - Rearrange imports to be more consistent - Format whitespace
This commit is contained in:
committed by
Roy Clarkson
parent
cd1e1d628f
commit
b0c71e52de
@@ -1,7 +1,7 @@
|
||||
[*]
|
||||
charset=utf-8
|
||||
end_of_line=lf
|
||||
insert_final_newline=false
|
||||
insert_final_newline=true
|
||||
indent_style=tab
|
||||
indent_size=4
|
||||
|
||||
|
||||
157
build.gradle
157
build.gradle
@@ -27,12 +27,38 @@ buildscript {
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
springBootVersion = project.findProperty("springBootVersion") ?: "2.1.10.RELEASE"
|
||||
springFrameworkVersion = project.findProperty("springFrameworkVersion") ?: "5.1.11.RELEASE"
|
||||
reactorVersion = project.findProperty("reactorVersion") ?: "Californium-SR13"
|
||||
openServiceBrokerVersion = "3.0.4.RELEASE"
|
||||
springCredhubVersion = "2.0.1.RELEASE"
|
||||
cfJavaClientVersion = "3.16.0.RELEASE"
|
||||
checkstyleVersion = "8.21"
|
||||
pmdVersion = "6.19.0"
|
||||
|
||||
javadocLinks = [
|
||||
"https://docs.oracle.com/javase/8/docs/api/",
|
||||
"https://docs.spring.io/spring/docs/${springFrameworkVersion}/javadoc-api/",
|
||||
] as String[]
|
||||
}
|
||||
|
||||
//override managed Spring Boot versions
|
||||
if (project.hasProperty("springFrameworkVersion")) {
|
||||
ext['spring-framework.version'] = ext.springFrameworkVersion
|
||||
}
|
||||
if (project.hasProperty("reactorVersion")) {
|
||||
ext['reactor-bom.version'] = ext.reactorVersion
|
||||
}
|
||||
|
||||
// NoHttp has to be applied at the root level
|
||||
// so that it reads all the root files, including the gradle ones.
|
||||
apply plugin: "io.spring.nohttp"
|
||||
|
||||
// nohttp requires a valid checkstyle configuration
|
||||
checkstyle {
|
||||
toolVersion = 8.16
|
||||
configFile = file("${project.rootDir}/src/checkstyle/checkstyle-nohttp.xml")
|
||||
toolVersion = "${checkstyleVersion}"
|
||||
}
|
||||
|
||||
configure(allprojects) {
|
||||
@@ -49,22 +75,7 @@ configure(allprojects) {
|
||||
apply plugin: "propdeps-eclipse"
|
||||
apply plugin: "io.spring.dependency-management"
|
||||
|
||||
ext {
|
||||
springBootVersion = project.findProperty("springBootVersion") ?: "2.1.10.RELEASE"
|
||||
springVersion = project.findProperty("springFrameworkVersion") ?: "5.1.11.RELEASE"
|
||||
reactorVersion = project.findProperty("reactorVersion") ?: "Californium-SR13"
|
||||
openServiceBrokerVersion = "3.0.4.RELEASE"
|
||||
springCredhubVersion = "2.0.1.RELEASE"
|
||||
cfJavaClientVersion = "3.16.0.RELEASE"
|
||||
}
|
||||
|
||||
//override managed Spring Boot versions
|
||||
if (project.hasProperty("springFrameworkVersion")) {
|
||||
ext['spring-framework.version'] = ext.springFrameworkVersion
|
||||
}
|
||||
if (project.hasProperty("reactorVersion")) {
|
||||
ext['reactor-bom.version'] = ext.reactorVersion
|
||||
}
|
||||
apply from: "${rootProject.projectDir}/publish-maven.gradle"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@@ -80,51 +91,36 @@ configure(allprojects) {
|
||||
maven { url "https://repo.spring.io/libs-snapshot" }
|
||||
}
|
||||
}
|
||||
|
||||
ext.javadocLinks = [
|
||||
"https://docs.oracle.com/javase/8/docs/api/",
|
||||
"https://docs.spring.io/spring/docs/${springFrameworkVersion}/javadoc-api/",
|
||||
] as String[]
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply from: "${rootProject.projectDir}/publish-maven.gradle"
|
||||
}
|
||||
configure(allprojects - [project(":spring-cloud-app-broker-docs")]) {
|
||||
apply plugin: "checkstyle"
|
||||
apply plugin: "pmd"
|
||||
|
||||
configure(subprojects - [project(":spring-cloud-starter-app-broker"),
|
||||
project(":spring-cloud-starter-app-broker-cloudfoundry")]) {
|
||||
compileJava {
|
||||
sourceCompatibility=1.8
|
||||
targetCompatibility=1.8
|
||||
options.encoding = "UTF-8"
|
||||
checkstyle {
|
||||
configFile = file("${project.rootDir}/src/checkstyle/checkstyle.xml")
|
||||
toolVersion = "${checkstyleVersion}"
|
||||
}
|
||||
compileTestJava {
|
||||
sourceCompatibility=1.8
|
||||
targetCompatibility=1.8
|
||||
options.encoding = "UTF-8"
|
||||
checkstyleMain {
|
||||
source = "src/main/java"
|
||||
}
|
||||
checkstyleTest {
|
||||
source = "src/test/java"
|
||||
}
|
||||
|
||||
[compileJava, compileTestJava]*.options*.compilerArgs = [
|
||||
"-Xlint:serial",
|
||||
"-Xlint:varargs",
|
||||
"-Xlint:cast",
|
||||
"-Xlint:classfile",
|
||||
"-Xlint:dep-ann",
|
||||
"-Xlint:divzero",
|
||||
"-Xlint:empty",
|
||||
"-Xlint:finally",
|
||||
"-Xlint:overrides",
|
||||
"-Xlint:path",
|
||||
"-Xlint:-processing",
|
||||
"-Xlint:static",
|
||||
"-Xlint:try",
|
||||
"-Xlint:fallthrough",
|
||||
"-Xlint:rawtypes",
|
||||
"-Xlint:deprecation",
|
||||
"-Xlint:unchecked",
|
||||
"-Xlint:-options",
|
||||
"-Werror"
|
||||
]
|
||||
pmd {
|
||||
toolVersion = "${pmdVersion}"
|
||||
}
|
||||
pmdMain {
|
||||
ruleSets = []
|
||||
ruleSetFiles = files("${project.rootDir}/src/pmd/pmdRuleSet.xml")
|
||||
source = "src/main/java"
|
||||
}
|
||||
pmdTest {
|
||||
ruleSets = []
|
||||
ruleSetFiles = files("${project.rootDir}/src/pmd/pmdTestRuleSet.xml")
|
||||
source = "src/test/java"
|
||||
}
|
||||
|
||||
test {
|
||||
// enable JUnit 5
|
||||
@@ -160,21 +156,41 @@ configure(subprojects - [project(":spring-cloud-starter-app-broker"),
|
||||
afterSuite {
|
||||
failedTests.each { test -> println "FAILED test: ${test.className} > ${test.name}" }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pmd {
|
||||
ruleSetFiles = files("${project.rootDir}/ci/config/pmdRuleSet.xml")
|
||||
}
|
||||
subprojects {
|
||||
task allDependencyInsight(type: DependencyInsightReportTask)
|
||||
task dependencyReport(type: DependencyReportTask)
|
||||
}
|
||||
|
||||
pmdTest {
|
||||
ruleSetFiles = files("${project.rootDir}/ci/config/pmdTestRuleSet.xml")
|
||||
}
|
||||
configure(subprojects - [project(":spring-cloud-starter-app-broker"),
|
||||
project(":spring-cloud-starter-app-broker-cloudfoundry")]) {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
[compileJava, compileTestJava]*.options*.encoding = "UTF-8"
|
||||
|
||||
checkstyle {
|
||||
configDir = file("${project.rootDir}/ci/config/")
|
||||
toolVersion = 8.16
|
||||
}
|
||||
[compileJava, compileTestJava]*.options*.compilerArgs = [
|
||||
"-Xlint:serial",
|
||||
"-Xlint:varargs",
|
||||
"-Xlint:cast",
|
||||
"-Xlint:classfile",
|
||||
"-Xlint:dep-ann",
|
||||
"-Xlint:divzero",
|
||||
"-Xlint:empty",
|
||||
"-Xlint:finally",
|
||||
"-Xlint:overrides",
|
||||
"-Xlint:path",
|
||||
"-Xlint:-processing",
|
||||
"-Xlint:static",
|
||||
"-Xlint:try",
|
||||
"-Xlint:fallthrough",
|
||||
"-Xlint:rawtypes",
|
||||
"-Xlint:deprecation",
|
||||
"-Xlint:unchecked",
|
||||
"-Xlint:-options",
|
||||
"-Werror"
|
||||
]
|
||||
|
||||
jar {
|
||||
manifest.attributes["Created-By"] =
|
||||
@@ -196,7 +212,7 @@ configure(subprojects - [project(":spring-cloud-starter-app-broker"),
|
||||
options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
|
||||
options.author = true
|
||||
options.header = project.name
|
||||
options.links(project.ext.javadocLinks)
|
||||
options.links(javadocLinks)
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
}
|
||||
|
||||
@@ -220,9 +236,6 @@ configure(subprojects - [project(":spring-cloud-starter-app-broker"),
|
||||
// exclude JUnit 4 globally, in favor of JUnit 5
|
||||
testImplementation.exclude group: "junit", module: "junit"
|
||||
}
|
||||
|
||||
task allDependencyInsight(type: DependencyInsightReportTask) {}
|
||||
task allDependencies(type: DependencyReportTask) {}
|
||||
}
|
||||
|
||||
configure(rootProject) {
|
||||
@@ -242,7 +255,7 @@ configure(rootProject) {
|
||||
options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
|
||||
options.author = true
|
||||
options.header = rootProject.description
|
||||
options.links(project.ext.javadocLinks)
|
||||
options.links(javadocLinks)
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
|
||||
source subprojects.collect { project ->
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="Custom ruleset"
|
||||
xmlns="https://pmd.sourceforge.net/ruleset/2.0.0"
|
||||
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
|
||||
|
||||
<rule ref="rulesets/java/basic.xml"/>
|
||||
<rule ref="rulesets/java/braces.xml"/>
|
||||
<rule ref="rulesets/java/codesize.xml">
|
||||
<exclude name="TooManyMethods"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/design.xml">
|
||||
<exclude name="UseUtilityClass"/>
|
||||
<exclude name="AccessorMethodGeneration"/>
|
||||
<exclude name="UncommentedEmptyConstructor"/>
|
||||
<exclude name="UncommentedEmptyMethodBody"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/empty.xml"/>
|
||||
<rule ref="rulesets/java/finalizers.xml"/>
|
||||
<rule ref="rulesets/java/naming.xml">
|
||||
<exclude name="ShortVariable" />
|
||||
<exclude name="LongVariable" />
|
||||
<exclude name="ShortMethodName" />
|
||||
<exclude name="ShortClassName" />
|
||||
<exclude name="AbstractNaming" />
|
||||
<exclude name="AvoidFieldNameMatchingMethodName" />
|
||||
</rule>
|
||||
<rule ref="rulesets/java/imports.xml"/>
|
||||
<rule ref="rulesets/java/imports.xml/TooManyStaticImports">
|
||||
<properties>
|
||||
<property name="maximumStaticImports" value="0"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/optimizations.xml">
|
||||
<exclude name="LocalVariableCouldBeFinal"/>
|
||||
<exclude name="MethodArgumentCouldBeFinal"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/strictexception.xml"/>
|
||||
<rule ref="rulesets/java/strings.xml"/>
|
||||
<rule ref="rulesets/java/typeresolution.xml"/>
|
||||
<rule ref="rulesets/java/unnecessary.xml"/>
|
||||
<rule ref="rulesets/java/unusedcode.xml" />
|
||||
|
||||
<!--
|
||||
<rule ref="rulesets/java/comments.xml"/>
|
||||
<rule ref="rulesets/java/controversial.xml"/>
|
||||
<rule ref="rulesets/java/junit.xml" />
|
||||
-->
|
||||
</ruleset>
|
||||
@@ -1,76 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
~ Copyright 2002-2019 the original author or authors.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ https://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<ruleset name="Custom ruleset"
|
||||
xmlns="https://pmd.sourceforge.net/ruleset/2.0.0"
|
||||
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
|
||||
|
||||
<rule ref="rulesets/java/basic.xml"/>
|
||||
<rule ref="rulesets/java/braces.xml">
|
||||
<exclude name="IfStmtsMustUseBraces"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/codesize.xml">
|
||||
<exclude name="TooManyMethods"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/design.xml">
|
||||
<exclude name="UncommentedEmptyMethodBody"/>
|
||||
<exclude name="AbstractClassWithoutAbstractMethod"/>
|
||||
<exclude name="NonStaticInitializer"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/design.xml">
|
||||
<exclude name="AbstractClassWithoutAbstractMethod"/>
|
||||
<exclude name="NonStaticInitializer"/>
|
||||
<exclude name="UncommentedEmptyConstructor"/>
|
||||
<exclude name="UncommentedEmptyMethodBody"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/empty.xml" />
|
||||
<rule ref="rulesets/java/finalizers.xml" />
|
||||
<rule ref="rulesets/java/imports.xml">
|
||||
<exclude name="TooManyStaticImports"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/junit.xml">
|
||||
<exclude name="JUnitTestContainsTooManyAsserts"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/naming.xml">
|
||||
<exclude name="LongVariable" />
|
||||
<exclude name="ShortVariable" />
|
||||
<exclude name="ShortMethodName" />
|
||||
<exclude name="AbstractNaming"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/optimizations.xml">
|
||||
<exclude name="LocalVariableCouldBeFinal"/>
|
||||
<exclude name="MethodArgumentCouldBeFinal"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/strictexception.xml">
|
||||
<exclude name="AvoidThrowingRawExceptionTypes"/>
|
||||
<exclude name="SignatureDeclareThrowsException"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/strings.xml">
|
||||
<exclude name="AvoidDuplicateLiterals"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/typeresolution.xml">
|
||||
<exclude name="SignatureDeclareThrowsException"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/unnecessary.xml" />
|
||||
<rule ref="rulesets/java/unusedcode.xml" />
|
||||
|
||||
<!--
|
||||
<rule ref="rulesets/java/comments.xml"/>
|
||||
<rule ref="rulesets/java/controversial.xml"/>
|
||||
-->
|
||||
</ruleset>
|
||||
@@ -18,11 +18,69 @@ package org.springframework.cloud.appbroker.acceptance;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.appbroker.acceptance.services.NoOpCreateServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.appbroker.acceptance.services.NoOpDeleteServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.appbroker.acceptance.services.NoOpServiceInstanceBindingService;
|
||||
import org.springframework.cloud.appbroker.acceptance.services.NoOpUpdateServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.appbroker.service.DeleteServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.appbroker.service.UpdateServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* A Spring Boot application for running acceptance tests
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class AppBrokerApplication {
|
||||
|
||||
/**
|
||||
* main application entry point
|
||||
*
|
||||
* @param args the args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AppBrokerApplication.class, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* A no-op CreateServiceInstanceWorkflow bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public CreateServiceInstanceWorkflow createServiceInstanceWorkflow() {
|
||||
return new NoOpCreateServiceInstanceWorkflow();
|
||||
}
|
||||
|
||||
/**
|
||||
* A no-op UpdateServiceInstanceWorkflow bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public UpdateServiceInstanceWorkflow updateServiceInstanceWorkflow() {
|
||||
return new NoOpUpdateServiceInstanceWorkflow();
|
||||
}
|
||||
|
||||
/**
|
||||
* A no-op DeleteServiceInstanceWorkflow bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public DeleteServiceInstanceWorkflow deleteServiceInstanceWorkflow() {
|
||||
return new NoOpDeleteServiceInstanceWorkflow();
|
||||
}
|
||||
|
||||
/**
|
||||
* A no-op ServiceInstanceBindingService bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public ServiceInstanceBindingService serviceInstanceBindingService() {
|
||||
return new NoOpServiceInstanceBindingService();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,36 +23,69 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* A controller for testing the {@link BackingAppManagementService}
|
||||
*/
|
||||
@RestController
|
||||
public class ManagementController {
|
||||
|
||||
private final BackingAppManagementService service;
|
||||
|
||||
/**
|
||||
* Construct a new {@literal ManagementController}
|
||||
*
|
||||
* @param service the service to test
|
||||
*/
|
||||
public ManagementController(BackingAppManagementService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests service start
|
||||
*
|
||||
* @param serviceInstanceId the id of the service to test
|
||||
* @return a response
|
||||
*/
|
||||
@GetMapping("/start/{serviceInstanceId}")
|
||||
public Mono<String> startApplications(@PathVariable String serviceInstanceId) {
|
||||
return service.start(serviceInstanceId)
|
||||
.thenReturn("starting " + serviceInstanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests service stop
|
||||
*
|
||||
* @param serviceInstanceId the id of the service to test
|
||||
* @return a response
|
||||
*/
|
||||
@GetMapping("/stop/{serviceInstanceId}")
|
||||
public Mono<String> stopApplications(@PathVariable String serviceInstanceId) {
|
||||
return service.stop(serviceInstanceId)
|
||||
.thenReturn("stopping " + serviceInstanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests service restart
|
||||
*
|
||||
* @param serviceInstanceId the id of the service to test
|
||||
* @return a response
|
||||
*/
|
||||
@GetMapping("/restart/{serviceInstanceId}")
|
||||
public Mono<String> restartApplications(@PathVariable String serviceInstanceId) {
|
||||
return service.restart(serviceInstanceId)
|
||||
.thenReturn("restarting " + serviceInstanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests service restage
|
||||
*
|
||||
* @param serviceInstanceId the id of the service to test
|
||||
* @return a response
|
||||
*/
|
||||
@GetMapping("/restage/{serviceInstanceId}")
|
||||
public Mono<String> restageApplications(@PathVariable String serviceInstanceId) {
|
||||
return service.restage(serviceInstanceId)
|
||||
.thenReturn("restaging " + serviceInstanceId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,17 +18,20 @@ package org.springframework.cloud.appbroker.acceptance.services;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest;
|
||||
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse;
|
||||
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse.CreateServiceInstanceResponseBuilder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Service
|
||||
/**
|
||||
* A no-op implementation of {@link CreateServiceInstanceWorkflow}
|
||||
*/
|
||||
public class NoOpCreateServiceInstanceWorkflow implements CreateServiceInstanceWorkflow {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NoOpCreateServiceInstanceWorkflow.class);
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(NoOpCreateServiceInstanceWorkflow.class);
|
||||
|
||||
@Value("${spring.cloud.openservicebroker.catalog.services[1].id}")
|
||||
private String backingServiceId;
|
||||
@@ -40,14 +43,19 @@ public class NoOpCreateServiceInstanceWorkflow implements CreateServiceInstanceW
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> accept(CreateServiceInstanceRequest request) {
|
||||
LOGGER.info("Got request to create service instance: " + request);
|
||||
if (LOG.isInfoEnabled()) {
|
||||
LOG.info("Got request to create service instance: " + request);
|
||||
}
|
||||
return Mono.just(request.getServiceDefinitionId().equals(backingServiceId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<CreateServiceInstanceResponseBuilder> buildResponse(CreateServiceInstanceRequest request,
|
||||
CreateServiceInstanceResponseBuilder responseBuilder) {
|
||||
LOGGER.info("Got request to create service instance: " + request);
|
||||
CreateServiceInstanceResponseBuilder responseBuilder) {
|
||||
if (LOG.isInfoEnabled()) {
|
||||
LOG.info("Got request to create service instance: " + request);
|
||||
}
|
||||
return Mono.just(responseBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,16 +16,19 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.acceptance.services;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.appbroker.service.DeleteServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceRequest;
|
||||
import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse;
|
||||
import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse.DeleteServiceInstanceResponseBuilder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Service
|
||||
/**
|
||||
* A no-op implementation of {@link DeleteServiceInstanceWorkflow}
|
||||
*/
|
||||
public class NoOpDeleteServiceInstanceWorkflow implements DeleteServiceInstanceWorkflow {
|
||||
|
||||
@Value("${spring.cloud.openservicebroker.catalog.services[1].id}")
|
||||
private String backingServiceId;
|
||||
|
||||
@@ -41,7 +44,8 @@ public class NoOpDeleteServiceInstanceWorkflow implements DeleteServiceInstanceW
|
||||
|
||||
@Override
|
||||
public Mono<DeleteServiceInstanceResponseBuilder> buildResponse(DeleteServiceInstanceRequest request,
|
||||
DeleteServiceInstanceResponseBuilder responseBuilder) {
|
||||
DeleteServiceInstanceResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,24 +16,30 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.acceptance.services;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceAppBindingResponse;
|
||||
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingRequest;
|
||||
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingResponse;
|
||||
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingRequest;
|
||||
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingResponse;
|
||||
import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Service
|
||||
/**
|
||||
* A no-op implementation of {@link ServiceInstanceBindingService}
|
||||
*/
|
||||
public class NoOpServiceInstanceBindingService implements ServiceInstanceBindingService {
|
||||
|
||||
@Override
|
||||
public Mono<CreateServiceInstanceBindingResponse> createServiceInstanceBinding(CreateServiceInstanceBindingRequest request) {
|
||||
public Mono<CreateServiceInstanceBindingResponse> createServiceInstanceBinding(
|
||||
CreateServiceInstanceBindingRequest request) {
|
||||
return Mono.just(CreateServiceInstanceAppBindingResponse.builder().build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<DeleteServiceInstanceBindingResponse> deleteServiceInstanceBinding(DeleteServiceInstanceBindingRequest request) {
|
||||
public Mono<DeleteServiceInstanceBindingResponse> deleteServiceInstanceBinding(
|
||||
DeleteServiceInstanceBindingRequest request) {
|
||||
return Mono.just(DeleteServiceInstanceBindingResponse.builder().build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,16 +16,19 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.acceptance.services;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.appbroker.service.UpdateServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceRequest;
|
||||
import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse;
|
||||
import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse.UpdateServiceInstanceResponseBuilder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Service
|
||||
/**
|
||||
* A no-op implementation of {@link UpdateServiceInstanceWorkflow}
|
||||
*/
|
||||
public class NoOpUpdateServiceInstanceWorkflow implements UpdateServiceInstanceWorkflow {
|
||||
|
||||
@Value("${spring.cloud.openservicebroker.catalog.services[1].id}")
|
||||
private String backingServiceId;
|
||||
|
||||
@@ -41,7 +44,8 @@ public class NoOpUpdateServiceInstanceWorkflow implements UpdateServiceInstanceW
|
||||
|
||||
@Override
|
||||
public Mono<UpdateServiceInstanceResponseBuilder> buildResponse(UpdateServiceInstanceRequest request,
|
||||
UpdateServiceInstanceResponseBuilder responseBuilder) {
|
||||
UpdateServiceInstanceResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.cloud.appbroker.acceptance;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(value = "tests")
|
||||
@ConfigurationProperties("tests")
|
||||
public class AcceptanceTestProperties {
|
||||
|
||||
private String brokerAppPath;
|
||||
@@ -32,11 +32,14 @@ class AppManagementRestageAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
private static final String SUFFIX = "app-management-restage";
|
||||
|
||||
private static final String APP_1 = "app-1-" + SUFFIX;
|
||||
|
||||
private static final String APP_2 = "app-2" + SUFFIX;
|
||||
|
||||
private static final String SI_NAME = "si-managed" + SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Override
|
||||
protected String testSuffix() {
|
||||
@@ -56,23 +59,23 @@ class AppManagementRestageAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
StepVerifier.create(cloudFoundryService.deleteServiceInstance(SI_NAME))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(cloudFoundryService.createServiceInstance(PLAN_NAME, APP_SERVICE_NAME, SI_NAME, null))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(cloudFoundryService.getServiceInstance(SI_NAME))
|
||||
.assertNext(serviceInstance -> assertThat(serviceInstance.getStatus()).isEqualTo("succeeded"))
|
||||
.verifyComplete();
|
||||
.assertNext(serviceInstance -> assertThat(serviceInstance.getStatus()).isEqualTo("succeeded"))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanUp() {
|
||||
StepVerifier.create(cloudFoundryService.deleteServiceInstance(SI_NAME))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(getApplications(APP_1, APP_2))
|
||||
.verifyError();
|
||||
.verifyError();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -91,8 +94,8 @@ class AppManagementRestageAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
assertThat(apps).extracting("runningInstances").containsOnly(1);
|
||||
|
||||
StepVerifier.create(manageApps(SI_NAME, "restage"))
|
||||
.assertNext(result -> assertThat(result).contains("restaging"))
|
||||
.verifyComplete();
|
||||
.assertNext(result -> assertThat(result).contains("restaging"))
|
||||
.verifyComplete();
|
||||
|
||||
List<ApplicationDetail> restagedApps = getApplications(APP_1, APP_2).block();
|
||||
Date since1 = restagedApps.get(0).getInstanceDetails().get(0).getSince();
|
||||
@@ -102,4 +105,4 @@ class AppManagementRestageAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
assertThat(since2).isAfter(originallySince2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -32,11 +32,14 @@ class AppManagementRestartAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
private static final String SUFFIX = "app-management-restart";
|
||||
|
||||
private static final String APP_1 = "app-1-" + SUFFIX;
|
||||
|
||||
private static final String APP_2 = "app-2" + SUFFIX;
|
||||
|
||||
private static final String SI_NAME = "si-managed" + SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Override
|
||||
protected String testSuffix() {
|
||||
@@ -56,23 +59,23 @@ class AppManagementRestartAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
StepVerifier.create(cloudFoundryService.deleteServiceInstance(SI_NAME))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(cloudFoundryService.createServiceInstance(PLAN_NAME, APP_SERVICE_NAME, SI_NAME, null))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(cloudFoundryService.getServiceInstance(SI_NAME))
|
||||
.assertNext(serviceInstance -> assertThat(serviceInstance.getStatus()).isEqualTo("succeeded"))
|
||||
.verifyComplete();
|
||||
.assertNext(serviceInstance -> assertThat(serviceInstance.getStatus()).isEqualTo("succeeded"))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanUp() {
|
||||
StepVerifier.create(cloudFoundryService.deleteServiceInstance(SI_NAME))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(getApplications(APP_1, APP_2))
|
||||
.verifyError();
|
||||
.verifyError();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,8 +93,8 @@ class AppManagementRestartAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
Date originallySince2 = apps.get(1).getInstanceDetails().get(0).getSince();
|
||||
|
||||
StepVerifier.create(manageApps(SI_NAME, "restart"))
|
||||
.assertNext(result -> assertThat(result).contains("restarting"))
|
||||
.verifyComplete();
|
||||
.assertNext(result -> assertThat(result).contains("restarting"))
|
||||
.verifyComplete();
|
||||
|
||||
List<ApplicationDetail> restagedApps = getApplications(APP_1, APP_2).block();
|
||||
Date since1 = restagedApps.get(0).getInstanceDetails().get(0).getSince();
|
||||
@@ -101,4 +104,4 @@ class AppManagementRestartAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
assertThat(since2).isAfter(originallySince2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -28,11 +28,14 @@ class AppManagementStartAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
private static final String SUFFIX = "app-management-start";
|
||||
|
||||
private static final String APP_1 = "app-1-" + SUFFIX;
|
||||
|
||||
private static final String APP_2 = "app-2" + SUFFIX;
|
||||
|
||||
private static final String SI_NAME = "si-managed" + SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Override
|
||||
protected String testSuffix() {
|
||||
@@ -52,23 +55,23 @@ class AppManagementStartAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
StepVerifier.create(cloudFoundryService.deleteServiceInstance(SI_NAME))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(cloudFoundryService.createServiceInstance(PLAN_NAME, APP_SERVICE_NAME, SI_NAME, null))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(cloudFoundryService.getServiceInstance(SI_NAME))
|
||||
.assertNext(serviceInstance -> assertThat(serviceInstance.getStatus()).isEqualTo("succeeded"))
|
||||
.verifyComplete();
|
||||
.assertNext(serviceInstance -> assertThat(serviceInstance.getStatus()).isEqualTo("succeeded"))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanUp() {
|
||||
StepVerifier.create(cloudFoundryService.deleteServiceInstance(SI_NAME))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(getApplications(APP_1, APP_2))
|
||||
.verifyError();
|
||||
.verifyError();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -82,19 +85,20 @@ class AppManagementStartAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
})
|
||||
void startApps() {
|
||||
StepVerifier.create(cloudFoundryService.stopApplication(APP_1)
|
||||
.then(cloudFoundryService.stopApplication(APP_2)))
|
||||
.verifyComplete();
|
||||
.then(cloudFoundryService.stopApplication(APP_2)))
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(getApplications(APP_1, APP_2))
|
||||
.assertNext(apps -> assertThat(apps).extracting("runningInstances").containsOnly(0))
|
||||
.verifyComplete();
|
||||
.assertNext(apps -> assertThat(apps).extracting("runningInstances").containsOnly(0))
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(manageApps(SI_NAME, "start"))
|
||||
.assertNext(result -> assertThat(result).contains("starting"))
|
||||
.verifyComplete();
|
||||
.assertNext(result -> assertThat(result).contains("starting"))
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(getApplications(APP_1, APP_2))
|
||||
.assertNext(apps -> assertThat(apps).extracting("runningInstances").containsOnly(1))
|
||||
.verifyComplete();
|
||||
.assertNext(apps -> assertThat(apps).extracting("runningInstances").containsOnly(1))
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,11 +28,14 @@ class AppManagementStopAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
private static final String SUFFIX = "app-management-stop";
|
||||
|
||||
private static final String APP_1 = "app-1-" + SUFFIX;
|
||||
|
||||
private static final String APP_2 = "app-2" + SUFFIX;
|
||||
|
||||
private static final String SI_NAME = "si-managed" + SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Override
|
||||
protected String testSuffix() {
|
||||
@@ -52,23 +55,23 @@ class AppManagementStopAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
StepVerifier.create(cloudFoundryService.deleteServiceInstance(SI_NAME))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(cloudFoundryService.createServiceInstance(PLAN_NAME, APP_SERVICE_NAME, SI_NAME, null))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(cloudFoundryService.getServiceInstance(SI_NAME))
|
||||
.assertNext(serviceInstance -> assertThat(serviceInstance.getStatus()).isEqualTo("succeeded"))
|
||||
.verifyComplete();
|
||||
.assertNext(serviceInstance -> assertThat(serviceInstance.getStatus()).isEqualTo("succeeded"))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanUp() {
|
||||
StepVerifier.create(cloudFoundryService.deleteServiceInstance(SI_NAME))
|
||||
.verifyComplete();
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(getApplications(APP_1, APP_2))
|
||||
.verifyError();
|
||||
.verifyError();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -82,11 +85,12 @@ class AppManagementStopAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
})
|
||||
void stopApps() {
|
||||
StepVerifier.create(manageApps(SI_NAME, "stop"))
|
||||
.assertNext(result -> assertThat(result).contains("stopping"))
|
||||
.verifyComplete();
|
||||
.assertNext(result -> assertThat(result).contains("stopping"))
|
||||
.verifyComplete();
|
||||
|
||||
StepVerifier.create(getApplications(APP_1, APP_2))
|
||||
.assertNext(apps -> assertThat(apps).extracting("runningInstances").containsOnly(0))
|
||||
.verifyComplete();
|
||||
.assertNext(apps -> assertThat(apps).extracting("runningInstances").containsOnly(0))
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,15 +16,27 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.acceptance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
class BrokerProperties {
|
||||
|
||||
private final String[] properties;
|
||||
private final List<String> properties = new ArrayList<>();
|
||||
|
||||
BrokerProperties(String... properties) {
|
||||
this.properties = properties;
|
||||
public BrokerProperties(List<String> properties) {
|
||||
if (!CollectionUtils.isEmpty(properties)) {
|
||||
this.properties.addAll(properties);
|
||||
}
|
||||
}
|
||||
|
||||
String[] getProperties() {
|
||||
public BrokerProperties(String... properties) {
|
||||
this(Arrays.asList(properties));
|
||||
}
|
||||
|
||||
public List<String> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.cloud.appbroker.acceptance;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||
@@ -25,13 +26,17 @@ import org.junit.jupiter.api.extension.ParameterResolver;
|
||||
|
||||
class BrokerPropertiesParameterResolver implements ParameterResolver {
|
||||
|
||||
@SuppressWarnings("PMD.AvoidUncheckedExceptionsInSignatures")
|
||||
@Override
|
||||
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
|
||||
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
|
||||
throws ParameterResolutionException {
|
||||
return parameterContext.getParameter().getType() == BrokerProperties.class;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AvoidUncheckedExceptionsInSignatures")
|
||||
@Override
|
||||
public BrokerProperties resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
|
||||
public BrokerProperties resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
|
||||
throws ParameterResolutionException {
|
||||
String[] properties = getValueHolderProperties(extensionContext);
|
||||
return new BrokerProperties(properties);
|
||||
}
|
||||
@@ -40,7 +45,7 @@ class BrokerPropertiesParameterResolver implements ParameterResolver {
|
||||
Optional<Method> testInstance = extensionContext.getTestMethod();
|
||||
return testInstance
|
||||
.map(method -> method.getAnnotation(AppBrokerTestProperties.class).value())
|
||||
.orElseGet(() -> new String[]{});
|
||||
.orElseGet(() -> new String[] {});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,11 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.acceptance;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
@@ -29,6 +30,8 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
import com.jayway.jsonpath.Configuration;
|
||||
import com.jayway.jsonpath.DocumentContext;
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
@@ -39,7 +42,6 @@ import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
|
||||
import com.jayway.jsonpath.spi.mapper.MappingProvider;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.cloudfoundry.operations.applications.ApplicationDetail;
|
||||
import org.cloudfoundry.operations.applications.ApplicationEnvironments;
|
||||
import org.cloudfoundry.operations.applications.ApplicationSummary;
|
||||
@@ -50,6 +52,8 @@ import org.cloudfoundry.uaa.clients.GetClientResponse;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
@@ -83,8 +87,11 @@ import static org.springframework.cloud.appbroker.acceptance.fixtures.cf.CloudFo
|
||||
@EnableConfigurationProperties(AcceptanceTestProperties.class)
|
||||
abstract class CloudFoundryAcceptanceTest {
|
||||
|
||||
static final String PLAN_NAME = "standard";
|
||||
static final String BACKING_APP_PATH = "classpath:backing-app.jar";
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CloudFoundryAcceptanceTest.class);
|
||||
|
||||
protected static final String PLAN_NAME = "standard";
|
||||
|
||||
protected static final String BACKING_APP_PATH = "classpath:backing-app.jar";
|
||||
|
||||
@Autowired
|
||||
protected CloudFoundryService cloudFoundryService;
|
||||
@@ -98,12 +105,15 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
private final WebClient webClient = getSslIgnoringWebClient();
|
||||
|
||||
protected abstract String testSuffix();
|
||||
|
||||
protected abstract String appServiceName();
|
||||
|
||||
protected abstract String backingServiceName();
|
||||
|
||||
private String testBrokerAppName() {
|
||||
return "test-broker-app-" + testSuffix();
|
||||
}
|
||||
|
||||
private String serviceBrokerName() {
|
||||
return "test-broker-" + testSuffix();
|
||||
}
|
||||
@@ -119,12 +129,11 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
"spring.cloud.openservicebroker.catalog.services[0].name=" + appServiceName(),
|
||||
"spring.cloud.openservicebroker.catalog.services[0].description=A service that deploys a backing app",
|
||||
"spring.cloud.openservicebroker.catalog.services[0].bindable=true",
|
||||
"spring.cloud.openservicebroker.catalog.services[0].plans[0].id=" + UUID.randomUUID().toString() ,
|
||||
"spring.cloud.openservicebroker.catalog.services[0].plans[0].id=" + UUID.randomUUID().toString(),
|
||||
"spring.cloud.openservicebroker.catalog.services[0].plans[0].name=standard",
|
||||
"spring.cloud.openservicebroker.catalog.services[0].plans[0].bindable=true",
|
||||
"spring.cloud.openservicebroker.catalog.services[0].plans[0].description=A simple plan",
|
||||
"spring.cloud.openservicebroker.catalog.services[0].plans[0].free=true",
|
||||
|
||||
"spring.cloud.openservicebroker.catalog.services[1].id=" + UUID.randomUUID().toString(),
|
||||
"spring.cloud.openservicebroker.catalog.services[1].name=" + backingServiceName(),
|
||||
"spring.cloud.openservicebroker.catalog.services[1].description=A backing service that can be bound to backing apps",
|
||||
@@ -136,9 +145,9 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
"spring.cloud.openservicebroker.catalog.services[1].plans[0].free=true"
|
||||
};
|
||||
|
||||
String[] appBrokerProperties = ArrayUtils.addAll(
|
||||
openServiceBrokerProperties,
|
||||
brokerProperties.getProperties());
|
||||
List<String> appBrokerProperties = new ArrayList<>();
|
||||
appBrokerProperties.addAll(Arrays.asList(openServiceBrokerProperties));
|
||||
appBrokerProperties.addAll(brokerProperties.getProperties());
|
||||
|
||||
blockingSubscribe(initializeBroker(appBrokerProperties));
|
||||
}
|
||||
@@ -147,6 +156,7 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
void configureJsonPath() {
|
||||
Configuration.setDefaults(new Configuration.Defaults() {
|
||||
private final JsonProvider jacksonJsonProvider = new JacksonJsonProvider();
|
||||
|
||||
private final MappingProvider jacksonMappingProvider = new JacksonMappingProvider();
|
||||
|
||||
@Override
|
||||
@@ -167,7 +177,7 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
public void tearDown() {
|
||||
blockingSubscribe(cloudFoundryService.getOrCreateDefaultOrganization()
|
||||
.map(OrganizationSummary::getId)
|
||||
.flatMap(orgId -> cloudFoundryService.getOrCreateDefaultSpace()
|
||||
@@ -175,7 +185,7 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
.flatMap(spaceId -> cleanup(orgId, spaceId))));
|
||||
}
|
||||
|
||||
private Mono<Void> initializeBroker(String... appBrokerProperties) {
|
||||
private Mono<Void> initializeBroker(List<String> appBrokerProperties) {
|
||||
return cloudFoundryService
|
||||
.getOrCreateDefaultOrganization()
|
||||
.map(OrganizationSummary::getId)
|
||||
@@ -188,7 +198,9 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
APP_BROKER_CLIENT_SECRET,
|
||||
APP_BROKER_CLIENT_AUTHORITIES))
|
||||
.then(cloudFoundryService.associateAppBrokerClientWithOrgAndSpace(brokerClientId(), orgId, spaceId))
|
||||
.then(cloudFoundryService.pushBrokerApp(testBrokerAppName(), getTestBrokerAppPath(), brokerClientId(), appBrokerProperties))
|
||||
.then(cloudFoundryService
|
||||
.pushBrokerApp(testBrokerAppName(), getTestBrokerAppPath(), brokerClientId(),
|
||||
appBrokerProperties))
|
||||
.then(cloudFoundryService.createServiceBroker(serviceBrokerName(), testBrokerAppName()))
|
||||
.then(cloudFoundryService.enableServiceBrokerAccess(appServiceName()))
|
||||
.then(cloudFoundryService.enableServiceBrokerAccess(backingServiceName()))));
|
||||
@@ -201,18 +213,18 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
.onErrorResume(e -> Mono.empty());
|
||||
}
|
||||
|
||||
void createServiceInstance(String serviceInstanceName) {
|
||||
protected void createServiceInstance(String serviceInstanceName) {
|
||||
createServiceInstance(serviceInstanceName, Collections.emptyMap());
|
||||
}
|
||||
|
||||
void createServiceInstance(String serviceInstanceName, Map<String, Object> parameters) {
|
||||
protected void createServiceInstance(String serviceInstanceName, Map<String, Object> parameters) {
|
||||
createServiceInstance(appServiceName(), PLAN_NAME, serviceInstanceName, parameters);
|
||||
}
|
||||
|
||||
void createServiceInstance(String serviceName,
|
||||
String planName,
|
||||
String serviceInstanceName,
|
||||
Map<String, Object> parameters) {
|
||||
protected void createServiceInstance(String serviceName,
|
||||
String planName,
|
||||
String serviceInstanceName,
|
||||
Map<String, Object> parameters) {
|
||||
cloudFoundryService.createServiceInstance(planName, serviceName, serviceInstanceName, parameters)
|
||||
.then(getServiceInstanceMono(serviceInstanceName))
|
||||
.flatMap(serviceInstance -> {
|
||||
@@ -224,7 +236,7 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
.block();
|
||||
}
|
||||
|
||||
void updateServiceInstance(String serviceInstanceName, Map<String, Object> parameters) {
|
||||
protected void updateServiceInstance(String serviceInstanceName, Map<String, Object> parameters) {
|
||||
cloudFoundryService.updateServiceInstance(serviceInstanceName, parameters)
|
||||
.then(getServiceInstanceMono(serviceInstanceName))
|
||||
.flatMap(serviceInstance -> {
|
||||
@@ -236,19 +248,19 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
.block();
|
||||
}
|
||||
|
||||
void deleteServiceInstance(String serviceInstanceName) {
|
||||
protected void deleteServiceInstance(String serviceInstanceName) {
|
||||
blockingSubscribe(cloudFoundryService.deleteServiceInstance(serviceInstanceName));
|
||||
}
|
||||
|
||||
ServiceInstance getServiceInstance(String serviceInstanceName) {
|
||||
protected ServiceInstance getServiceInstance(String serviceInstanceName) {
|
||||
return getServiceInstanceMono(serviceInstanceName).block();
|
||||
}
|
||||
|
||||
ServiceInstance getServiceInstance(String serviceInstanceName, String space) {
|
||||
protected ServiceInstance getServiceInstance(String serviceInstanceName, String space) {
|
||||
return cloudFoundryService.getServiceInstance(serviceInstanceName, space).block();
|
||||
}
|
||||
|
||||
String getServiceInstanceGuid(String serviceInstanceName) {
|
||||
protected String getServiceInstanceGuid(String serviceInstanceName) {
|
||||
return getServiceInstanceMono(serviceInstanceName)
|
||||
.map(ServiceInstance::getId)
|
||||
.block();
|
||||
@@ -258,7 +270,7 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
return cloudFoundryService.getServiceInstance(serviceInstanceName);
|
||||
}
|
||||
|
||||
Optional<ApplicationSummary> getApplicationSummary(String appName) {
|
||||
protected Optional<ApplicationSummary> getApplicationSummary(String appName) {
|
||||
return cloudFoundryService
|
||||
.getApplications()
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
@@ -267,44 +279,44 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
.blockOptional();
|
||||
}
|
||||
|
||||
Optional<ApplicationSummary> getApplicationSummary(String appName, String space) {
|
||||
protected Optional<ApplicationSummary> getApplicationSummary(String appName, String space) {
|
||||
return cloudFoundryService.getApplication(appName, space).blockOptional();
|
||||
}
|
||||
|
||||
ApplicationEnvironments getApplicationEnvironment(String appName) {
|
||||
private ApplicationEnvironments getApplicationEnvironment(String appName) {
|
||||
return cloudFoundryService.getApplicationEnvironment(appName).block();
|
||||
}
|
||||
|
||||
ApplicationEnvironments getApplicationEnvironment(String appName, String space) {
|
||||
private ApplicationEnvironments getApplicationEnvironment(String appName, String space) {
|
||||
return cloudFoundryService.getApplicationEnvironment(appName, space).block();
|
||||
}
|
||||
|
||||
DocumentContext getSpringAppJson(String appName) {
|
||||
protected DocumentContext getSpringAppJson(String appName) {
|
||||
ApplicationEnvironments env = getApplicationEnvironment(appName);
|
||||
String saj = (String) env.getUserProvided().get("SPRING_APPLICATION_JSON");
|
||||
return JsonPath.parse(saj);
|
||||
}
|
||||
|
||||
DocumentContext getSpringAppJson(String appName, String space) {
|
||||
protected DocumentContext getSpringAppJson(String appName, String space) {
|
||||
ApplicationEnvironments env = getApplicationEnvironment(appName, space);
|
||||
String saj = (String) env.getUserProvided().get("SPRING_APPLICATION_JSON");
|
||||
return JsonPath.parse(saj);
|
||||
}
|
||||
|
||||
List<String> getSpaces() {
|
||||
protected List<String> getSpaces() {
|
||||
return cloudFoundryService.getSpaces().block();
|
||||
}
|
||||
|
||||
Optional<GetClientResponse> getUaaClient(String clientId) {
|
||||
protected Optional<GetClientResponse> getUaaClient(String clientId) {
|
||||
return uaaService.getUaaClient(clientId)
|
||||
.blockOptional();
|
||||
}
|
||||
|
||||
void createDomain(String domain) {
|
||||
protected void createDomain(String domain) {
|
||||
cloudFoundryService.createDomain(domain).block();
|
||||
}
|
||||
|
||||
void deleteDomain(String domain) {
|
||||
protected void deleteDomain(String domain) {
|
||||
cloudFoundryService.deleteDomain(domain).block();
|
||||
}
|
||||
|
||||
@@ -315,7 +327,9 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
private <T> void blockingSubscribe(Mono<? super T> publisher) {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
publisher.subscribe(System.out::println, t -> {
|
||||
t.printStackTrace();
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("error subscribing to publisher", t);
|
||||
}
|
||||
latch.countDown();
|
||||
}, latch::countDown);
|
||||
try {
|
||||
@@ -326,7 +340,7 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
}
|
||||
}
|
||||
|
||||
Mono<String> manageApps(String serviceInstanceName, String operation) {
|
||||
protected Mono<String> manageApps(String serviceInstanceName, String operation) {
|
||||
return cloudFoundryService
|
||||
.getServiceInstance(serviceInstanceName)
|
||||
.map(ServiceInstance::getId)
|
||||
@@ -335,37 +349,39 @@ abstract class CloudFoundryAcceptanceTest {
|
||||
.getApplicationRoute(testBrokerAppName())
|
||||
.flatMap(appRoute ->
|
||||
webClient.get()
|
||||
.uri(URI.create(appRoute + "/" + operation + "/" + serviceInstanceId))
|
||||
.exchange()
|
||||
.flatMap(clientResponse -> clientResponse.toEntity(String.class))
|
||||
.map(HttpEntity::getBody)));
|
||||
.uri(URI.create(appRoute + "/" + operation + "/" + serviceInstanceId))
|
||||
.exchange()
|
||||
.flatMap(clientResponse -> clientResponse.toEntity(String.class))
|
||||
.map(HttpEntity::getBody)));
|
||||
}
|
||||
|
||||
private WebClient getSslIgnoringWebClient() {
|
||||
return WebClient.builder()
|
||||
.clientConnector(new ReactorClientHttpConnector(HttpClient
|
||||
.create()
|
||||
.secure(t -> {
|
||||
try {
|
||||
t.sslContext(SslContextBuilder
|
||||
.forClient()
|
||||
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
||||
.build());
|
||||
}
|
||||
catch (SSLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
})))
|
||||
.build();
|
||||
.clientConnector(new ReactorClientHttpConnector(HttpClient
|
||||
.create()
|
||||
.secure(t -> {
|
||||
try {
|
||||
t.sslContext(SslContextBuilder
|
||||
.forClient()
|
||||
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
||||
.build());
|
||||
}
|
||||
catch (SSLException e) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("problem ignoring SSL in WebClient", e);
|
||||
}
|
||||
}
|
||||
})))
|
||||
.build();
|
||||
}
|
||||
|
||||
protected Mono<List<ApplicationDetail>> getApplications(String app1, String app2) {
|
||||
return Flux.merge(cloudFoundryService.getApplication(app1),
|
||||
cloudFoundryService.getApplication(app2))
|
||||
.parallel()
|
||||
.runOn(Schedulers.parallel())
|
||||
.sequential()
|
||||
.collectList();
|
||||
.parallel()
|
||||
.runOn(Schedulers.parallel())
|
||||
.sequential()
|
||||
.collectList();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,12 +27,16 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class CreateInstanceAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
|
||||
private static final String APP_CREATE_1 = "app-create-1";
|
||||
|
||||
private static final String APP_CREATE_2 = "app-create-2";
|
||||
|
||||
private static final String SI_NAME = "si-create";
|
||||
|
||||
private static final String SUFFIX = "create-instance";
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Override
|
||||
protected String testSuffix() {
|
||||
@@ -115,4 +119,5 @@ class CreateInstanceAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
assertThat(json.read("$.['spring.security.user.password']").toString())
|
||||
.matches("[a-zA-Z]{14}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,11 +29,14 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class CreateInstanceWithOAuth2CredentialsAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
|
||||
private static final String APP_NAME = "app-create-oauth2";
|
||||
|
||||
private static final String SI_NAME = "si-create-oauth2";
|
||||
|
||||
private static final String SUFFIX = "create-instance-oauth2";
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Override
|
||||
protected String testSuffix() {
|
||||
@@ -57,7 +60,7 @@ class CreateInstanceWithOAuth2CredentialsAcceptanceTest extends CloudFoundryAcce
|
||||
|
||||
"spring.cloud.appbroker.services[0].apps[0].name=" + APP_NAME,
|
||||
"spring.cloud.appbroker.services[0].apps[0].path=" + BACKING_APP_PATH,
|
||||
|
||||
|
||||
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].name=SpringSecurityOAuth2",
|
||||
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.registration=sample-app-client",
|
||||
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.grant-types=[\"client_credentials\"]",
|
||||
@@ -83,7 +86,8 @@ class CreateInstanceWithOAuth2CredentialsAcceptanceTest extends CloudFoundryAcce
|
||||
DocumentContext json = getSpringAppJson(APP_NAME);
|
||||
assertThat(json.read("$.['spring.security.oauth2.client.registration.sample-app-client.client-id']").toString())
|
||||
.isEqualTo(uaaClientId(serviceInstanceGuid));
|
||||
assertThat(json.read("$.['spring.security.oauth2.client.registration.sample-app-client.client-secret']").toString())
|
||||
assertThat(
|
||||
json.read("$.['spring.security.oauth2.client.registration.sample-app-client.client-secret']").toString())
|
||||
.matches("[a-zA-Z]{12}");
|
||||
|
||||
// and a UAA client is created
|
||||
@@ -108,4 +112,5 @@ class CreateInstanceWithOAuth2CredentialsAcceptanceTest extends CloudFoundryAcce
|
||||
private String uaaClientId(String serviceInstanceGuid) {
|
||||
return APP_NAME + "-" + serviceInstanceGuid;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,11 +29,14 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class CreateInstanceWithParametersAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
|
||||
private static final String APP_NAME = "app-create-params";
|
||||
|
||||
private static final String SI_NAME = "si-create-params";
|
||||
|
||||
private static final String SUFFIX = "create-instance-with-params";
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Override
|
||||
protected String testSuffix() {
|
||||
@@ -54,18 +57,15 @@ class CreateInstanceWithParametersAcceptanceTest extends CloudFoundryAcceptanceT
|
||||
@AppBrokerTestProperties({
|
||||
"spring.cloud.appbroker.services[0].service-name=" + APP_SERVICE_NAME,
|
||||
"spring.cloud.appbroker.services[0].plan-name=" + PLAN_NAME,
|
||||
|
||||
"spring.cloud.appbroker.services[0].apps[0].name=" + APP_NAME,
|
||||
"spring.cloud.appbroker.services[0].apps[0].path=" + BACKING_APP_PATH,
|
||||
"spring.cloud.appbroker.services[0].apps[0].environment.parameter1=config1",
|
||||
"spring.cloud.appbroker.services[0].apps[0].environment.parameter2=config2",
|
||||
"spring.cloud.appbroker.services[0].apps[0].environment.parameter3=config3",
|
||||
|
||||
"spring.cloud.appbroker.services[0].apps[0].parameters-transformers[0].name=EnvironmentMapping",
|
||||
"spring.cloud.appbroker.services[0].apps[0].parameters-transformers[0].args.include=parameter1,parameter3",
|
||||
|
||||
"spring.cloud.appbroker.services[0].apps[0].parameters-transformers[1].name=PropertyMapping",
|
||||
"spring.cloud.appbroker.services[0].apps[0].parameters-transformers[1].args.include=memory",
|
||||
"spring.cloud.appbroker.services[0].apps[0].parameters-transformers[1].args.include=memory"
|
||||
})
|
||||
void deployAppsWithParametersOnCreateService() {
|
||||
// when a service instance is created
|
||||
@@ -96,4 +96,4 @@ class CreateInstanceWithParametersAcceptanceTest extends CloudFoundryAcceptanceT
|
||||
deleteServiceInstance(SI_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -27,13 +27,16 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class CreateInstanceWithServiceInstanceGuidSuffixTargetAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
|
||||
private static final String SUFFIX = "create-si-guid";
|
||||
|
||||
private static final String APP_NAME_1 = "app-create-" + SUFFIX;
|
||||
|
||||
private static final String SI_NAME = "si-create-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SI_NAME = "backing-si";
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Override
|
||||
protected String testSuffix() {
|
||||
@@ -54,15 +57,12 @@ class CreateInstanceWithServiceInstanceGuidSuffixTargetAcceptanceTest extends Cl
|
||||
@AppBrokerTestProperties({
|
||||
"spring.cloud.appbroker.services[0].service-name=" + APP_SERVICE_NAME,
|
||||
"spring.cloud.appbroker.services[0].plan-name=" + PLAN_NAME,
|
||||
|
||||
"spring.cloud.appbroker.services[0].apps[0].name=" + APP_NAME_1,
|
||||
"spring.cloud.appbroker.services[0].apps[0].path=" + BACKING_APP_PATH,
|
||||
"spring.cloud.appbroker.services[0].apps[0].services[0].service-instance-name=" + BACKING_SI_NAME,
|
||||
|
||||
"spring.cloud.appbroker.services[0].services[0].name=" + BACKING_SERVICE_NAME,
|
||||
"spring.cloud.appbroker.services[0].services[0].plan=" + PLAN_NAME,
|
||||
"spring.cloud.appbroker.services[0].services[0].service-instance-name=" + BACKING_SI_NAME,
|
||||
|
||||
"spring.cloud.appbroker.services[0].target.name=ServiceInstanceGuidSuffix"
|
||||
})
|
||||
void deployAppsWithServiceInstanceGuidSuffixOnCreateService() {
|
||||
@@ -88,4 +88,5 @@ class CreateInstanceWithServiceInstanceGuidSuffixTargetAcceptanceTest extends Cl
|
||||
// when the service instance is deleted
|
||||
deleteServiceInstance(SI_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,14 +28,18 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class CreateInstanceWithServicesAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
|
||||
private static final String APP_NAME = "app-create-services";
|
||||
|
||||
private static final String SI_NAME = "si-create-services";
|
||||
|
||||
private static final String BACKING_SI_1_NAME = "backing-service-instance-created";
|
||||
|
||||
private static final String BACKING_SI_2_NAME = "backing-service-instance-existing";
|
||||
|
||||
private static final String SUFFIX = "create-instance-with-services";
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Override
|
||||
protected String testSuffix() {
|
||||
@@ -56,15 +60,13 @@ class CreateInstanceWithServicesAcceptanceTest extends CloudFoundryAcceptanceTes
|
||||
@AppBrokerTestProperties({
|
||||
"spring.cloud.appbroker.services[0].service-name=" + APP_SERVICE_NAME,
|
||||
"spring.cloud.appbroker.services[0].plan-name=" + PLAN_NAME,
|
||||
|
||||
"spring.cloud.appbroker.services[0].apps[0].name=" + APP_NAME,
|
||||
"spring.cloud.appbroker.services[0].apps[0].path=" + BACKING_APP_PATH,
|
||||
"spring.cloud.appbroker.services[0].apps[0].services[0].service-instance-name=" + BACKING_SI_1_NAME,
|
||||
"spring.cloud.appbroker.services[0].apps[0].services[1].service-instance-name=" + BACKING_SI_2_NAME,
|
||||
|
||||
"spring.cloud.appbroker.services[0].services[0].name=" + BACKING_SERVICE_NAME,
|
||||
"spring.cloud.appbroker.services[0].services[0].plan=" + PLAN_NAME,
|
||||
"spring.cloud.appbroker.services[0].services[0].service-instance-name=" + BACKING_SI_1_NAME,
|
||||
"spring.cloud.appbroker.services[0].services[0].service-instance-name=" + BACKING_SI_1_NAME
|
||||
})
|
||||
void deployAppsAndCreateServicesOnCreateService() {
|
||||
// given that a service is available in the marketplace
|
||||
@@ -94,4 +96,5 @@ class CreateInstanceWithServicesAcceptanceTest extends CloudFoundryAcceptanceTes
|
||||
|
||||
deleteServiceInstance(BACKING_SI_2_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,14 +28,18 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class CreateInstanceWithSpacePerServiceInstanceTargetAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
|
||||
private static final String APP_NAME_1 = "app-create-space-per1";
|
||||
|
||||
private static final String APP_NAME_2 = "app-create-space-per2";
|
||||
|
||||
private static final String SI_NAME = "si-create-space-per";
|
||||
|
||||
private static final String BACKING_SI_NAME = "backing-service-space-per-target";
|
||||
|
||||
private static final String SUFFIX = "create-instance-space-per-si";
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Override
|
||||
protected String testSuffix() {
|
||||
@@ -101,4 +105,5 @@ class CreateInstanceWithSpacePerServiceInstanceTargetAcceptanceTest extends Clou
|
||||
List<String> spaces = getSpaces();
|
||||
assertThat(spaces).doesNotContain(spaceName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,25 +20,36 @@ import java.net.URI;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@SuppressWarnings("PMD.DoNotUseThreads")
|
||||
@Service
|
||||
public class HealthListener {
|
||||
class HealthListener {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HealthListener.class);
|
||||
|
||||
private final AtomicInteger requests = new AtomicInteger();
|
||||
|
||||
private final AtomicInteger errors = new AtomicInteger();
|
||||
|
||||
private final AtomicBoolean running = new AtomicBoolean(false);
|
||||
|
||||
private Thread runner;
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
public HealthListener(RestTemplate restTemplate) {
|
||||
this.restTemplate = restTemplate;
|
||||
}
|
||||
|
||||
void start(String path) {
|
||||
public void start(String path) {
|
||||
if (running.get()) {
|
||||
throw new IllegalStateException("cannot start when test is already running");
|
||||
}
|
||||
@@ -50,8 +61,9 @@ public class HealthListener {
|
||||
while (running.get()) {
|
||||
try {
|
||||
requests.incrementAndGet();
|
||||
ResponseEntity<String> response = restTemplate.getForEntity(URI.create("http://" + path + "/actuator/health"), String.class);
|
||||
if (response.getStatusCodeValue() != 200) {
|
||||
ResponseEntity<String> response = restTemplate
|
||||
.getForEntity(URI.create("http://" + path + "/actuator/health"), String.class);
|
||||
if (response.getStatusCode() != HttpStatus.OK) {
|
||||
errors.incrementAndGet();
|
||||
}
|
||||
Thread.sleep(1000);
|
||||
@@ -64,21 +76,23 @@ public class HealthListener {
|
||||
runner.start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
public void stop() {
|
||||
running.set(false);
|
||||
try {
|
||||
runner.join();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("thread was interrupted while waiting to die", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getSuccesses() {
|
||||
public int getSuccesses() {
|
||||
return requests.get();
|
||||
}
|
||||
|
||||
int getFailures() {
|
||||
public int getFailures() {
|
||||
return errors.get();
|
||||
}
|
||||
|
||||
@@ -31,11 +31,14 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class UpdateInstanceAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
|
||||
private static final String APP_NAME = "app-update";
|
||||
|
||||
private static final String SI_NAME = "si-update";
|
||||
|
||||
private static final String SUFFIX = "update-instance";
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Autowired
|
||||
private HealthListener healthListener;
|
||||
@@ -59,7 +62,6 @@ class UpdateInstanceAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
@AppBrokerTestProperties({
|
||||
"spring.cloud.appbroker.services[0].service-name=" + APP_SERVICE_NAME,
|
||||
"spring.cloud.appbroker.services[0].plan-name=" + PLAN_NAME,
|
||||
|
||||
"spring.cloud.appbroker.services[0].apps[0].name=" + APP_NAME,
|
||||
"spring.cloud.appbroker.services[0].apps[0].path=" + BACKING_APP_PATH,
|
||||
"spring.cloud.appbroker.services[0].apps[0].environment.parameter1=config1",
|
||||
@@ -71,7 +73,7 @@ class UpdateInstanceAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
"spring.cloud.appbroker.services[0].apps[0].parameters-transformers[1].name=PropertyMapping",
|
||||
"spring.cloud.appbroker.services[0].apps[0].parameters-transformers[1].args.include=count"
|
||||
})
|
||||
void deployAppsOnUpdateService() {
|
||||
public void deployAppsOnUpdateService() {
|
||||
// given a service instance is created
|
||||
createServiceInstance(SI_NAME);
|
||||
|
||||
@@ -119,4 +121,5 @@ class UpdateInstanceAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
Optional<ApplicationSummary> backingApplicationAfterDeletion = getApplicationSummary(APP_NAME);
|
||||
assertThat(backingApplicationAfterDeletion).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,11 +30,14 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class UpdateInstanceWithHostAndDomainAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
|
||||
private static final String APP_NAME = "app-update-domain";
|
||||
|
||||
private static final String SI_NAME = "si-update-domain";
|
||||
|
||||
private static final String SUFFIX = "update-instance-domain";
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Autowired
|
||||
private HealthListener healthListener;
|
||||
@@ -103,4 +106,5 @@ class UpdateInstanceWithHostAndDomainAcceptanceTest extends CloudFoundryAcceptan
|
||||
|
||||
deleteDomain("mydomain.com");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.acceptance;
|
||||
|
||||
import org.cloudfoundry.operations.applications.ApplicationSummary;
|
||||
import org.cloudfoundry.operations.services.ServiceInstance;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cloudfoundry.operations.applications.ApplicationSummary;
|
||||
import org.cloudfoundry.operations.services.ServiceInstance;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -31,13 +31,16 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class UpdateInstanceWithServicesAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
|
||||
private static final String APP_NAME = "app-update-services";
|
||||
|
||||
private static final String SI_NAME = "si-update-services";
|
||||
|
||||
private static final String BACKING_SI_NAME = "backing-service-instance-update";
|
||||
|
||||
private static final String SUFFIX = "update-instance-with-services";
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Autowired
|
||||
private HealthListener healthListener;
|
||||
@@ -111,4 +114,5 @@ class UpdateInstanceWithServicesAcceptanceTest extends CloudFoundryAcceptanceTes
|
||||
// then the service instance is deleted
|
||||
deleteServiceInstance(SI_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,11 +31,14 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class UpdateInstanceWithTargetAcceptanceTest extends CloudFoundryAcceptanceTest {
|
||||
|
||||
private static final String APP_NAME = "app-update-target";
|
||||
|
||||
private static final String SI_NAME = "si-update-target";
|
||||
|
||||
private static final String SUFFIX = "update-instance-with-target";
|
||||
private static final String APP_SERVICE_NAME = "app-service-"+ SUFFIX;
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-"+ SUFFIX;
|
||||
|
||||
private static final String APP_SERVICE_NAME = "app-service-" + SUFFIX;
|
||||
|
||||
private static final String BACKING_SERVICE_NAME = "backing-service-" + SUFFIX;
|
||||
|
||||
@Autowired
|
||||
private HealthListener healthListener;
|
||||
@@ -105,4 +108,4 @@ class UpdateInstanceWithTargetAcceptanceTest extends CloudFoundryAcceptanceTest
|
||||
assertThat(spaces).doesNotContain(spaceName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -42,16 +42,23 @@ import org.springframework.context.annotation.Configuration;
|
||||
@EnableConfigurationProperties(CloudFoundryProperties.class)
|
||||
public class CloudFoundryClientConfiguration {
|
||||
|
||||
/**
|
||||
* The client secret
|
||||
*/
|
||||
public static final String APP_BROKER_CLIENT_SECRET = "app-broker-client-secret";
|
||||
|
||||
/**
|
||||
* The client authorities
|
||||
*/
|
||||
public static final String[] APP_BROKER_CLIENT_AUTHORITIES = {
|
||||
"cloud_controller.read", "cloud_controller.write", "clients.write"
|
||||
};
|
||||
|
||||
@Bean
|
||||
CloudFoundryOperations cloudFoundryOperations(CloudFoundryProperties properties,
|
||||
CloudFoundryClient client,
|
||||
DopplerClient dopplerClient,
|
||||
UaaClient uaaClient) {
|
||||
protected CloudFoundryOperations cloudFoundryOperations(CloudFoundryProperties properties,
|
||||
CloudFoundryClient client,
|
||||
DopplerClient dopplerClient,
|
||||
UaaClient uaaClient) {
|
||||
return DefaultCloudFoundryOperations.builder()
|
||||
.cloudFoundryClient(client)
|
||||
.dopplerClient(dopplerClient)
|
||||
@@ -62,8 +69,8 @@ public class CloudFoundryClientConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
CloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext,
|
||||
@Qualifier("userCredentials") TokenProvider tokenProvider) {
|
||||
protected CloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext,
|
||||
@Qualifier("userCredentials") TokenProvider tokenProvider) {
|
||||
return ReactorCloudFoundryClient.builder()
|
||||
.connectionContext(connectionContext)
|
||||
.tokenProvider(tokenProvider)
|
||||
@@ -71,7 +78,7 @@ public class CloudFoundryClientConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
ConnectionContext connectionContext(CloudFoundryProperties properties) {
|
||||
protected ConnectionContext connectionContext(CloudFoundryProperties properties) {
|
||||
return DefaultConnectionContext.builder()
|
||||
.apiHost(properties.getApiHost())
|
||||
.port(Optional.ofNullable(properties.getApiPort()))
|
||||
@@ -81,8 +88,8 @@ public class CloudFoundryClientConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
DopplerClient dopplerClient(ConnectionContext connectionContext,
|
||||
@Qualifier("userCredentials") TokenProvider tokenProvider) {
|
||||
protected DopplerClient dopplerClient(ConnectionContext connectionContext,
|
||||
@Qualifier("userCredentials") TokenProvider tokenProvider) {
|
||||
return ReactorDopplerClient.builder()
|
||||
.connectionContext(connectionContext)
|
||||
.tokenProvider(tokenProvider)
|
||||
@@ -90,8 +97,8 @@ public class CloudFoundryClientConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
UaaClient uaaClient(ConnectionContext connectionContext,
|
||||
@Qualifier("clientCredentials") TokenProvider tokenProvider) {
|
||||
protected UaaClient uaaClient(ConnectionContext connectionContext,
|
||||
@Qualifier("clientCredentials") TokenProvider tokenProvider) {
|
||||
return ReactorUaaClient.builder()
|
||||
.connectionContext(connectionContext)
|
||||
.tokenProvider(tokenProvider)
|
||||
@@ -104,7 +111,7 @@ public class CloudFoundryClientConfiguration {
|
||||
CloudFoundryProperties.PROPERTY_PREFIX + ".username",
|
||||
CloudFoundryProperties.PROPERTY_PREFIX + ".password"
|
||||
})
|
||||
PasswordGrantTokenProvider passwordTokenProvider(CloudFoundryProperties properties) {
|
||||
protected PasswordGrantTokenProvider passwordTokenProvider(CloudFoundryProperties properties) {
|
||||
return PasswordGrantTokenProvider.builder()
|
||||
.password(properties.getPassword())
|
||||
.username(properties.getUsername())
|
||||
@@ -117,7 +124,7 @@ public class CloudFoundryClientConfiguration {
|
||||
CloudFoundryProperties.PROPERTY_PREFIX + ".client-id",
|
||||
CloudFoundryProperties.PROPERTY_PREFIX + ".client-secret"
|
||||
})
|
||||
ClientCredentialsGrantTokenProvider clientTokenProvider(CloudFoundryProperties properties) {
|
||||
protected ClientCredentialsGrantTokenProvider clientTokenProvider(CloudFoundryProperties properties) {
|
||||
return ClientCredentialsGrantTokenProvider.builder()
|
||||
.clientId(properties.getClientId())
|
||||
.clientSecret(properties.getClientSecret())
|
||||
@@ -27,18 +27,28 @@ import static org.springframework.cloud.appbroker.acceptance.fixtures.cf.CloudFo
|
||||
@ConfigurationProperties(PROPERTY_PREFIX)
|
||||
public class CloudFoundryProperties {
|
||||
|
||||
static final String PROPERTY_PREFIX = "spring.cloud.appbroker.acceptancetest.cloudfoundry";
|
||||
protected static final String PROPERTY_PREFIX = "spring.cloud.appbroker.acceptancetest.cloudfoundry";
|
||||
|
||||
private String apiHost;
|
||||
|
||||
private Integer apiPort;
|
||||
|
||||
private String defaultOrg;
|
||||
|
||||
private String defaultSpace;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
private String clientId;
|
||||
|
||||
private String clientSecret;
|
||||
|
||||
private String identityZoneSubdomain;
|
||||
|
||||
private boolean secure = true;
|
||||
|
||||
private boolean skipSslValidation;
|
||||
|
||||
public String getApiHost() {
|
||||
@@ -73,9 +73,11 @@ import static java.lang.String.format;
|
||||
public class CloudFoundryService {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CloudFoundryService.class);
|
||||
|
||||
|
||||
private static final String DEPLOYER_PROPERTY_PREFIX = "spring.cloud.appbroker.deployer.cloudfoundry.";
|
||||
|
||||
private static final int EXPECTED_PROPERTY_PARTS = 2;
|
||||
|
||||
private final CloudFoundryClient cloudFoundryClient;
|
||||
|
||||
private final CloudFoundryOperations cloudFoundryOperations;
|
||||
@@ -83,8 +85,8 @@ public class CloudFoundryService {
|
||||
private final CloudFoundryProperties cloudFoundryProperties;
|
||||
|
||||
public CloudFoundryService(CloudFoundryClient cloudFoundryClient,
|
||||
CloudFoundryOperations cloudFoundryOperations,
|
||||
CloudFoundryProperties cloudFoundryProperties) {
|
||||
CloudFoundryOperations cloudFoundryOperations,
|
||||
CloudFoundryProperties cloudFoundryProperties) {
|
||||
this.cloudFoundryClient = cloudFoundryClient;
|
||||
this.cloudFoundryOperations = cloudFoundryOperations;
|
||||
this.cloudFoundryProperties = cloudFoundryProperties;
|
||||
@@ -125,7 +127,8 @@ public class CloudFoundryService {
|
||||
.map(url -> "https://" + url);
|
||||
}
|
||||
|
||||
public Mono<Void> pushBrokerApp(String appName, Path appPath, String brokerClientId, String... appBrokerProperties) {
|
||||
public Mono<Void> pushBrokerApp(String appName, Path appPath, String brokerClientId,
|
||||
List<String> appBrokerProperties) {
|
||||
return cloudFoundryOperations.applications()
|
||||
.pushManifest(PushApplicationManifestRequest.builder()
|
||||
.manifest(ApplicationManifest.builder()
|
||||
@@ -168,16 +171,17 @@ public class CloudFoundryService {
|
||||
.name(si.getName())
|
||||
.build())
|
||||
.doOnSuccess(item -> LOGGER.info("Deleted service instance " + serviceInstanceName))
|
||||
.doOnError(error -> LOGGER.error("Error deleting service instance " + serviceInstanceName + ": " + error))
|
||||
.doOnError(
|
||||
error -> LOGGER.error("Error deleting service instance " + serviceInstanceName + ": " + error))
|
||||
.onErrorResume(e -> Mono.empty()))
|
||||
.doOnError(error -> LOGGER.warn("Error getting service instance " + serviceInstanceName + ": " + error))
|
||||
.onErrorResume(e -> Mono.empty());
|
||||
}
|
||||
|
||||
public Mono<Void> createServiceInstance(String planName,
|
||||
String serviceName,
|
||||
String serviceInstanceName,
|
||||
Map<String, Object> parameters) {
|
||||
String serviceName,
|
||||
String serviceInstanceName,
|
||||
Map<String, Object> parameters) {
|
||||
return cloudFoundryOperations.services()
|
||||
.createInstance(CreateServiceInstanceRequest.builder()
|
||||
.planName(planName)
|
||||
@@ -208,7 +212,7 @@ public class CloudFoundryService {
|
||||
}
|
||||
|
||||
private Mono<ServiceInstance> getServiceInstance(CloudFoundryOperations operations,
|
||||
String serviceInstanceName) {
|
||||
String serviceInstanceName) {
|
||||
return operations.services()
|
||||
.getInstance(GetServiceInstanceRequest.builder()
|
||||
.name(serviceInstanceName)
|
||||
@@ -338,28 +342,28 @@ public class CloudFoundryService {
|
||||
|
||||
public Mono<Void> createDomain(String domain) {
|
||||
return cloudFoundryOperations
|
||||
.domains()
|
||||
.create(CreateDomainRequest
|
||||
.builder()
|
||||
.domain(domain)
|
||||
.organization(cloudFoundryProperties.getDefaultOrg())
|
||||
.build())
|
||||
.onErrorResume(e -> Mono.empty());
|
||||
.domains()
|
||||
.create(CreateDomainRequest
|
||||
.builder()
|
||||
.domain(domain)
|
||||
.organization(cloudFoundryProperties.getDefaultOrg())
|
||||
.build())
|
||||
.onErrorResume(e -> Mono.empty());
|
||||
}
|
||||
|
||||
public Mono<Void> deleteDomain(String domain) {
|
||||
return cloudFoundryOperations
|
||||
.domains()
|
||||
.list()
|
||||
.filter(d -> d.getName().equals(domain))
|
||||
.map(Domain::getId)
|
||||
.flatMap(domainId -> cloudFoundryClient
|
||||
.privateDomains()
|
||||
.delete(DeletePrivateDomainRequest
|
||||
.builder()
|
||||
.privateDomainId(domainId)
|
||||
.build()))
|
||||
.then();
|
||||
.domains()
|
||||
.list()
|
||||
.filter(d -> d.getName().equals(domain))
|
||||
.map(Domain::getId)
|
||||
.flatMap(domainId -> cloudFoundryClient
|
||||
.privateDomains()
|
||||
.delete(DeletePrivateDomainRequest
|
||||
.builder()
|
||||
.privateDomainId(domainId)
|
||||
.build()))
|
||||
.then();
|
||||
}
|
||||
|
||||
private Mono<AssociateOrganizationUserResponse> associateOrgUser(String orgId, String userId) {
|
||||
@@ -432,17 +436,19 @@ public class CloudFoundryService {
|
||||
return deployerVariables;
|
||||
}
|
||||
|
||||
private Map<String, String> propertiesToEnvironment(String... properties) {
|
||||
private Map<String, String> propertiesToEnvironment(List<String> properties) {
|
||||
Map<String, String> environment = new HashMap<>();
|
||||
for (String property : properties) {
|
||||
final String[] propertyKeyValue = property.split("=");
|
||||
if (propertyKeyValue.length == 2) {
|
||||
if (propertyKeyValue.length == EXPECTED_PROPERTY_PARTS) {
|
||||
environment.put(propertyKeyValue[0], propertyKeyValue[1]);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(format("App Broker property '%s' is incorrectly formatted",
|
||||
Arrays.toString(propertyKeyValue)));
|
||||
}
|
||||
}
|
||||
return environment;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,12 +24,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.appbroker.deployer.AppDeployer;
|
||||
import org.springframework.cloud.appbroker.deployer.DefaultBackingAppDeploymentService;
|
||||
import org.springframework.cloud.appbroker.deployer.BackingAppDeploymentService;
|
||||
import org.springframework.cloud.appbroker.deployer.BackingApplication;
|
||||
import org.springframework.cloud.appbroker.deployer.BackingService;
|
||||
import org.springframework.cloud.appbroker.deployer.BackingServicesProvisionService;
|
||||
import org.springframework.cloud.appbroker.deployer.BrokeredServices;
|
||||
import org.springframework.cloud.appbroker.deployer.DefaultBackingAppDeploymentService;
|
||||
import org.springframework.cloud.appbroker.deployer.DefaultBackingServicesProvisionService;
|
||||
import org.springframework.cloud.appbroker.deployer.DeployerClient;
|
||||
import org.springframework.cloud.appbroker.extensions.credentials.CredentialGenerator;
|
||||
@@ -71,6 +71,10 @@ import org.springframework.cloud.servicebroker.service.ServiceInstanceBindingSer
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* App Broker Auto-configuration
|
||||
*/
|
||||
@SuppressWarnings("PMD.CouplingBetweenObjects")
|
||||
@Configuration
|
||||
@AutoConfigureAfter(CloudFoundryAppDeployerAutoConfiguration.class)
|
||||
@ConditionalOnBean(AppDeployer.class)
|
||||
@@ -78,124 +82,251 @@ public class AppBrokerAutoConfiguration {
|
||||
|
||||
private static final String PROPERTY_PREFIX = "spring.cloud.appbroker";
|
||||
|
||||
/**
|
||||
* Provide a {@link DeployerClient} bean
|
||||
*
|
||||
* @param appDeployer the AppDeployer bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public DeployerClient deployerClient(AppDeployer appDeployer) {
|
||||
return new DeployerClient(appDeployer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link BackingAppDeploymentService} bean
|
||||
*
|
||||
* @param deployerClient the DeployerClient bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public BackingAppDeploymentService backingAppDeploymentService(DeployerClient deployerClient) {
|
||||
return new DefaultBackingAppDeploymentService(deployerClient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link ManagementClient} bean
|
||||
*
|
||||
* @param appManager the AppManager bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public ManagementClient managementClient(AppManager appManager) {
|
||||
return new ManagementClient(appManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link BackingAppManagementService} bean
|
||||
*
|
||||
* @param managementClient the ManagementClient bean
|
||||
* @param appDeployer the AppDeployer bean
|
||||
* @param brokeredServices the BrokeredServices bean
|
||||
* @param targetService the TargetService bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public BackingAppManagementService backingAppManagementService(ManagementClient managementClient,
|
||||
AppDeployer appDeployer, BrokeredServices brokeredServices, TargetService targetService) {
|
||||
return new BackingAppManagementService(managementClient, appDeployer, brokeredServices, targetService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link BrokeredServices} bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
@ConfigurationProperties(PROPERTY_PREFIX + ".services")
|
||||
public BrokeredServices brokeredServices() {
|
||||
return BrokeredServices.builder().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link ServiceInstanceStateRepository} bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ServiceInstanceStateRepository.class)
|
||||
public ServiceInstanceStateRepository serviceInstanceStateRepository() {
|
||||
return new InMemoryServiceInstanceStateRepository();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link ServiceInstanceBindingStateRepository} bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ServiceInstanceBindingStateRepository.class)
|
||||
public ServiceInstanceBindingStateRepository serviceInstanceBindingStateRepository() {
|
||||
return new InMemoryServiceInstanceBindingStateRepository();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an {@link EnvironmentMappingParametersTransformerFactory} bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public EnvironmentMappingParametersTransformerFactory environmentMappingParametersTransformerFactory() {
|
||||
return new EnvironmentMappingParametersTransformerFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link ParameterMappingParametersTransformerFactory} bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public PropertyMappingParametersTransformerFactory propertyMappingParametersTransformerFactory() {
|
||||
return new PropertyMappingParametersTransformerFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link ParameterMappingParametersTransformerFactory} bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public ParameterMappingParametersTransformerFactory parameterMappingParametersTransformerFactory() {
|
||||
return new ParameterMappingParametersTransformerFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link BackingApplicationsParametersTransformationService} bean
|
||||
*
|
||||
* @param transformers a collection of parameter transformers
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public BackingApplicationsParametersTransformationService backingApplicationsParametersTransformationService(
|
||||
List<ParametersTransformerFactory<BackingApplication, ?>> transformers) {
|
||||
return new BackingApplicationsParametersTransformationService(transformers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link BackingServicesParametersTransformationService} bean
|
||||
*
|
||||
* @param transformers a collection of parameter transformers
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public BackingServicesParametersTransformationService backingServicesParametersTransformationService(
|
||||
List<ParametersTransformerFactory<BackingService, ?>> transformers) {
|
||||
return new BackingServicesParametersTransformationService(transformers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link SimpleCredentialGenerator} bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@ConditionalOnMissingBean(CredentialGenerator.class)
|
||||
@Bean
|
||||
public SimpleCredentialGenerator simpleCredentialGenerator() {
|
||||
return new SimpleCredentialGenerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link SpringSecurityBasicAuthCredentialProviderFactory} bean
|
||||
*
|
||||
* @param credentialGenerator the CredentialGenerator bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public SpringSecurityBasicAuthCredentialProviderFactory springSecurityBasicAuthCredentialProvider(CredentialGenerator credentialGenerator) {
|
||||
public SpringSecurityBasicAuthCredentialProviderFactory springSecurityBasicAuthCredentialProvider(
|
||||
CredentialGenerator credentialGenerator) {
|
||||
return new SpringSecurityBasicAuthCredentialProviderFactory(credentialGenerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link SpringSecurityOAuth2CredentialProviderFactory} bean
|
||||
*
|
||||
* @param credentialGenerator the CredentialGenerator bean
|
||||
* @param oAuth2Client the OAuth2Client bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public SpringSecurityOAuth2CredentialProviderFactory springSecurityOAuth2CredentialProvider(CredentialGenerator credentialGenerator,
|
||||
OAuth2Client oAuth2Client) {
|
||||
public SpringSecurityOAuth2CredentialProviderFactory springSecurityOAuth2CredentialProvider(
|
||||
CredentialGenerator credentialGenerator,
|
||||
OAuth2Client oAuth2Client) {
|
||||
return new SpringSecurityOAuth2CredentialProviderFactory(credentialGenerator, oAuth2Client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link CredentialProviderService} bean
|
||||
*
|
||||
* @param providers a collection of credential providers
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public CredentialProviderService credentialProviderService(List<CredentialProviderFactory<?>> providers) {
|
||||
return new CredentialProviderService(providers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link SpacePerServiceInstance} bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public SpacePerServiceInstance spacePerServiceInstance() {
|
||||
return new SpacePerServiceInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link ServiceInstanceGuidSuffix} bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public ServiceInstanceGuidSuffix serviceInstanceGuidSuffix() {
|
||||
return new ServiceInstanceGuidSuffix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link TargetService} bean
|
||||
*
|
||||
* @param targets a collection of targets
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public TargetService targetService(List<TargetFactory<?>> targets) {
|
||||
return new TargetService(targets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link BackingServicesProvisionService} bean
|
||||
*
|
||||
* @param deployerClient the DeployerClient bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public BackingServicesProvisionService backingServicesProvisionService(DeployerClient deployerClient) {
|
||||
return new DefaultBackingServicesProvisionService(deployerClient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link CreateServiceInstanceWorkflow} bean
|
||||
*
|
||||
* @param brokeredServices the BrokeredServices bean
|
||||
* @param backingAppDeploymentService the BackingAppDeploymentService bean
|
||||
* @param appsParametersTransformationService the BackingApplicationsParametersTransformationService bean
|
||||
* @param servicesParametersTransformationService the BackingServicesParametersTransformationService bean
|
||||
* @param credentialProviderService the CredentialProviderService bean
|
||||
* @param targetService the TargetService bean
|
||||
* @param backingServicesProvisionService the BackingServicesProvisionService bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public CreateServiceInstanceWorkflow appDeploymentCreateServiceInstanceWorkflow(
|
||||
BrokeredServices brokeredServices,
|
||||
BackingAppDeploymentService backingAppDeploymentService,
|
||||
BrokeredServices brokeredServices, BackingAppDeploymentService backingAppDeploymentService,
|
||||
BackingApplicationsParametersTransformationService appsParametersTransformationService,
|
||||
BackingServicesParametersTransformationService servicesParametersTransformationService,
|
||||
CredentialProviderService credentialProviderService,
|
||||
TargetService targetService,
|
||||
CredentialProviderService credentialProviderService, TargetService targetService,
|
||||
BackingServicesProvisionService backingServicesProvisionService) {
|
||||
return new AppDeploymentCreateServiceInstanceWorkflow(
|
||||
brokeredServices,
|
||||
@@ -207,10 +338,20 @@ public class AppBrokerAutoConfiguration {
|
||||
targetService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link UpdateServiceInstanceWorkflow} bean
|
||||
*
|
||||
* @param brokeredServices the BrokeredServices bean
|
||||
* @param backingAppDeploymentService the BackingAppDeploymentService bean
|
||||
* @param backingServicesProvisionService the BackingServicesProvisionService bean
|
||||
* @param appsParametersTransformationService the BackingApplicationsParametersTransformationService bean
|
||||
* @param servicesParametersTransformationService the BackingServicesParametersTransformationService bean
|
||||
* @param targetService the TargetService bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public UpdateServiceInstanceWorkflow appDeploymentUpdateServiceInstanceWorkflow(
|
||||
BrokeredServices brokeredServices,
|
||||
BackingAppDeploymentService backingAppDeploymentService,
|
||||
BrokeredServices brokeredServices, BackingAppDeploymentService backingAppDeploymentService,
|
||||
BackingServicesProvisionService backingServicesProvisionService,
|
||||
BackingApplicationsParametersTransformationService appsParametersTransformationService,
|
||||
BackingServicesParametersTransformationService servicesParametersTransformationService,
|
||||
@@ -225,13 +366,21 @@ public class AppBrokerAutoConfiguration {
|
||||
targetService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link DeleteServiceInstanceWorkflow} bean
|
||||
*
|
||||
* @param brokeredServices the BrokeredServices bean
|
||||
* @param backingAppDeploymentService the BackingAppDeploymentService bean
|
||||
* @param backingServicesProvisionService the BackingServicesProvisionService bean
|
||||
* @param credentialProviderService the CredentialProviderService bean
|
||||
* @param targetService the TargetService bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public DeleteServiceInstanceWorkflow appDeploymentDeleteServiceInstanceWorkflow(
|
||||
BrokeredServices brokeredServices,
|
||||
BackingAppDeploymentService backingAppDeploymentService,
|
||||
BrokeredServices brokeredServices, BackingAppDeploymentService backingAppDeploymentService,
|
||||
BackingServicesProvisionService backingServicesProvisionService,
|
||||
CredentialProviderService credentialProviderService,
|
||||
TargetService targetService) {
|
||||
CredentialProviderService credentialProviderService, TargetService targetService) {
|
||||
|
||||
return new AppDeploymentDeleteServiceInstanceWorkflow(
|
||||
brokeredServices,
|
||||
@@ -241,14 +390,31 @@ public class AppBrokerAutoConfiguration {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link WorkflowServiceInstanceService} bean
|
||||
*
|
||||
* @param stateRepository the ServiceInstanceStateRepository bean
|
||||
* @param createWorkflows a collection of create workflows
|
||||
* @param deleteWorkflows a collection of delete workflows
|
||||
* @param updateWorkflows a collection of update workflows
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public WorkflowServiceInstanceService serviceInstanceService(ServiceInstanceStateRepository stateRepository,
|
||||
List<CreateServiceInstanceWorkflow> createWorkflows,
|
||||
List<DeleteServiceInstanceWorkflow> deleteWorkflows,
|
||||
List<UpdateServiceInstanceWorkflow> updateWorkflows) {
|
||||
List<CreateServiceInstanceWorkflow> createWorkflows, List<DeleteServiceInstanceWorkflow> deleteWorkflows,
|
||||
List<UpdateServiceInstanceWorkflow> updateWorkflows) {
|
||||
return new WorkflowServiceInstanceService(stateRepository, createWorkflows, deleteWorkflows, updateWorkflows);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link WorkflowServiceInstanceBindingService} bean
|
||||
*
|
||||
* @param stateRepository the ServiceInstanceBindingStateRepository bean
|
||||
* @param createServiceInstanceAppBindingWorkflows a collection of create app binding workflows
|
||||
* @param createServiceInstanceRouteBindingWorkflows a collection of create route binding workflows
|
||||
* @param deleteServiceInstanceBindingWorkflows a collection of update workflows
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ServiceInstanceBindingService.class)
|
||||
public WorkflowServiceInstanceBindingService serviceInstanceBindingService(
|
||||
@@ -257,8 +423,8 @@ public class AppBrokerAutoConfiguration {
|
||||
@Autowired(required = false) List<CreateServiceInstanceRouteBindingWorkflow> createServiceInstanceRouteBindingWorkflows,
|
||||
@Autowired(required = false) List<DeleteServiceInstanceBindingWorkflow> deleteServiceInstanceBindingWorkflows) {
|
||||
return new WorkflowServiceInstanceBindingService(stateRepository,
|
||||
createServiceInstanceAppBindingWorkflows,
|
||||
createServiceInstanceRouteBindingWorkflows,
|
||||
createServiceInstanceAppBindingWorkflows, createServiceInstanceRouteBindingWorkflows,
|
||||
deleteServiceInstanceBindingWorkflows);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,11 +42,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.appbroker.deployer.AppDeployer;
|
||||
import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryAppManager;
|
||||
import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryOperationsUtils;
|
||||
import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryAppDeployer;
|
||||
import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryAppManager;
|
||||
import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryDeploymentProperties;
|
||||
import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryOAuth2Client;
|
||||
import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryOperationsUtils;
|
||||
import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryTargetProperties;
|
||||
import org.springframework.cloud.appbroker.manager.AppManager;
|
||||
import org.springframework.cloud.appbroker.oauth2.OAuth2Client;
|
||||
@@ -55,59 +55,108 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Auto-configuration support for deploying apps to Cloud Foundry
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty(CloudFoundryAppDeployerAutoConfiguration.PROPERTY_PREFIX + ".api-host")
|
||||
@EnableConfigurationProperties
|
||||
public class CloudFoundryAppDeployerAutoConfiguration {
|
||||
static final String PROPERTY_PREFIX = "spring.cloud.appbroker.deployer.cloudfoundry";
|
||||
|
||||
protected static final String PROPERTY_PREFIX = "spring.cloud.appbroker.deployer.cloudfoundry";
|
||||
|
||||
/**
|
||||
* Provide a {@link CloudFoundryDeploymentProperties} bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
@ConfigurationProperties(PROPERTY_PREFIX + ".properties")
|
||||
CloudFoundryDeploymentProperties cloudFoundryDeploymentProperties() {
|
||||
public CloudFoundryDeploymentProperties cloudFoundryDeploymentProperties() {
|
||||
return new CloudFoundryDeploymentProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link CloudFoundryTargetProperties} bean
|
||||
*
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
@ConfigurationProperties(PROPERTY_PREFIX)
|
||||
CloudFoundryTargetProperties cloudFoundryTargetProperties() {
|
||||
public CloudFoundryTargetProperties cloudFoundryTargetProperties() {
|
||||
return new CloudFoundryTargetProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link AppDeployer} bean
|
||||
*
|
||||
* @param deploymentProperties the CloudFoundryDeploymentProperties bean
|
||||
* @param cloudFoundryOperations the CloudFoundryOperations bean
|
||||
* @param cloudFoundryClient the CloudFoundryClient bean
|
||||
* @param operationsUtils the CloudFoundryOperationsUtils bean
|
||||
* @param targetProperties the CloudFoundryTargetProperties bean
|
||||
* @param resourceLoader the ResourceLoader bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
AppDeployer cloudFoundryAppDeployer(CloudFoundryDeploymentProperties deploymentProperties,
|
||||
CloudFoundryOperations cloudFoundryOperations,
|
||||
CloudFoundryClient cloudFoundryClient,
|
||||
CloudFoundryOperationsUtils operationsUtils,
|
||||
CloudFoundryTargetProperties targetProperties,
|
||||
ResourceLoader resourceLoader) {
|
||||
public AppDeployer cloudFoundryAppDeployer(CloudFoundryDeploymentProperties deploymentProperties,
|
||||
CloudFoundryOperations cloudFoundryOperations, CloudFoundryClient cloudFoundryClient,
|
||||
CloudFoundryOperationsUtils operationsUtils, CloudFoundryTargetProperties targetProperties,
|
||||
ResourceLoader resourceLoader) {
|
||||
return new CloudFoundryAppDeployer(deploymentProperties, cloudFoundryOperations, cloudFoundryClient,
|
||||
operationsUtils, targetProperties, resourceLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an {@link AppManager} bean
|
||||
*
|
||||
* @param cloudFoundryOperationsUtils the CloudFoundryOperationsUtils bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
AppManager cloudFoundryAppManager(CloudFoundryOperationsUtils cloudFoundryOperationsUtils) {
|
||||
public AppManager cloudFoundryAppManager(CloudFoundryOperationsUtils cloudFoundryOperationsUtils) {
|
||||
return new CloudFoundryAppManager(cloudFoundryOperationsUtils);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an {@link OAuth2Client} bean
|
||||
*
|
||||
* @param uaaClient the UaaClient bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
OAuth2Client cloudFoundryOAuth2Client(@UaaClientQualifier UaaClient uaaClient) {
|
||||
public OAuth2Client cloudFoundryOAuth2Client(@UaaClientQualifier UaaClient uaaClient) {
|
||||
return new CloudFoundryOAuth2Client(uaaClient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link ReactorCloudFoundryClient} bean
|
||||
*
|
||||
* @param connectionContext the ConnectionContext bean
|
||||
* @param tokenProvider the TokenProvider bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
ReactorCloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext,
|
||||
@TokenQualifier TokenProvider tokenProvider) {
|
||||
public ReactorCloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext,
|
||||
@TokenQualifier TokenProvider tokenProvider) {
|
||||
return ReactorCloudFoundryClient.builder()
|
||||
.connectionContext(connectionContext)
|
||||
.tokenProvider(tokenProvider)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link CloudFoundryOperations} bean
|
||||
*
|
||||
* @param properties the CloudFoundryTargetProperties bean
|
||||
* @param client the CloudFoundryClient bean
|
||||
* @param dopplerClient the DopplerClient bean
|
||||
* @param uaaClient the UaaClient bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
CloudFoundryOperations cloudFoundryOperations(CloudFoundryTargetProperties properties,
|
||||
CloudFoundryClient client,
|
||||
DopplerClient dopplerClient,
|
||||
@UaaClientQualifier UaaClient uaaClient) {
|
||||
public CloudFoundryOperations cloudFoundryOperations(CloudFoundryTargetProperties properties,
|
||||
CloudFoundryClient client, DopplerClient dopplerClient, @UaaClientQualifier UaaClient uaaClient) {
|
||||
return DefaultCloudFoundryOperations.builder()
|
||||
.cloudFoundryClient(client)
|
||||
.dopplerClient(dopplerClient)
|
||||
@@ -117,13 +166,25 @@ public class CloudFoundryAppDeployerAutoConfiguration {
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link CloudFoundryOperationsUtils} bean
|
||||
*
|
||||
* @param operations the CloudFoundryOperations bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
CloudFoundryOperationsUtils cloudFoundryOperationsUtils(CloudFoundryOperations operations) {
|
||||
public CloudFoundryOperationsUtils cloudFoundryOperationsUtils(CloudFoundryOperations operations) {
|
||||
return new CloudFoundryOperationsUtils(operations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link DefaultConnectionContext} bean
|
||||
*
|
||||
* @param properties the CloudFoundryTargetProperties bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
DefaultConnectionContext connectionContext(CloudFoundryTargetProperties properties) {
|
||||
public DefaultConnectionContext connectionContext(CloudFoundryTargetProperties properties) {
|
||||
return DefaultConnectionContext.builder()
|
||||
.apiHost(properties.getApiHost())
|
||||
.port(Optional.ofNullable(properties.getApiPort()))
|
||||
@@ -132,22 +193,35 @@ public class CloudFoundryAppDeployerAutoConfiguration {
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link ReactorDopplerClient} bean
|
||||
*
|
||||
* @param connectionContext the ConnectionContext bean
|
||||
* @param tokenProvider the TokenProvider bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
ReactorDopplerClient dopplerClient(ConnectionContext connectionContext,
|
||||
@TokenQualifier TokenProvider tokenProvider) {
|
||||
public ReactorDopplerClient dopplerClient(ConnectionContext connectionContext,
|
||||
@TokenQualifier TokenProvider tokenProvider) {
|
||||
return ReactorDopplerClient.builder()
|
||||
.connectionContext(connectionContext)
|
||||
.tokenProvider(tokenProvider)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link TokenProvider} bean
|
||||
*
|
||||
* @param properties the CloudFoundryTargetProperties bean
|
||||
* @return the bean
|
||||
*/
|
||||
@TokenQualifier
|
||||
@Bean
|
||||
TokenProvider uaaTokenProvider(CloudFoundryTargetProperties properties) {
|
||||
public TokenProvider uaaTokenProvider(CloudFoundryTargetProperties properties) {
|
||||
boolean isClientIdAndSecretSet = Stream.of(properties.getClientId(), properties.getClientSecret())
|
||||
.allMatch(StringUtils::hasText);
|
||||
.allMatch(StringUtils::hasText);
|
||||
boolean isUsernameAndPasswordSet = Stream.of(properties.getUsername(), properties.getPassword())
|
||||
.allMatch(StringUtils::hasText);
|
||||
.allMatch(StringUtils::hasText);
|
||||
if (isClientIdAndSecretSet && isUsernameAndPasswordSet) {
|
||||
throw new IllegalStateException(
|
||||
String.format("(%1$s.client_id / %1$s.client_secret) must not be set when\n" +
|
||||
@@ -155,16 +229,16 @@ public class CloudFoundryAppDeployerAutoConfiguration {
|
||||
}
|
||||
else if (isClientIdAndSecretSet) {
|
||||
return ClientCredentialsGrantTokenProvider.builder()
|
||||
.clientId(properties.getClientId())
|
||||
.clientSecret(properties.getClientSecret())
|
||||
.identityZoneSubdomain(properties.getIdentityZoneSubdomain())
|
||||
.build();
|
||||
.clientId(properties.getClientId())
|
||||
.clientSecret(properties.getClientSecret())
|
||||
.identityZoneSubdomain(properties.getIdentityZoneSubdomain())
|
||||
.build();
|
||||
}
|
||||
else if (isUsernameAndPasswordSet) {
|
||||
return PasswordGrantTokenProvider.builder()
|
||||
.password(properties.getPassword())
|
||||
.username(properties.getUsername())
|
||||
.build();
|
||||
.password(properties.getPassword())
|
||||
.username(properties.getUsername())
|
||||
.build();
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
@@ -173,10 +247,17 @@ public class CloudFoundryAppDeployerAutoConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link ReactorUaaClient} bean
|
||||
*
|
||||
* @param connectionContext the ConnectionContext bean
|
||||
* @param tokenProvider the TokenProvider bean
|
||||
* @return the bean
|
||||
*/
|
||||
@UaaClientQualifier
|
||||
@Bean
|
||||
ReactorUaaClient uaaClient(ConnectionContext connectionContext,
|
||||
@TokenQualifier TokenProvider tokenProvider) {
|
||||
public ReactorUaaClient uaaClient(ConnectionContext connectionContext,
|
||||
@TokenQualifier TokenProvider tokenProvider) {
|
||||
return ReactorUaaClient.builder()
|
||||
.connectionContext(connectionContext)
|
||||
.tokenProvider(tokenProvider)
|
||||
@@ -189,13 +270,16 @@ public class CloudFoundryAppDeployerAutoConfiguration {
|
||||
public @interface TokenQualifier {
|
||||
|
||||
String value() default "appBrokerTokenProvider";
|
||||
|
||||
}
|
||||
|
||||
@Qualifier
|
||||
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface UaaClientQualifier {
|
||||
public @interface UaaClientQualifier {
|
||||
|
||||
String value() default "appBrokerUaaClientQualifier";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.credhub.autoconfig.CredHubTemplateAutoConfiguration;
|
||||
import org.springframework.credhub.core.CredHubOperations;
|
||||
|
||||
/**
|
||||
* CredHub auto-configuration
|
||||
*/
|
||||
@Configuration
|
||||
@AutoConfigureBefore(AppBrokerAutoConfiguration.class)
|
||||
@AutoConfigureAfter(CredHubTemplateAutoConfiguration.class)
|
||||
@@ -41,16 +44,36 @@ public class CredHubAutoConfiguration {
|
||||
@Value("${spring.application.name}")
|
||||
private String appName;
|
||||
|
||||
/**
|
||||
* Provide a {@link CreateServiceInstanceAppBindingWorkflow} bean
|
||||
*
|
||||
* @param credHubOperations the CredHubOperations bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public CreateServiceInstanceAppBindingWorkflow credhubPersistingCreateServiceInstanceAppBindingWorkflow(CredHubOperations credHubOperations) {
|
||||
public CreateServiceInstanceAppBindingWorkflow credhubPersistingCreateServiceInstanceAppBindingWorkflow(
|
||||
CredHubOperations credHubOperations) {
|
||||
return new CredHubPersistingCreateServiceInstanceAppBindingWorkflow(credHubOperations, appName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link DeleteServiceInstanceBindingWorkflow} bean
|
||||
*
|
||||
* @param credHubOperations the CredHubOperations bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public DeleteServiceInstanceBindingWorkflow credhubPersistingDeleteServiceInstanceAppBindingWorkflow(CredHubOperations credHubOperations) {
|
||||
public DeleteServiceInstanceBindingWorkflow credhubPersistingDeleteServiceInstanceAppBindingWorkflow(
|
||||
CredHubOperations credHubOperations) {
|
||||
return new CredHubPersistingDeleteServiceInstanceBindingWorkflow(credHubOperations, appName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a {@link CredHubCredentialsGenerator} bean
|
||||
*
|
||||
* @param credHubOperations the CredHubOperations bean
|
||||
* @return the bean
|
||||
*/
|
||||
@Bean
|
||||
public CredHubCredentialsGenerator credHubCredentialsGenerator(CredHubOperations credHubOperations) {
|
||||
return new CredHubCredentialsGenerator(credHubOperations);
|
||||
|
||||
@@ -266,10 +266,12 @@ class AppBrokerAutoConfigurationTest {
|
||||
public ServiceInstanceBindingService serviceInstanceBindingService() {
|
||||
return new TestServiceInstanceBindingService();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class CustomStateRepositoriesConfiguration {
|
||||
|
||||
@Bean
|
||||
public ServiceInstanceStateRepository serviceInstanceStateRepository() {
|
||||
return new TestServiceInstanceStateRepository();
|
||||
@@ -279,6 +281,7 @@ class AppBrokerAutoConfigurationTest {
|
||||
public ServiceInstanceBindingStateRepository serviceInstanceBindingStateRepository() {
|
||||
return new TestServiceInstanceBindingStateRepository();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TestServiceInstanceBindingService implements ServiceInstanceBindingService {
|
||||
@@ -287,4 +290,5 @@ class AppBrokerAutoConfigurationTest {
|
||||
private static class TestServiceInstanceStateRepository implements ServiceInstanceStateRepository {}
|
||||
|
||||
private static class TestServiceInstanceBindingStateRepository implements ServiceInstanceBindingStateRepository {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -69,7 +69,8 @@ class CloudFoundryAppDeployerAutoConfigurationTest {
|
||||
assertThat(targetProperties.getPassword()).isEqualTo("secret");
|
||||
|
||||
assertThat(context).hasSingleBean(CloudFoundryDeploymentProperties.class);
|
||||
CloudFoundryDeploymentProperties deploymentProperties = context.getBean(CloudFoundryDeploymentProperties.class);
|
||||
CloudFoundryDeploymentProperties deploymentProperties = context
|
||||
.getBean(CloudFoundryDeploymentProperties.class);
|
||||
assertThat(deploymentProperties.getMemory()).isEqualTo("2G");
|
||||
assertThat(deploymentProperties.getCount()).isEqualTo(3);
|
||||
assertThat(deploymentProperties.getBuildpack()).isEqualTo("example-buildpack");
|
||||
@@ -139,4 +140,4 @@ class CloudFoundryAppDeployerAutoConfigurationTest {
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.appbroker.autoconfigure;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
@@ -80,10 +81,12 @@ class CredHubAutoConfigurationTest {
|
||||
|
||||
@TestConfiguration
|
||||
public static class CredHubConfiguration {
|
||||
|
||||
@Bean
|
||||
public CredHubOperations credHubOperations() {
|
||||
return mock(CredHubOperations.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,36 @@ import java.util.List;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
/**
|
||||
* This interface is implemented by service brokers to process requests to deploy, update, and undeploy backing
|
||||
* applications associated with a service instance.
|
||||
*/
|
||||
public interface BackingAppDeploymentService {
|
||||
|
||||
/**
|
||||
* Deploy the backing applications and associate with the service instance
|
||||
*
|
||||
* @param backingApps a collection of backing applications
|
||||
* @param serviceInstanceId the service instance ID
|
||||
* @return a set of strings, where each corresponds to an application e.g. the application name
|
||||
*/
|
||||
Flux<String> deploy(List<BackingApplication> backingApps, String serviceInstanceId);
|
||||
|
||||
/**
|
||||
* Update the backing applications and associate with the service instance
|
||||
*
|
||||
* @param backingApps a collection of backing applications
|
||||
* @param serviceInstanceId the service instance ID
|
||||
* @return a set of strings, where each corresponds to an application. e.g. the application name
|
||||
*/
|
||||
Flux<String> update(List<BackingApplication> backingApps, String serviceInstanceId);
|
||||
|
||||
/**
|
||||
* Undeploy the backing applications
|
||||
*
|
||||
* @param backingApps a collection of backing applications
|
||||
* @return a set of strings, where each corresponds to an application. e.g. the application name
|
||||
*/
|
||||
Flux<String> undeploy(List<BackingApplication> backingApps);
|
||||
|
||||
}
|
||||
|
||||
@@ -26,28 +26,48 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* An application deployed as part of the service provisioning process
|
||||
*/
|
||||
@SuppressWarnings("PMD.GodClass")
|
||||
public class BackingApplication {
|
||||
|
||||
private static final String VALUE_HIDDEN = "<value hidden>";
|
||||
|
||||
private String name;
|
||||
|
||||
private String path;
|
||||
|
||||
private Map<String, String> properties;
|
||||
|
||||
private Map<String, Object> environment;
|
||||
|
||||
private List<ServicesSpec> services;
|
||||
|
||||
private List<ParametersTransformerSpec> parametersTransformers;
|
||||
|
||||
private List<CredentialProviderSpec> credentialProviders;
|
||||
|
||||
private BackingApplication() {
|
||||
}
|
||||
|
||||
BackingApplication(String name, String path,
|
||||
Map<String, String> properties,
|
||||
Map<String, Object> environment,
|
||||
List<ServicesSpec> services,
|
||||
List<ParametersTransformerSpec> parametersTransformers,
|
||||
List<CredentialProviderSpec> credentialProviders) {
|
||||
/**
|
||||
* Construct a new {@link BackingApplication}
|
||||
*
|
||||
* @param name the name of the application
|
||||
* @param path the path to the application
|
||||
* @param properties the properties
|
||||
* @param environment the environment variables
|
||||
* @param services the services required by the application
|
||||
* @param parametersTransformers the parameter transformers
|
||||
* @param credentialProviders the credential providers
|
||||
*/
|
||||
public BackingApplication(String name, String path,
|
||||
Map<String, String> properties,
|
||||
Map<String, Object> environment,
|
||||
List<ServicesSpec> services,
|
||||
List<ParametersTransformerSpec> parametersTransformers,
|
||||
List<CredentialProviderSpec> credentialProviders) {
|
||||
this.name = name;
|
||||
this.path = path;
|
||||
this.properties = properties;
|
||||
@@ -81,6 +101,12 @@ public class BackingApplication {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single property
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
*/
|
||||
public void addProperty(String key, String value) {
|
||||
this.properties.put(key, value);
|
||||
}
|
||||
@@ -93,6 +119,12 @@ public class BackingApplication {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single environment value
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
*/
|
||||
public void addEnvironment(String key, Object value) {
|
||||
environment.put(key, value);
|
||||
}
|
||||
@@ -121,6 +153,11 @@ public class BackingApplication {
|
||||
this.credentialProviders = credentialProviders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a builder that provides a fluent API for constructing a {@literal BackingApplication}.
|
||||
*
|
||||
* @return the builder
|
||||
*/
|
||||
public static BackingApplicationBuilder builder() {
|
||||
return new BackingApplicationBuilder();
|
||||
}
|
||||
@@ -145,8 +182,7 @@ public class BackingApplication {
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return Objects.hash(name, path, properties, environment, services,
|
||||
parametersTransformers, credentialProviders);
|
||||
return Objects.hash(name, path, properties, environment, services, parametersTransformers, credentialProviders);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -173,7 +209,10 @@ public class BackingApplication {
|
||||
return sanitizedEnvironment;
|
||||
}
|
||||
|
||||
public static class BackingApplicationBuilder {
|
||||
/**
|
||||
* Provides a fluent API for constructing a {@literal BackingApplication}.
|
||||
*/
|
||||
public static final class BackingApplicationBuilder {
|
||||
|
||||
private String name;
|
||||
|
||||
@@ -189,48 +228,73 @@ public class BackingApplication {
|
||||
|
||||
private final List<CredentialProviderSpec> credentialProviders = new ArrayList<>();
|
||||
|
||||
BackingApplicationBuilder() {
|
||||
private BackingApplicationBuilder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a backing application based on another application definition
|
||||
*
|
||||
* @param backingApplication the backing application from which to copy properties
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder backingApplication(BackingApplication backingApplication) {
|
||||
this.name(backingApplication.getName())
|
||||
.path(backingApplication.getPath())
|
||||
.properties(backingApplication.getProperties())
|
||||
.environment(backingApplication.getEnvironment());
|
||||
if (!CollectionUtils.isEmpty(backingApplication.getServices())) {
|
||||
this.services(backingApplication.getServices().stream()
|
||||
.map(spec -> ServicesSpec.builder()
|
||||
.spec(spec)
|
||||
.build())
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(backingApplication.getParametersTransformers())) {
|
||||
this.parameterTransformers(backingApplication.getParametersTransformers().stream()
|
||||
.map(spec -> ParametersTransformerSpec.builder()
|
||||
.spec(spec)
|
||||
.build())
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(backingApplication.getCredentialProviders())) {
|
||||
this.credentialProviders(backingApplication.getCredentialProviders().stream()
|
||||
.map(spec -> CredentialProviderSpec.builder()
|
||||
.spec(spec)
|
||||
.build())
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
return this;
|
||||
if (!CollectionUtils.isEmpty(backingApplication.getServices())) {
|
||||
this.services(backingApplication.getServices().stream()
|
||||
.map(spec -> ServicesSpec.builder()
|
||||
.spec(spec)
|
||||
.build())
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(backingApplication.getParametersTransformers())) {
|
||||
this.parameterTransformers(backingApplication.getParametersTransformers().stream()
|
||||
.map(spec -> ParametersTransformerSpec.builder()
|
||||
.spec(spec)
|
||||
.build())
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(backingApplication.getCredentialProviders())) {
|
||||
this.credentialProviders(backingApplication.getCredentialProviders().stream()
|
||||
.map(spec -> CredentialProviderSpec.builder()
|
||||
.spec(spec)
|
||||
.build())
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the application
|
||||
*
|
||||
* @param name the name
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The path to the application
|
||||
*
|
||||
* @param path the path
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder path(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Properties that describe the application
|
||||
*
|
||||
* @param key the property key
|
||||
* @param value the property value
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder property(String key, String value) {
|
||||
if (key != null && value != null) {
|
||||
this.properties.put(key, value);
|
||||
@@ -238,6 +302,12 @@ public class BackingApplication {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Properties that describe the application
|
||||
*
|
||||
* @param properties the properties
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder properties(Map<String, String> properties) {
|
||||
if (!CollectionUtils.isEmpty(properties)) {
|
||||
this.properties.putAll(properties);
|
||||
@@ -245,6 +315,13 @@ public class BackingApplication {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Environment variables to be set for the application
|
||||
*
|
||||
* @param key the env var key
|
||||
* @param value the env var value
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder environment(String key, String value) {
|
||||
if (key != null && value != null) {
|
||||
this.environment.put(key, value);
|
||||
@@ -252,6 +329,12 @@ public class BackingApplication {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Environment variables to be set for the application
|
||||
*
|
||||
* @param environment the env vars
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder environment(Map<String, Object> environment) {
|
||||
if (!CollectionUtils.isEmpty(environment)) {
|
||||
this.environment.putAll(environment);
|
||||
@@ -259,6 +342,12 @@ public class BackingApplication {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Services required by the application
|
||||
*
|
||||
* @param services the services
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder services(List<ServicesSpec> services) {
|
||||
if (!CollectionUtils.isEmpty(services)) {
|
||||
this.services.addAll(services);
|
||||
@@ -266,6 +355,12 @@ public class BackingApplication {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Services required by the application
|
||||
*
|
||||
* @param services the services
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder services(ServicesSpec... services) {
|
||||
if (services != null) {
|
||||
this.services(Arrays.asList(services));
|
||||
@@ -273,6 +368,12 @@ public class BackingApplication {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameter transformers for the application
|
||||
*
|
||||
* @param parameterTransformers the parameter transformers
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder parameterTransformers(List<ParametersTransformerSpec> parameterTransformers) {
|
||||
if (!CollectionUtils.isEmpty(parameterTransformers)) {
|
||||
this.parameterTransformers.addAll(parameterTransformers);
|
||||
@@ -280,6 +381,12 @@ public class BackingApplication {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameter transformers for the application
|
||||
*
|
||||
* @param parameterTransformers the parameter transformers
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder parameterTransformers(ParametersTransformerSpec... parameterTransformers) {
|
||||
if (parameterTransformers != null) {
|
||||
this.parameterTransformers(Arrays.asList(parameterTransformers));
|
||||
@@ -287,6 +394,12 @@ public class BackingApplication {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Credential providers for the application
|
||||
*
|
||||
* @param credentialProviders the credential providers
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder credentialProviders(List<CredentialProviderSpec> credentialProviders) {
|
||||
if (!CollectionUtils.isEmpty(credentialProviders)) {
|
||||
this.credentialProviders.addAll(credentialProviders);
|
||||
@@ -294,6 +407,12 @@ public class BackingApplication {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Credential providers for the backing application
|
||||
*
|
||||
* @param credentialProviders the credential providers
|
||||
* @return the builder
|
||||
*/
|
||||
public BackingApplicationBuilder credentialProviders(CredentialProviderSpec... credentialProviders) {
|
||||
if (credentialProviders != null) {
|
||||
this.credentialProviders(Arrays.asList(credentialProviders));
|
||||
@@ -301,9 +420,16 @@ public class BackingApplication {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@link BackingApplication} from the provided values.
|
||||
*
|
||||
* @return the newly constructed {@literal BackingApplication}
|
||||
*/
|
||||
public BackingApplication build() {
|
||||
return new BackingApplication(name, path, properties, environment, services,
|
||||
parameterTransformers, credentialProviders);
|
||||
return new BackingApplication(name, path, properties, environment, services, parameterTransformers,
|
||||
credentialProviders);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,12 +22,15 @@ import java.util.List;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
public class BackingApplications extends ArrayList<BackingApplication> {
|
||||
|
||||
private static final long serialVersionUID = 159473836238657105L;
|
||||
|
||||
private BackingApplications() {
|
||||
super();
|
||||
}
|
||||
|
||||
BackingApplications(List<BackingApplication> backingApplications) {
|
||||
public BackingApplications(List<BackingApplication> backingApplications) {
|
||||
super();
|
||||
super.addAll(backingApplications);
|
||||
}
|
||||
|
||||
@@ -35,7 +38,8 @@ public class BackingApplications extends ArrayList<BackingApplication> {
|
||||
return new BackingApplicationsBuilder();
|
||||
}
|
||||
|
||||
public static class BackingApplicationsBuilder {
|
||||
public static final class BackingApplicationsBuilder {
|
||||
|
||||
private final List<BackingApplication> backingApplications = new ArrayList<>();
|
||||
|
||||
public BackingApplicationsBuilder backingApplication(BackingApplication backingApplication) {
|
||||
@@ -57,5 +61,7 @@ public class BackingApplications extends ArrayList<BackingApplication> {
|
||||
public BackingApplications build() {
|
||||
return new BackingApplications(backingApplications);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,23 +28,29 @@ import org.springframework.util.CollectionUtils;
|
||||
public class BackingService {
|
||||
|
||||
private String serviceInstanceName;
|
||||
|
||||
private String name;
|
||||
|
||||
private String plan;
|
||||
|
||||
private Map<String, Object> parameters;
|
||||
|
||||
private Map<String, String> properties;
|
||||
|
||||
private List<ParametersTransformerSpec> parametersTransformers;
|
||||
|
||||
private boolean rebindOnUpdate;
|
||||
|
||||
private BackingService() {
|
||||
}
|
||||
|
||||
BackingService(String serviceInstanceName,
|
||||
String name,
|
||||
String plan,
|
||||
Map<String, Object> parameters,
|
||||
Map<String, String> properties,
|
||||
List<ParametersTransformerSpec> parametersTransformers,
|
||||
boolean rebindOnUpdate) {
|
||||
public BackingService(String serviceInstanceName,
|
||||
String name,
|
||||
String plan,
|
||||
Map<String, Object> parameters,
|
||||
Map<String, String> properties,
|
||||
List<ParametersTransformerSpec> parametersTransformers,
|
||||
boolean rebindOnUpdate) {
|
||||
this.serviceInstanceName = serviceInstanceName;
|
||||
this.name = name;
|
||||
this.plan = plan;
|
||||
@@ -134,7 +140,8 @@ public class BackingService {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(serviceInstanceName, name, plan, parameters, properties, parametersTransformers, rebindOnUpdate);
|
||||
return Objects
|
||||
.hash(serviceInstanceName, name, plan, parameters, properties, parametersTransformers, rebindOnUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,14 +164,20 @@ public class BackingService {
|
||||
public static final class BackingServiceBuilder {
|
||||
|
||||
private String serviceInstanceName;
|
||||
|
||||
private String name;
|
||||
|
||||
private String plan;
|
||||
|
||||
private final Map<String, Object> parameters = new HashMap<>();
|
||||
|
||||
private final Map<String, String> properties = new HashMap<>();
|
||||
|
||||
private final List<ParametersTransformerSpec> parameterTransformers = new ArrayList<>();
|
||||
|
||||
private boolean rebindOnUpdate;
|
||||
|
||||
BackingServiceBuilder() {
|
||||
private BackingServiceBuilder() {
|
||||
}
|
||||
|
||||
public BackingServiceBuilder backingService(BackingService backingService) {
|
||||
@@ -226,8 +239,10 @@ public class BackingService {
|
||||
}
|
||||
|
||||
public BackingService build() {
|
||||
return new BackingService(serviceInstanceName, name, plan, parameters, properties, parameterTransformers, rebindOnUpdate);
|
||||
return new BackingService(serviceInstanceName, name, plan, parameters, properties, parameterTransformers,
|
||||
rebindOnUpdate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,10 +26,11 @@ public class BackingServices extends ArrayList<BackingService> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private BackingServices() {
|
||||
super();
|
||||
}
|
||||
|
||||
BackingServices(List<BackingService> backingServices) {
|
||||
super.addAll(backingServices);
|
||||
public BackingServices(List<BackingService> backingServices) {
|
||||
super(backingServices);
|
||||
}
|
||||
|
||||
public static BackingServicesBuilder builder() {
|
||||
@@ -59,5 +60,7 @@ public class BackingServices extends ArrayList<BackingService> {
|
||||
public BackingServices build() {
|
||||
return new BackingServices(backingServices);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,4 +27,5 @@ public interface BackingServicesProvisionService {
|
||||
Flux<String> updateServiceInstance(List<BackingService> backingServices);
|
||||
|
||||
Flux<String> deleteServiceInstance(List<BackingService> backingServices);
|
||||
|
||||
}
|
||||
|
||||
@@ -23,15 +23,22 @@ import org.springframework.util.CollectionUtils;
|
||||
public class BrokeredService {
|
||||
|
||||
private String serviceName;
|
||||
|
||||
private String planName;
|
||||
|
||||
private BackingApplications apps;
|
||||
|
||||
private BackingServices services;
|
||||
|
||||
private TargetSpec target;
|
||||
|
||||
private BrokeredService() {
|
||||
super();
|
||||
}
|
||||
|
||||
BrokeredService(String serviceName, String planName, BackingApplications apps, BackingServices services, TargetSpec target) {
|
||||
public BrokeredService(String serviceName, String planName, BackingApplications apps, BackingServices services,
|
||||
TargetSpec target) {
|
||||
super();
|
||||
this.serviceName = serviceName;
|
||||
this.planName = planName;
|
||||
this.apps = apps;
|
||||
@@ -118,9 +125,13 @@ public class BrokeredService {
|
||||
public static class BrokeredServiceBuilder {
|
||||
|
||||
private String id;
|
||||
|
||||
private String planId;
|
||||
|
||||
private BackingApplications backingApplications;
|
||||
|
||||
private BackingServices backingServices;
|
||||
|
||||
private TargetSpec target;
|
||||
|
||||
public BrokeredServiceBuilder serviceName(String id) {
|
||||
@@ -159,5 +170,7 @@ public class BrokeredService {
|
||||
public BrokeredService build() {
|
||||
return new BrokeredService(id, planId, backingApplications, backingServices, target);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,13 +22,15 @@ import java.util.List;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
public class BrokeredServices extends ArrayList<BrokeredService> {
|
||||
|
||||
private static final long serialVersionUID = 6303127383252611352L;
|
||||
|
||||
private BrokeredServices() {
|
||||
super();
|
||||
}
|
||||
|
||||
BrokeredServices(List<BrokeredService> brokeredServices) {
|
||||
super.addAll(brokeredServices);
|
||||
public BrokeredServices(List<BrokeredService> brokeredServices) {
|
||||
super(brokeredServices);
|
||||
}
|
||||
|
||||
public static BrokeredServicesBuilder builder() {
|
||||
@@ -36,6 +38,7 @@ public class BrokeredServices extends ArrayList<BrokeredService> {
|
||||
}
|
||||
|
||||
public static class BrokeredServicesBuilder {
|
||||
|
||||
private final List<BrokeredService> brokeredServices = new ArrayList<>();
|
||||
|
||||
public BrokeredServicesBuilder service(BrokeredService brokeredService) {
|
||||
@@ -55,5 +58,7 @@ public class BrokeredServices extends ArrayList<BrokeredService> {
|
||||
public BrokeredServices build() {
|
||||
return new BrokeredServices(brokeredServices);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,12 +24,13 @@ import org.springframework.util.CollectionUtils;
|
||||
public class CredentialProviderSpec {
|
||||
|
||||
private String name;
|
||||
|
||||
private Map<String, Object> args;
|
||||
|
||||
private CredentialProviderSpec() {
|
||||
}
|
||||
|
||||
CredentialProviderSpec(String name, Map<String, Object> args) {
|
||||
public CredentialProviderSpec(String name, Map<String, Object> args) {
|
||||
this.name = name;
|
||||
this.args = args;
|
||||
}
|
||||
@@ -54,13 +55,13 @@ public class CredentialProviderSpec {
|
||||
return new CredentialProviderSpecBuilder();
|
||||
}
|
||||
|
||||
public static class CredentialProviderSpecBuilder {
|
||||
public static final class CredentialProviderSpecBuilder {
|
||||
|
||||
private String name;
|
||||
|
||||
private final Map<String, Object> args = new LinkedHashMap<>();
|
||||
|
||||
CredentialProviderSpecBuilder() {
|
||||
private CredentialProviderSpecBuilder() {
|
||||
}
|
||||
|
||||
public CredentialProviderSpecBuilder spec(CredentialProviderSpec spec) {
|
||||
@@ -90,5 +91,7 @@ public class CredentialProviderSpec {
|
||||
public CredentialProviderSpec build() {
|
||||
return new CredentialProviderSpec(name, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import reactor.util.Logger;
|
||||
import reactor.util.Loggers;
|
||||
|
||||
public class DefaultBackingAppDeploymentService implements BackingAppDeploymentService {
|
||||
|
||||
private final Logger log = Loggers.getLogger(DefaultBackingAppDeploymentService.class);
|
||||
|
||||
private final DeployerClient deployerClient;
|
||||
@@ -56,7 +57,8 @@ public class DefaultBackingAppDeploymentService implements BackingAppDeploymentS
|
||||
.doOnRequest(l -> log.debug("Updating applications {}", backingApps))
|
||||
.doOnEach(response -> log.debug("Finished updating application {}", response))
|
||||
.doOnComplete(() -> log.debug("Finished updating application {}", backingApps))
|
||||
.doOnError(exception -> log.error(String.format("Error updating applications %s with error '%s'", backingApps, exception)));
|
||||
.doOnError(exception -> log
|
||||
.error(String.format("Error updating applications %s with error '%s'", backingApps, exception)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,4 +74,5 @@ public class DefaultBackingAppDeploymentService implements BackingAppDeploymentS
|
||||
.doOnError(exception -> log.error(String.format("Error undeploying applications %s with error '%s'",
|
||||
backingApps, exception.getMessage()), exception));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -74,4 +74,5 @@ public class DefaultBackingServicesProvisionService implements BackingServicesPr
|
||||
.doOnError(exception -> log.error(String.format("Error deleting backing services %s with error '%s'",
|
||||
backingServices, exception.getMessage()), exception));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class DeployerClient {
|
||||
this.appDeployer = appDeployer;
|
||||
}
|
||||
|
||||
Mono<String> deploy(BackingApplication backingApplication, String serviceInstanceId) {
|
||||
public Mono<String> deploy(BackingApplication backingApplication, String serviceInstanceId) {
|
||||
return appDeployer
|
||||
.deploy(DeployApplicationRequest
|
||||
.builder()
|
||||
@@ -52,7 +52,7 @@ public class DeployerClient {
|
||||
.map(DeployApplicationResponse::getName);
|
||||
}
|
||||
|
||||
Mono<String> update(BackingApplication backingApplication, String serviceInstanceId) {
|
||||
public Mono<String> update(BackingApplication backingApplication, String serviceInstanceId) {
|
||||
return appDeployer
|
||||
.update(UpdateApplicationRequest
|
||||
.builder()
|
||||
@@ -72,7 +72,7 @@ public class DeployerClient {
|
||||
.map(UpdateApplicationResponse::getName);
|
||||
}
|
||||
|
||||
Mono<String> undeploy(BackingApplication backingApplication) {
|
||||
public Mono<String> undeploy(BackingApplication backingApplication) {
|
||||
return appDeployer
|
||||
.undeploy(UndeployApplicationRequest
|
||||
.builder()
|
||||
@@ -89,7 +89,7 @@ public class DeployerClient {
|
||||
.map(UndeployApplicationResponse::getName);
|
||||
}
|
||||
|
||||
Mono<String> createServiceInstance(BackingService backingService) {
|
||||
public Mono<String> createServiceInstance(BackingService backingService) {
|
||||
return appDeployer
|
||||
.createServiceInstance(
|
||||
CreateServiceInstanceRequest
|
||||
@@ -107,7 +107,7 @@ public class DeployerClient {
|
||||
.map(CreateServiceInstanceResponse::getName);
|
||||
}
|
||||
|
||||
Mono<String> updateServiceInstance(BackingService backingService) {
|
||||
public Mono<String> updateServiceInstance(BackingService backingService) {
|
||||
return appDeployer
|
||||
.updateServiceInstance(
|
||||
UpdateServiceInstanceRequest
|
||||
@@ -124,7 +124,7 @@ public class DeployerClient {
|
||||
.map(UpdateServiceInstanceResponse::getName);
|
||||
}
|
||||
|
||||
Mono<String> deleteServiceInstance(BackingService backingService) {
|
||||
public Mono<String> deleteServiceInstance(BackingService backingService) {
|
||||
return appDeployer
|
||||
.deleteServiceInstance(
|
||||
DeleteServiceInstanceRequest
|
||||
@@ -141,4 +141,5 @@ public class DeployerClient {
|
||||
.build())
|
||||
.map(DeleteServiceInstanceResponse::getName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class ParametersTransformerSpec {
|
||||
private ParametersTransformerSpec() {
|
||||
}
|
||||
|
||||
ParametersTransformerSpec(String name, Map<String, Object> args) {
|
||||
public ParametersTransformerSpec(String name, Map<String, Object> args) {
|
||||
this.name = name;
|
||||
this.args = args;
|
||||
}
|
||||
@@ -55,13 +55,13 @@ public class ParametersTransformerSpec {
|
||||
return new ParametersTransformerSpecBuilder();
|
||||
}
|
||||
|
||||
public static class ParametersTransformerSpecBuilder {
|
||||
public static final class ParametersTransformerSpecBuilder {
|
||||
|
||||
private String name;
|
||||
|
||||
private final Map<String, Object> args = new LinkedHashMap<>();
|
||||
|
||||
ParametersTransformerSpecBuilder() {
|
||||
private ParametersTransformerSpecBuilder() {
|
||||
}
|
||||
|
||||
public ParametersTransformerSpecBuilder spec(ParametersTransformerSpec spec) {
|
||||
@@ -91,5 +91,7 @@ public class ParametersTransformerSpec {
|
||||
public ParametersTransformerSpec build() {
|
||||
return new ParametersTransformerSpec(name, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public class ServicesSpec {
|
||||
private ServicesSpec() {
|
||||
}
|
||||
|
||||
ServicesSpec(String serviceInstanceName) {
|
||||
public ServicesSpec(String serviceInstanceName) {
|
||||
this.serviceInstanceName = serviceInstanceName;
|
||||
}
|
||||
|
||||
@@ -39,11 +39,11 @@ public class ServicesSpec {
|
||||
return new ServicesSpecBuilder();
|
||||
}
|
||||
|
||||
public static class ServicesSpecBuilder {
|
||||
public static final class ServicesSpecBuilder {
|
||||
|
||||
private String serviceInstanceName;
|
||||
|
||||
ServicesSpecBuilder() {
|
||||
private ServicesSpecBuilder() {
|
||||
}
|
||||
|
||||
public ServicesSpecBuilder spec(ServicesSpec spec) {
|
||||
@@ -58,5 +58,7 @@ public class ServicesSpec {
|
||||
public ServicesSpec build() {
|
||||
return new ServicesSpec(serviceInstanceName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public class TargetSpec {
|
||||
private TargetSpec() {
|
||||
}
|
||||
|
||||
TargetSpec(String name) {
|
||||
public TargetSpec(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -40,11 +40,11 @@ public class TargetSpec {
|
||||
return new TargetSpecBuilder();
|
||||
}
|
||||
|
||||
public static class TargetSpecBuilder {
|
||||
public static final class TargetSpecBuilder {
|
||||
|
||||
private String name;
|
||||
|
||||
TargetSpecBuilder() {
|
||||
private TargetSpecBuilder() {
|
||||
}
|
||||
|
||||
public TargetSpecBuilder name(String name) {
|
||||
@@ -55,5 +55,7 @@ public class TargetSpec {
|
||||
public TargetSpec build() {
|
||||
return new TargetSpec(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.extensions;
|
||||
|
||||
import org.springframework.cloud.appbroker.extensions.support.ConfigurationBeanUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.cloud.appbroker.extensions.support.ConfigurationBeanUtils;
|
||||
|
||||
public abstract class AbstractExtensionFactory<T, C> implements ExtensionFactory<T, C> {
|
||||
|
||||
private Class<C> configClass;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -42,6 +43,7 @@ public abstract class AbstractExtensionFactory<T, C> implements ExtensionFactory
|
||||
return create(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T createWithConfig(Map<String, Object> args) {
|
||||
C config = ConfigurationBeanUtils.instantiate(this.configClass);
|
||||
ConfigurationBeanUtils.populate(config, args);
|
||||
@@ -51,4 +53,5 @@ public abstract class AbstractExtensionFactory<T, C> implements ExtensionFactory
|
||||
protected String getShortName(Class<?> cls) {
|
||||
return getClass().getSimpleName().replace(cls.getSimpleName(), "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,4 +30,5 @@ public interface ExtensionFactory<T, C> {
|
||||
default String getName() {
|
||||
throw new UnsupportedOperationException("getName() not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,14 +16,15 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.extensions;
|
||||
|
||||
import org.springframework.cloud.servicebroker.exception.ServiceBrokerException;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.servicebroker.exception.ServiceBrokerException;
|
||||
|
||||
public class ExtensionLocator<T> {
|
||||
|
||||
private final Map<String, ExtensionFactory<T, ?>> factoriesByName = new HashMap<>();
|
||||
|
||||
public ExtensionLocator(List<? extends ExtensionFactory<T, ?>> factories) {
|
||||
@@ -42,14 +43,16 @@ public class ExtensionLocator<T> {
|
||||
private ExtensionFactory<T, ?> getFactoryByName(String name) {
|
||||
if (factoriesByName.containsKey(name)) {
|
||||
return factoriesByName.get(name);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new ServiceBrokerException("Unknown extension " + name + ". " +
|
||||
"Registered extensions are " + factoriesByName.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
private T getExtensionFromFactory(ExtensionFactory<T, ?> factory,
|
||||
Map<String, Object> args) {
|
||||
Map<String, Object> args) {
|
||||
return factory.createWithConfig(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,10 +18,15 @@ package org.springframework.cloud.appbroker.extensions.credentials;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class CredentialGenerationConfig {
|
||||
|
||||
private int length;
|
||||
|
||||
private boolean includeUppercaseAlpha = true;
|
||||
|
||||
private boolean includeLowercaseAlpha = true;
|
||||
|
||||
private boolean includeNumeric = true;
|
||||
|
||||
private boolean includeSpecial = true;
|
||||
|
||||
public int getLength() {
|
||||
@@ -63,4 +68,5 @@ public class CredentialGenerationConfig {
|
||||
public void setIncludeSpecial(boolean includeSpecial) {
|
||||
this.includeSpecial = includeSpecial;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,14 +22,14 @@ import reactor.util.function.Tuple2;
|
||||
public interface CredentialGenerator {
|
||||
|
||||
Mono<Tuple2<String, String>> generateUser(String applicationId, String serviceInstanceId, String descriptor,
|
||||
int length, boolean includeUppercaseAlpha,
|
||||
boolean includeLowercaseAlpha, boolean includeNumeric,
|
||||
boolean includeSpecial);
|
||||
int length, boolean includeUppercaseAlpha,
|
||||
boolean includeLowercaseAlpha, boolean includeNumeric,
|
||||
boolean includeSpecial);
|
||||
|
||||
Mono<String> generateString(String applicationId, String serviceInstanceId, String descriptor,
|
||||
int length, boolean includeUppercaseAlpha,
|
||||
boolean includeLowercaseAlpha, boolean includeNumeric,
|
||||
boolean includeSpecial);
|
||||
int length, boolean includeUppercaseAlpha,
|
||||
boolean includeLowercaseAlpha, boolean includeNumeric,
|
||||
boolean includeSpecial);
|
||||
|
||||
default Mono<Void> deleteUser(String applicationId, String serviceInstanceId, String descriptor) {
|
||||
return Mono.empty();
|
||||
@@ -38,4 +38,5 @@ public interface CredentialGenerator {
|
||||
default Mono<Void> deleteString(String applicationId, String serviceInstanceId, String descriptor) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,14 +16,17 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.extensions.credentials;
|
||||
|
||||
import org.springframework.cloud.appbroker.deployer.BackingApplication;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.appbroker.deployer.BackingApplication;
|
||||
|
||||
public interface CredentialProvider {
|
||||
|
||||
Mono<BackingApplication> addCredentials(BackingApplication backingApplication, String serviceInstanceGuid);
|
||||
|
||||
default Mono<BackingApplication> deleteCredentials(BackingApplication backingApplication, String serviceInstanceGuid) {
|
||||
default Mono<BackingApplication> deleteCredentials(BackingApplication backingApplication,
|
||||
String serviceInstanceGuid) {
|
||||
return Mono.just(backingApplication);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ public abstract class CredentialProviderFactory<C> extends AbstractExtensionFact
|
||||
@Override
|
||||
public abstract CredentialProvider create(C config);
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getShortName(CredentialProviderFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,14 +16,15 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.extensions.credentials;
|
||||
|
||||
import org.springframework.cloud.appbroker.deployer.BackingApplication;
|
||||
import org.springframework.cloud.appbroker.deployer.CredentialProviderSpec;
|
||||
import org.springframework.cloud.appbroker.extensions.ExtensionLocator;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.springframework.cloud.appbroker.deployer.BackingApplication;
|
||||
import org.springframework.cloud.appbroker.deployer.CredentialProviderSpec;
|
||||
import org.springframework.cloud.appbroker.extensions.ExtensionLocator;
|
||||
|
||||
public class CredentialProviderService {
|
||||
|
||||
@@ -34,7 +35,7 @@ public class CredentialProviderService {
|
||||
}
|
||||
|
||||
public Mono<List<BackingApplication>> addCredentials(List<BackingApplication> backingApplications,
|
||||
String serviceInstanceGuid) {
|
||||
String serviceInstanceGuid) {
|
||||
return Flux.fromIterable(backingApplications)
|
||||
.flatMap(backingApplication -> {
|
||||
List<CredentialProviderSpec> specs = getSpecsForApplication(backingApplication);
|
||||
@@ -50,7 +51,7 @@ public class CredentialProviderService {
|
||||
}
|
||||
|
||||
public Mono<List<BackingApplication>> deleteCredentials(List<BackingApplication> backingApplications,
|
||||
String serviceInstanceGuid) {
|
||||
String serviceInstanceGuid) {
|
||||
return Flux.fromIterable(backingApplications)
|
||||
.flatMap(backingApplication -> {
|
||||
List<CredentialProviderSpec> specs = getSpecsForApplication(backingApplication);
|
||||
@@ -70,4 +71,5 @@ public class CredentialProviderService {
|
||||
? Collections.emptyList()
|
||||
: backingApplication.getCredentialProviders();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,16 +26,20 @@ import reactor.util.function.Tuples;
|
||||
public class SimpleCredentialGenerator implements CredentialGenerator {
|
||||
|
||||
private static final String UPPERCASE_ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
private static final String LOWERCASE_ALPHA = "abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
private static final String DIGITS = "0123456789";
|
||||
|
||||
private static final String SPECIAL_CHARACTERS = "~`!@#$%^&*()-_=+[{]}\\|;:\'\",<.>/?";
|
||||
|
||||
private final SecureRandom secureRandom = new SecureRandom();
|
||||
|
||||
@Override
|
||||
public Mono<Tuple2<String, String>> generateUser(String applicationId, String serviceInstanceId, String descriptor, int length,
|
||||
boolean includeUppercaseAlpha, boolean includeLowercaseAlpha,
|
||||
boolean includeNumeric, boolean includeSpecial) {
|
||||
public Mono<Tuple2<String, String>> generateUser(String applicationId, String serviceInstanceId, String descriptor,
|
||||
int length,
|
||||
boolean includeUppercaseAlpha, boolean includeLowercaseAlpha,
|
||||
boolean includeNumeric, boolean includeSpecial) {
|
||||
return generateString(applicationId, serviceInstanceId, descriptor, length,
|
||||
includeUppercaseAlpha, includeLowercaseAlpha, includeNumeric, includeSpecial)
|
||||
.flatMap(username -> generateString(applicationId, serviceInstanceId, descriptor, length,
|
||||
@@ -45,8 +49,8 @@ public class SimpleCredentialGenerator implements CredentialGenerator {
|
||||
|
||||
@Override
|
||||
public Mono<String> generateString(String applicationId, String serviceInstanceId, String descriptor, int length,
|
||||
boolean includeUppercaseAlpha, boolean includeLowercaseAlpha,
|
||||
boolean includeNumeric, boolean includeSpecial) {
|
||||
boolean includeUppercaseAlpha, boolean includeLowercaseAlpha,
|
||||
boolean includeNumeric, boolean includeSpecial) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
if (includeUppercaseAlpha) {
|
||||
@@ -67,13 +71,14 @@ public class SimpleCredentialGenerator implements CredentialGenerator {
|
||||
|
||||
if (builder.length() == 0) {
|
||||
builder.append(UPPERCASE_ALPHA)
|
||||
.append(LOWERCASE_ALPHA)
|
||||
.append(DIGITS)
|
||||
.append(SPECIAL_CHARACTERS);
|
||||
.append(LOWERCASE_ALPHA)
|
||||
.append(DIGITS)
|
||||
.append(SPECIAL_CHARACTERS);
|
||||
}
|
||||
|
||||
char[] chars = builder.toString().toCharArray();
|
||||
|
||||
return Mono.just(RandomStringUtils.random(length, 0, chars.length - 1, false, false, chars, secureRandom));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,13 +21,20 @@ import reactor.util.function.Tuple2;
|
||||
|
||||
import org.springframework.cloud.appbroker.deployer.BackingApplication;
|
||||
|
||||
public class SpringSecurityBasicAuthCredentialProviderFactory extends
|
||||
CredentialProviderFactory<CredentialGenerationConfig> {
|
||||
public class SpringSecurityBasicAuthCredentialProviderFactory
|
||||
extends CredentialProviderFactory<CredentialGenerationConfig> {
|
||||
|
||||
private static final String CREDENTIAL_DESCRIPTOR = "basic";
|
||||
|
||||
static final String SPRING_SECURITY_USER_NAME_KEY = "spring.security.user.name";
|
||||
static final String SPRING_SECURITY_USER_PASSWORD_KEY = "spring.security.user.password";
|
||||
/**
|
||||
* Key for storing the Spring Security Username in the environment
|
||||
*/
|
||||
public static final String SPRING_SECURITY_USER_NAME_KEY = "spring.security.user.name";
|
||||
|
||||
/**
|
||||
* Key for storing the Spring Security Password in the environment
|
||||
*/
|
||||
public static final String SPRING_SECURITY_USER_PASSWORD_KEY = "spring.security.user.password";
|
||||
|
||||
private final CredentialGenerator credentialGenerator;
|
||||
|
||||
@@ -41,7 +48,7 @@ public class SpringSecurityBasicAuthCredentialProviderFactory extends
|
||||
return new CredentialProvider() {
|
||||
@Override
|
||||
public Mono<BackingApplication> addCredentials(BackingApplication backingApplication,
|
||||
String serviceInstanceGuid) {
|
||||
String serviceInstanceGuid) {
|
||||
return generateCredentials(config, backingApplication, serviceInstanceGuid)
|
||||
.flatMap(user -> addUserToEnvironment(backingApplication, user))
|
||||
.thenReturn(backingApplication);
|
||||
@@ -49,19 +56,21 @@ public class SpringSecurityBasicAuthCredentialProviderFactory extends
|
||||
|
||||
@Override
|
||||
public Mono<BackingApplication> deleteCredentials(BackingApplication backingApplication,
|
||||
String serviceInstanceGuid) {
|
||||
return credentialGenerator.deleteUser(backingApplication.getName(), serviceInstanceGuid, CREDENTIAL_DESCRIPTOR)
|
||||
.thenReturn(backingApplication);
|
||||
String serviceInstanceGuid) {
|
||||
return credentialGenerator
|
||||
.deleteUser(backingApplication.getName(), serviceInstanceGuid, CREDENTIAL_DESCRIPTOR)
|
||||
.thenReturn(backingApplication);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Mono<Tuple2<String, String>> generateCredentials(CredentialGenerationConfig config,
|
||||
BackingApplication backingApplication,
|
||||
String serviceInstanceGuid) {
|
||||
return credentialGenerator.generateUser(backingApplication.getName(), serviceInstanceGuid, CREDENTIAL_DESCRIPTOR,
|
||||
config.getLength(), config.isIncludeUppercaseAlpha(), config.isIncludeLowercaseAlpha(),
|
||||
config.isIncludeNumeric(), config.isIncludeSpecial());
|
||||
BackingApplication backingApplication,
|
||||
String serviceInstanceGuid) {
|
||||
return credentialGenerator
|
||||
.generateUser(backingApplication.getName(), serviceInstanceGuid, CREDENTIAL_DESCRIPTOR,
|
||||
config.getLength(), config.isIncludeUppercaseAlpha(), config.isIncludeLowercaseAlpha(),
|
||||
config.isIncludeNumeric(), config.isIncludeSpecial());
|
||||
}
|
||||
|
||||
private Mono<Void> addUserToEnvironment(BackingApplication backingApplication, Tuple2<String, String> user) {
|
||||
@@ -69,4 +78,5 @@ public class SpringSecurityBasicAuthCredentialProviderFactory extends
|
||||
backingApplication.addEnvironment(SPRING_SECURITY_USER_PASSWORD_KEY, user.getT2());
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.extensions.credentials;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
@@ -32,15 +36,27 @@ public class SpringSecurityOAuth2CredentialProviderFactory extends
|
||||
|
||||
private static final String CREDENTIAL_DESCRIPTOR = "oauth2";
|
||||
|
||||
static final String SPRING_SECURITY_OAUTH2_REGISTRATION_KEY = "spring.security.oauth2.client.registration.";
|
||||
static final String SPRING_SECURITY_OAUTH2_CLIENT_ID_KEY = ".client-id";
|
||||
static final String SPRING_SECURITY_OAUTH2_CLIENT_SECRET_KEY = ".client-secret";
|
||||
/**
|
||||
* Key for storing the Spring Security OAuth2 Registration in the environment
|
||||
*/
|
||||
public static final String SPRING_SECURITY_OAUTH2_REGISTRATION_KEY = "spring.security.oauth2.client.registration.";
|
||||
|
||||
/**
|
||||
* Key for storing the Spring Security OAuth2 Client ID in the environment
|
||||
*/
|
||||
public static final String SPRING_SECURITY_OAUTH2_CLIENT_ID_KEY = ".client-id";
|
||||
|
||||
/**
|
||||
* Key for storing the Spring Security OAuth2 Client Secret in the environment
|
||||
*/
|
||||
public static final String SPRING_SECURITY_OAUTH2_CLIENT_SECRET_KEY = ".client-secret";
|
||||
|
||||
private final CredentialGenerator credentialGenerator;
|
||||
|
||||
private final OAuth2Client oAuth2Client;
|
||||
|
||||
public SpringSecurityOAuth2CredentialProviderFactory(CredentialGenerator credentialGenerator,
|
||||
OAuth2Client oAuth2Client) {
|
||||
OAuth2Client oAuth2Client) {
|
||||
super(Config.class);
|
||||
this.credentialGenerator = credentialGenerator;
|
||||
this.oAuth2Client = oAuth2Client;
|
||||
@@ -51,7 +67,7 @@ public class SpringSecurityOAuth2CredentialProviderFactory extends
|
||||
return new CredentialProvider() {
|
||||
@Override
|
||||
public Mono<BackingApplication> addCredentials(BackingApplication backingApplication,
|
||||
String serviceInstanceGuid) {
|
||||
String serviceInstanceGuid) {
|
||||
return generateCredentials(config, backingApplication, serviceInstanceGuid)
|
||||
.flatMap(client -> addClientToEnvironment(config, backingApplication, client))
|
||||
.flatMap(client -> createOAuth2Client(config, client))
|
||||
@@ -60,8 +76,9 @@ public class SpringSecurityOAuth2CredentialProviderFactory extends
|
||||
|
||||
@Override
|
||||
public Mono<BackingApplication> deleteCredentials(BackingApplication backingApplication,
|
||||
String serviceInstanceGuid) {
|
||||
return credentialGenerator.deleteString(backingApplication.getName(), serviceInstanceGuid, CREDENTIAL_DESCRIPTOR)
|
||||
String serviceInstanceGuid) {
|
||||
return credentialGenerator
|
||||
.deleteString(backingApplication.getName(), serviceInstanceGuid, CREDENTIAL_DESCRIPTOR)
|
||||
.then(generateClientId(config, backingApplication, serviceInstanceGuid))
|
||||
.flatMap(clientId -> deleteOAuth2Client(config, clientId)
|
||||
.flatMap(response -> Mono.just(backingApplication)));
|
||||
@@ -70,16 +87,16 @@ public class SpringSecurityOAuth2CredentialProviderFactory extends
|
||||
}
|
||||
|
||||
private Mono<Tuple2<String, String>> generateCredentials(Config config,
|
||||
BackingApplication backingApplication,
|
||||
String serviceInstanceGuid) {
|
||||
BackingApplication backingApplication,
|
||||
String serviceInstanceGuid) {
|
||||
return generateClientId(config, backingApplication, serviceInstanceGuid)
|
||||
.flatMap(id -> generateClientSecret(config, backingApplication, serviceInstanceGuid)
|
||||
.map(secret -> Tuples.of(id, secret)));
|
||||
}
|
||||
|
||||
private Mono<Tuple2<String, String>> addClientToEnvironment(Config config,
|
||||
BackingApplication backingApplication,
|
||||
Tuple2<String, String> client) {
|
||||
BackingApplication backingApplication,
|
||||
Tuple2<String, String> client) {
|
||||
String registrationKey = SPRING_SECURITY_OAUTH2_REGISTRATION_KEY + config.getRegistration();
|
||||
|
||||
backingApplication.addEnvironment(registrationKey + SPRING_SECURITY_OAUTH2_CLIENT_ID_KEY, client.getT1());
|
||||
@@ -89,7 +106,7 @@ public class SpringSecurityOAuth2CredentialProviderFactory extends
|
||||
}
|
||||
|
||||
private Mono<String> generateClientId(Config config, BackingApplication backingApplication,
|
||||
String serviceInstanceGuid) {
|
||||
String serviceInstanceGuid) {
|
||||
return Mono.defer(() -> {
|
||||
if (config.clientId == null) {
|
||||
return Mono.just(backingApplication.getName() + "-" + serviceInstanceGuid);
|
||||
@@ -99,9 +116,10 @@ public class SpringSecurityOAuth2CredentialProviderFactory extends
|
||||
}
|
||||
|
||||
private Mono<String> generateClientSecret(Config config, BackingApplication backingApplication,
|
||||
String serviceInstanceGuid) {
|
||||
String serviceInstanceGuid) {
|
||||
return credentialGenerator.generateString(backingApplication.getName(), serviceInstanceGuid,
|
||||
CREDENTIAL_DESCRIPTOR, config.getLength(), config.isIncludeUppercaseAlpha(), config.isIncludeLowercaseAlpha(),
|
||||
CREDENTIAL_DESCRIPTOR, config.getLength(), config.isIncludeUppercaseAlpha(),
|
||||
config.isIncludeLowercaseAlpha(),
|
||||
config.isIncludeNumeric(), config.isIncludeSpecial());
|
||||
}
|
||||
|
||||
@@ -140,13 +158,21 @@ public class SpringSecurityOAuth2CredentialProviderFactory extends
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public static class Config extends CredentialGenerationConfig {
|
||||
|
||||
private String registration;
|
||||
|
||||
private String clientId;
|
||||
|
||||
private String clientName;
|
||||
private String[] scopes;
|
||||
private String[] authorities;
|
||||
private String[] grantTypes;
|
||||
|
||||
private final List<String> scopes = new ArrayList<>();
|
||||
|
||||
private final List<String> authorities = new ArrayList<>();
|
||||
|
||||
private final List<String> grantTypes = new ArrayList<>();
|
||||
|
||||
private String identityZoneSubdomain;
|
||||
|
||||
private String identityZoneId;
|
||||
|
||||
public String getRegistration() {
|
||||
@@ -173,28 +199,34 @@ public class SpringSecurityOAuth2CredentialProviderFactory extends
|
||||
this.clientName = clientName;
|
||||
}
|
||||
|
||||
public String[] getScopes() {
|
||||
public List<String> getScopes() {
|
||||
return scopes;
|
||||
}
|
||||
|
||||
public void setScopes(String... scopes) {
|
||||
this.scopes = scopes;
|
||||
if (scopes != null) {
|
||||
this.scopes.addAll(Arrays.asList(scopes));
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getAuthorities() {
|
||||
public List<String> getAuthorities() {
|
||||
return authorities;
|
||||
}
|
||||
|
||||
public void setAuthorities(String... authorities) {
|
||||
this.authorities = authorities;
|
||||
if (authorities != null) {
|
||||
this.authorities.addAll(Arrays.asList(authorities));
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getGrantTypes() {
|
||||
public List<String> getGrantTypes() {
|
||||
return grantTypes;
|
||||
}
|
||||
|
||||
public void setGrantTypes(String... grantTypes) {
|
||||
this.grantTypes = grantTypes;
|
||||
if (grantTypes != null) {
|
||||
this.grantTypes.addAll(Arrays.asList(grantTypes));
|
||||
}
|
||||
}
|
||||
|
||||
public String getIdentityZoneSubdomain() {
|
||||
@@ -212,5 +244,7 @@ public class SpringSecurityOAuth2CredentialProviderFactory extends
|
||||
public void setIdentityZoneId(String identityZoneId) {
|
||||
this.identityZoneId = identityZoneId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,24 +37,25 @@ public class BackingApplicationsParametersTransformationService {
|
||||
}
|
||||
|
||||
public Mono<List<BackingApplication>> transformParameters(List<BackingApplication> backingApplications,
|
||||
Map<String, Object> parameters) {
|
||||
Map<String, Object> parameters) {
|
||||
return Flux.fromIterable(backingApplications)
|
||||
.flatMap(backingApplication -> {
|
||||
List<ParametersTransformerSpec> specs = getTransformerSpecsForApplication(backingApplication);
|
||||
.flatMap(backingApplication -> {
|
||||
List<ParametersTransformerSpec> specs = getTransformerSpecsForApplication(backingApplication);
|
||||
|
||||
return Flux.fromIterable(specs)
|
||||
.flatMap(spec -> {
|
||||
ParametersTransformer<BackingApplication> transformer = locator.getByName(spec.getName(), spec.getArgs());
|
||||
return transformer.transform(backingApplication, parameters);
|
||||
})
|
||||
.then(Mono.just(backingApplication));
|
||||
})
|
||||
.collectList();
|
||||
return Flux.fromIterable(specs)
|
||||
.flatMap(spec -> {
|
||||
ParametersTransformer<BackingApplication> transformer = locator
|
||||
.getByName(spec.getName(), spec.getArgs());
|
||||
return transformer.transform(backingApplication, parameters);
|
||||
})
|
||||
.then(Mono.just(backingApplication));
|
||||
})
|
||||
.collectList();
|
||||
}
|
||||
|
||||
private List<ParametersTransformerSpec> getTransformerSpecsForApplication(BackingApplication backingApplication) {
|
||||
return backingApplication.getParametersTransformers() == null
|
||||
? Collections.emptyList()
|
||||
: backingApplication.getParametersTransformers();
|
||||
return backingApplication.getParametersTransformers() == null ? Collections.emptyList() :
|
||||
backingApplication.getParametersTransformers();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,19 +37,20 @@ public class BackingServicesParametersTransformationService {
|
||||
}
|
||||
|
||||
public Mono<List<BackingService>> transformParameters(List<BackingService> backingServices,
|
||||
Map<String, Object> parameters) {
|
||||
Map<String, Object> parameters) {
|
||||
return Flux.fromIterable(backingServices)
|
||||
.flatMap(backingService -> {
|
||||
List<ParametersTransformerSpec> specs = getTransformerSpecsForService(backingService);
|
||||
.flatMap(backingService -> {
|
||||
List<ParametersTransformerSpec> specs = getTransformerSpecsForService(backingService);
|
||||
|
||||
return Flux.fromIterable(specs)
|
||||
.flatMap(spec -> {
|
||||
ParametersTransformer<BackingService> transformer = locator.getByName(spec.getName(), spec.getArgs());
|
||||
return transformer.transform(backingService, parameters);
|
||||
})
|
||||
.then(Mono.just(backingService));
|
||||
})
|
||||
.collectList();
|
||||
return Flux.fromIterable(specs)
|
||||
.flatMap(spec -> {
|
||||
ParametersTransformer<BackingService> transformer = locator
|
||||
.getByName(spec.getName(), spec.getArgs());
|
||||
return transformer.transform(backingService, parameters);
|
||||
})
|
||||
.then(Mono.just(backingService));
|
||||
})
|
||||
.collectList();
|
||||
}
|
||||
|
||||
private List<ParametersTransformerSpec> getTransformerSpecsForService(BackingService backingService) {
|
||||
@@ -57,4 +58,5 @@ public class BackingServicesParametersTransformationService {
|
||||
? Collections.emptyList()
|
||||
: backingService.getParametersTransformers();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ public class EnvironmentMappingParametersTransformerFactory extends
|
||||
ParametersTransformerFactory<BackingApplication, EnvironmentMappingParametersTransformerFactory.Config> {
|
||||
|
||||
private final Logger logger = Loggers.getLogger(EnvironmentMappingParametersTransformerFactory.class);
|
||||
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
public EnvironmentMappingParametersTransformerFactory() {
|
||||
@@ -44,8 +45,8 @@ public class EnvironmentMappingParametersTransformerFactory extends
|
||||
}
|
||||
|
||||
private Mono<BackingApplication> transform(BackingApplication backingApplication,
|
||||
Map<String, Object> parameters,
|
||||
List<String> include) {
|
||||
Map<String, Object> parameters,
|
||||
List<String> include) {
|
||||
if (parameters != null) {
|
||||
parameters
|
||||
.keySet().stream()
|
||||
@@ -77,9 +78,6 @@ public class EnvironmentMappingParametersTransformerFactory extends
|
||||
|
||||
private String include;
|
||||
|
||||
public Config() {
|
||||
}
|
||||
|
||||
public List<String> getIncludes() {
|
||||
return Arrays.asList(include.split(","));
|
||||
}
|
||||
@@ -87,5 +85,7 @@ public class EnvironmentMappingParametersTransformerFactory extends
|
||||
public void setInclude(String include) {
|
||||
this.include = include;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ public class ParameterMappingParametersTransformerFactory extends
|
||||
}
|
||||
|
||||
private Mono<BackingService> transform(BackingService backingService,
|
||||
Map<String, Object> parameters,
|
||||
List<String> include) {
|
||||
Map<String, Object> parameters,
|
||||
List<String> include) {
|
||||
if (parameters != null) {
|
||||
parameters.keySet().stream()
|
||||
.filter(include::contains)
|
||||
.forEach(key -> backingService.addParameter(key, parameters.get(key)));
|
||||
.filter(include::contains)
|
||||
.forEach(key -> backingService.addParameter(key, parameters.get(key)));
|
||||
}
|
||||
|
||||
return Mono.just(backingService);
|
||||
@@ -53,9 +53,6 @@ public class ParameterMappingParametersTransformerFactory extends
|
||||
|
||||
private String include;
|
||||
|
||||
public Config() {
|
||||
}
|
||||
|
||||
public List<String> getIncludes() {
|
||||
return Arrays.asList(include.split(","));
|
||||
}
|
||||
@@ -63,5 +60,7 @@ public class ParameterMappingParametersTransformerFactory extends
|
||||
public void setInclude(String include) {
|
||||
this.include = include;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.appbroker.extensions.parameters;
|
||||
import org.springframework.cloud.appbroker.extensions.AbstractExtensionFactory;
|
||||
|
||||
public abstract class ParametersTransformerFactory<B, C> extends AbstractExtensionFactory<ParametersTransformer<B>, C> {
|
||||
|
||||
protected ParametersTransformerFactory() {
|
||||
super();
|
||||
}
|
||||
@@ -30,7 +31,9 @@ public abstract class ParametersTransformerFactory<B, C> extends AbstractExtensi
|
||||
@Override
|
||||
public abstract ParametersTransformer<B> create(C config);
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getShortName(ParametersTransformerFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ public class PropertyMappingParametersTransformerFactory extends
|
||||
}
|
||||
|
||||
private Mono<BackingApplication> transform(BackingApplication backingApplication,
|
||||
Map<String, Object> parameters,
|
||||
List<String> include) {
|
||||
Map<String, Object> parameters,
|
||||
List<String> include) {
|
||||
if (parameters != null) {
|
||||
parameters.keySet().stream()
|
||||
.filter(include::contains)
|
||||
.forEach(key -> backingApplication.addProperty(key, parameters.get(key).toString()));
|
||||
.filter(include::contains)
|
||||
.forEach(key -> backingApplication.addProperty(key, parameters.get(key).toString()));
|
||||
}
|
||||
return Mono.just(backingApplication);
|
||||
}
|
||||
@@ -52,9 +52,6 @@ public class PropertyMappingParametersTransformerFactory extends
|
||||
|
||||
private String include;
|
||||
|
||||
public Config() {
|
||||
}
|
||||
|
||||
public List<String> getIncludes() {
|
||||
return Arrays.asList(include.split(","));
|
||||
}
|
||||
@@ -62,5 +59,7 @@ public class PropertyMappingParametersTransformerFactory extends
|
||||
public void setInclude(String include) {
|
||||
this.include = include;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,15 +16,16 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.extensions.support;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.beanutils.BeanUtilsBean;
|
||||
import org.apache.commons.beanutils.DefaultBeanIntrospector;
|
||||
import org.apache.commons.beanutils.SuppressPropertiesBeanIntrospector;
|
||||
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Map;
|
||||
|
||||
public final class ConfigurationBeanUtils {
|
||||
|
||||
private ConfigurationBeanUtils() {
|
||||
@@ -38,7 +39,7 @@ public final class ConfigurationBeanUtils {
|
||||
if (properties == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
T target = getTargetObject(targetObject);
|
||||
|
||||
try {
|
||||
@@ -47,13 +48,14 @@ public final class ConfigurationBeanUtils {
|
||||
beanUtils.getPropertyUtils().addBeanIntrospector(new KebabCasePropertyBeanIntrospector());
|
||||
beanUtils.getPropertyUtils().addBeanIntrospector(SuppressPropertiesBeanIntrospector.SUPPRESS_CLASS);
|
||||
beanUtils.copyProperties(target, properties);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
}
|
||||
catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new IllegalArgumentException("Failed to populate target of type " + targetObject.getClass()
|
||||
+ " with properties " + properties, e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked","PMD.AvoidCatchingGenericException"})
|
||||
@SuppressWarnings({"unchecked", "PMD.AvoidCatchingGenericException"})
|
||||
private static <T> T getTargetObject(Object candidate) {
|
||||
try {
|
||||
if (AopUtils.isAopProxy(candidate) && candidate instanceof Advised) {
|
||||
@@ -65,4 +67,5 @@ public final class ConfigurationBeanUtils {
|
||||
}
|
||||
return (T) candidate;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,49 +15,40 @@
|
||||
*/
|
||||
package org.springframework.cloud.appbroker.extensions.support;
|
||||
|
||||
import org.apache.commons.beanutils.BeanIntrospector;
|
||||
import org.apache.commons.beanutils.DefaultBeanIntrospector;
|
||||
import org.apache.commons.beanutils.IntrospectionContext;
|
||||
import reactor.util.Logger;
|
||||
import reactor.util.Loggers;
|
||||
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.beanutils.BeanIntrospector;
|
||||
import org.apache.commons.beanutils.DefaultBeanIntrospector;
|
||||
import org.apache.commons.beanutils.IntrospectionContext;
|
||||
import reactor.util.Logger;
|
||||
import reactor.util.Loggers;
|
||||
|
||||
/**
|
||||
* An implementation of the {@link BeanIntrospector} interface that provides property descriptors following the
|
||||
* kebab-case convention.
|
||||
* <p>
|
||||
* An implementation of the {@link BeanIntrospector} interface that provides property descriptors
|
||||
* following the kebab-case convention.
|
||||
* </p>
|
||||
*
|
||||
* This implementation is intended to collaborate with a {@link DefaultBeanIntrospector} object.
|
||||
* Best results are achieved by adding this instance as custom {@link BeanIntrospector} after the
|
||||
* {@link DefaultBeanIntrospector} object.
|
||||
* This implementation is intended to collaborate with a {@link DefaultBeanIntrospector} object. Best results are
|
||||
* achieved by adding this instance as custom {@link BeanIntrospector} after the {@link DefaultBeanIntrospector}
|
||||
* object.
|
||||
*/
|
||||
public class KebabCasePropertyBeanIntrospector implements BeanIntrospector {
|
||||
|
||||
private static final Logger LOG = Loggers.getLogger(KebabCasePropertyBeanIntrospector.class);
|
||||
|
||||
private static final String WRITE_METHOD_PREFIX = "set";
|
||||
|
||||
private final Logger log = Loggers.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>KebabCaseBeanIntrospector</code> and
|
||||
* sets the default prefix for write methods.
|
||||
*/
|
||||
KebabCasePropertyBeanIntrospector() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs introspection. This method scans the current class's methods for
|
||||
* property write methods add adds a property descriptor using the kebab-case
|
||||
* naming convention to match each property descriptor that uses the camel-case
|
||||
* Java Bean convention.
|
||||
* Performs introspection. This method scans the current class's methods for property write methods add adds a
|
||||
* property descriptor using the kebab-case naming convention to match each property descriptor that uses the
|
||||
* camel-case Java Bean convention.
|
||||
*
|
||||
* @param context the introspection context
|
||||
*/
|
||||
@Override
|
||||
public void introspect(final IntrospectionContext context) {
|
||||
for (final Method m : context.getTargetClass().getMethods()) {
|
||||
if (m.getName().startsWith(WRITE_METHOD_PREFIX)) {
|
||||
@@ -67,9 +58,12 @@ public class KebabCasePropertyBeanIntrospector implements BeanIntrospector {
|
||||
if (pd != null) {
|
||||
context.addPropertyDescriptor(createPropertyDescriptor(m));
|
||||
}
|
||||
} catch (final IntrospectionException e) {
|
||||
log.error("Error when creating PropertyDescriptor for method '{}'. " +
|
||||
}
|
||||
catch (final IntrospectionException e) {
|
||||
if (LOG.isErrorEnabled()) {
|
||||
LOG.error("Error when creating PropertyDescriptor for method '{}'. " +
|
||||
"This property will be ignored. {}", m, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,16 +90,17 @@ public class KebabCasePropertyBeanIntrospector implements BeanIntrospector {
|
||||
*/
|
||||
private String kebabCasePropertyName(final Method m) {
|
||||
final String methodName = camelCasePropertyName(m);
|
||||
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (char c : methodName.toCharArray()) {
|
||||
if (Character.isUpperCase(c)) {
|
||||
builder.append('-').append(Character.toLowerCase(c));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
builder.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@@ -120,4 +115,5 @@ public class KebabCasePropertyBeanIntrospector implements BeanIntrospector {
|
||||
String propertyName = kebabCasePropertyName(m);
|
||||
return new PropertyDescriptor(propertyName, null, m);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,9 +24,10 @@ import org.springframework.util.CollectionUtils;
|
||||
public class ArtifactDetails {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final Map<String, String> properties;
|
||||
|
||||
ArtifactDetails(String name, Map<String, String> properties) {
|
||||
public ArtifactDetails(String name, Map<String, String> properties) {
|
||||
this.name = name;
|
||||
this.properties = properties;
|
||||
}
|
||||
@@ -46,9 +47,10 @@ public class ArtifactDetails {
|
||||
public static final class ArtifactDetailsBuilder {
|
||||
|
||||
private String name;
|
||||
|
||||
private final Map<String, String> properties = new HashMap<>();
|
||||
|
||||
ArtifactDetailsBuilder() {
|
||||
private ArtifactDetailsBuilder() {
|
||||
}
|
||||
|
||||
public ArtifactDetailsBuilder name(String name) {
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ServiceInstanceGuidSuffix extends TargetFactory<ServiceInstanceGuid
|
||||
.build();
|
||||
}
|
||||
|
||||
static class Config {
|
||||
public static class Config {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class SpacePerServiceInstance extends TargetFactory<SpacePerServiceInstan
|
||||
.build();
|
||||
}
|
||||
|
||||
static class Config {
|
||||
public static class Config {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,4 +21,5 @@ import java.util.Map;
|
||||
public interface Target {
|
||||
|
||||
ArtifactDetails apply(Map<String, String> properties, String name, String serviceInstanceId);
|
||||
|
||||
}
|
||||
|
||||
@@ -20,18 +20,20 @@ import org.springframework.cloud.appbroker.extensions.AbstractExtensionFactory;
|
||||
|
||||
public abstract class TargetFactory<C> extends AbstractExtensionFactory<Target, C> {
|
||||
|
||||
TargetFactory() {
|
||||
protected TargetFactory() {
|
||||
super();
|
||||
}
|
||||
|
||||
TargetFactory(Class<C> configClass) {
|
||||
public TargetFactory(Class<C> configClass) {
|
||||
super(configClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Target create(C config);
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getShortName(TargetFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,8 +37,7 @@ public class TargetService {
|
||||
}
|
||||
|
||||
public Mono<List<BackingApplication>> addToBackingApplications(List<BackingApplication> backingApplications,
|
||||
TargetSpec targetSpec,
|
||||
String serviceInstanceId) {
|
||||
TargetSpec targetSpec, String serviceInstanceId) {
|
||||
return Flux.fromIterable(backingApplications)
|
||||
.flatMap(backingApplication -> {
|
||||
if (targetSpec != null) {
|
||||
@@ -59,8 +58,8 @@ public class TargetService {
|
||||
}
|
||||
|
||||
public Mono<List<BackingService>> addToBackingServices(List<BackingService> backingServices,
|
||||
TargetSpec targetSpec,
|
||||
String serviceInstanceId) {
|
||||
TargetSpec targetSpec,
|
||||
String serviceInstanceId) {
|
||||
return Flux.fromIterable(backingServices)
|
||||
.flatMap(backingService -> {
|
||||
if (targetSpec != null) {
|
||||
@@ -75,8 +74,9 @@ public class TargetService {
|
||||
}
|
||||
|
||||
private ArtifactDetails getArtifactDetails(TargetSpec targetSpec, String serviceInstanceId,
|
||||
String name, Map<String, String> properties) {
|
||||
String name, Map<String, String> properties) {
|
||||
Target target = locator.getByName(targetSpec.getName());
|
||||
return target.apply(properties, name, serviceInstanceId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.springframework.cloud.appbroker.deployer.BackingApplication;
|
||||
|
||||
public class ManagementClient {
|
||||
|
||||
private final Logger log = Loggers.getLogger(ManagementClient.class);
|
||||
private static final Logger LOG = Loggers.getLogger(ManagementClient.class);
|
||||
|
||||
private final AppManager appManager;
|
||||
|
||||
@@ -32,51 +32,52 @@ public class ManagementClient {
|
||||
this.appManager = appManager;
|
||||
}
|
||||
|
||||
Mono<Void> start(BackingApplication backingApplication) {
|
||||
public Mono<Void> start(BackingApplication backingApplication) {
|
||||
return Mono.justOrEmpty(backingApplication)
|
||||
.flatMap(backingApp -> appManager.start(StartApplicationRequest.builder()
|
||||
.name(backingApp.getName())
|
||||
.properties(backingApp.getProperties())
|
||||
.build())
|
||||
.doOnRequest(l -> log.debug("Starting application {}", backingApp))
|
||||
.doOnSuccess(response -> log.debug("Finished starting application {}", backingApp))
|
||||
.doOnError(exception -> log.error(String.format("Error starting application %s with error '%s'",
|
||||
.doOnRequest(l -> LOG.debug("Starting application {}", backingApp))
|
||||
.doOnSuccess(response -> LOG.debug("Finished starting application {}", backingApp))
|
||||
.doOnError(exception -> LOG.error(String.format("Error starting application %s with error '%s'",
|
||||
backingApp, exception.getMessage()), exception)));
|
||||
}
|
||||
|
||||
Mono<Void> stop(BackingApplication backingApplication) {
|
||||
public Mono<Void> stop(BackingApplication backingApplication) {
|
||||
return Mono.justOrEmpty(backingApplication)
|
||||
.flatMap(backingApp -> appManager.stop(StopApplicationRequest.builder()
|
||||
.name(backingApp.getName())
|
||||
.properties(backingApp.getProperties())
|
||||
.build())
|
||||
.doOnRequest(l -> log.debug("Stopping application {}", backingApp))
|
||||
.doOnSuccess(response -> log.debug("Finished stopping application {}", backingApp))
|
||||
.doOnError(exception -> log.error(String.format("Error stopping application %s with error '%s'",
|
||||
.doOnRequest(l -> LOG.debug("Stopping application {}", backingApp))
|
||||
.doOnSuccess(response -> LOG.debug("Finished stopping application {}", backingApp))
|
||||
.doOnError(exception -> LOG.error(String.format("Error stopping application %s with error '%s'",
|
||||
backingApp, exception.getMessage()), exception)));
|
||||
}
|
||||
|
||||
Mono<Void> restart(BackingApplication backingApplication) {
|
||||
public Mono<Void> restart(BackingApplication backingApplication) {
|
||||
return Mono.justOrEmpty(backingApplication)
|
||||
.flatMap(backingApp -> appManager.restart(RestartApplicationRequest.builder()
|
||||
.name(backingApp.getName())
|
||||
.properties(backingApp.getProperties())
|
||||
.build())
|
||||
.doOnRequest(l -> log.debug("Restarting application {}", backingApp))
|
||||
.doOnSuccess(response -> log.debug("Finished restarting application {}", backingApp))
|
||||
.doOnError(exception -> log.error(String.format("Error restarting application %s with error '%s'",
|
||||
.doOnRequest(l -> LOG.debug("Restarting application {}", backingApp))
|
||||
.doOnSuccess(response -> LOG.debug("Finished restarting application {}", backingApp))
|
||||
.doOnError(exception -> LOG.error(String.format("Error restarting application %s with error '%s'",
|
||||
backingApp, exception.getMessage()), exception)));
|
||||
}
|
||||
|
||||
Mono<Void> restage(BackingApplication backingApplication) {
|
||||
public Mono<Void> restage(BackingApplication backingApplication) {
|
||||
return Mono.justOrEmpty(backingApplication)
|
||||
.flatMap(backingApp -> appManager.restage(RestageApplicationRequest.builder()
|
||||
.name(backingApp.getName())
|
||||
.properties(backingApp.getProperties())
|
||||
.build())
|
||||
.doOnRequest(l -> log.debug("Restaging application {}", backingApp))
|
||||
.doOnSuccess(response -> log.debug("Finished restaging application {}", backingApp))
|
||||
.doOnError(exception -> log.error(String.format("Error restaging application %s with error '%s'",
|
||||
.doOnRequest(l -> LOG.debug("Restaging application {}", backingApp))
|
||||
.doOnSuccess(response -> LOG.debug("Finished restaging application {}", backingApp))
|
||||
.doOnError(exception -> LOG.error(String.format("Error restaging application %s with error '%s'",
|
||||
backingApp, exception.getMessage()), exception)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,13 +18,14 @@ package org.springframework.cloud.appbroker.service;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceAppBindingResponse;
|
||||
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceAppBindingResponse.CreateServiceInstanceAppBindingResponseBuilder;
|
||||
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingRequest;
|
||||
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceAppBindingResponse;
|
||||
|
||||
public interface CreateServiceInstanceAppBindingWorkflow {
|
||||
|
||||
default Mono<Void> create(CreateServiceInstanceBindingRequest request,
|
||||
CreateServiceInstanceAppBindingResponse response) {
|
||||
CreateServiceInstanceAppBindingResponse response) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@@ -32,8 +33,10 @@ public interface CreateServiceInstanceAppBindingWorkflow {
|
||||
return Mono.just(true);
|
||||
}
|
||||
|
||||
default Mono<CreateServiceInstanceAppBindingResponseBuilder> buildResponse(CreateServiceInstanceBindingRequest request,
|
||||
CreateServiceInstanceAppBindingResponseBuilder responseBuilder) {
|
||||
default Mono<CreateServiceInstanceAppBindingResponseBuilder> buildResponse(
|
||||
CreateServiceInstanceBindingRequest request,
|
||||
CreateServiceInstanceAppBindingResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,12 +19,13 @@ package org.springframework.cloud.appbroker.service;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceBindingRequest;
|
||||
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceRouteBindingResponse.CreateServiceInstanceRouteBindingResponseBuilder;
|
||||
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceRouteBindingResponse;
|
||||
import org.springframework.cloud.servicebroker.model.binding.CreateServiceInstanceRouteBindingResponse.CreateServiceInstanceRouteBindingResponseBuilder;
|
||||
|
||||
public interface CreateServiceInstanceRouteBindingWorkflow {
|
||||
|
||||
default Mono<Void> create(CreateServiceInstanceBindingRequest request,
|
||||
CreateServiceInstanceRouteBindingResponse response) {
|
||||
CreateServiceInstanceRouteBindingResponse response) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@@ -32,8 +33,10 @@ public interface CreateServiceInstanceRouteBindingWorkflow {
|
||||
return Mono.just(true);
|
||||
}
|
||||
|
||||
default Mono<CreateServiceInstanceRouteBindingResponseBuilder> buildResponse(CreateServiceInstanceBindingRequest request,
|
||||
CreateServiceInstanceRouteBindingResponseBuilder responseBuilder) {
|
||||
default Mono<CreateServiceInstanceRouteBindingResponseBuilder> buildResponse(
|
||||
CreateServiceInstanceBindingRequest request,
|
||||
CreateServiceInstanceRouteBindingResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,12 +19,13 @@ package org.springframework.cloud.appbroker.service;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest;
|
||||
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse.CreateServiceInstanceResponseBuilder;
|
||||
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse;
|
||||
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse.CreateServiceInstanceResponseBuilder;
|
||||
|
||||
public interface CreateServiceInstanceWorkflow {
|
||||
|
||||
default Mono<Void> create(CreateServiceInstanceRequest request,
|
||||
CreateServiceInstanceResponse response) {
|
||||
CreateServiceInstanceResponse response) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@@ -33,7 +34,8 @@ public interface CreateServiceInstanceWorkflow {
|
||||
}
|
||||
|
||||
default Mono<CreateServiceInstanceResponseBuilder> buildResponse(CreateServiceInstanceRequest request,
|
||||
CreateServiceInstanceResponseBuilder responseBuilder) {
|
||||
CreateServiceInstanceResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,12 +19,13 @@ package org.springframework.cloud.appbroker.service;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingRequest;
|
||||
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingResponse.DeleteServiceInstanceBindingResponseBuilder;
|
||||
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingResponse;
|
||||
import org.springframework.cloud.servicebroker.model.binding.DeleteServiceInstanceBindingResponse.DeleteServiceInstanceBindingResponseBuilder;
|
||||
|
||||
public interface DeleteServiceInstanceBindingWorkflow {
|
||||
|
||||
default Mono<Void> delete(DeleteServiceInstanceBindingRequest request,
|
||||
DeleteServiceInstanceBindingResponse response) {
|
||||
DeleteServiceInstanceBindingResponse response) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@@ -33,7 +34,8 @@ public interface DeleteServiceInstanceBindingWorkflow {
|
||||
}
|
||||
|
||||
default Mono<DeleteServiceInstanceBindingResponseBuilder> buildResponse(DeleteServiceInstanceBindingRequest request,
|
||||
DeleteServiceInstanceBindingResponseBuilder responseBuilder) {
|
||||
DeleteServiceInstanceBindingResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInsta
|
||||
import org.springframework.cloud.servicebroker.model.instance.DeleteServiceInstanceResponse.DeleteServiceInstanceResponseBuilder;
|
||||
|
||||
public interface DeleteServiceInstanceWorkflow {
|
||||
|
||||
default Mono<Void> delete(DeleteServiceInstanceRequest request, DeleteServiceInstanceResponse response) {
|
||||
return Mono.empty();
|
||||
}
|
||||
@@ -32,7 +33,8 @@ public interface DeleteServiceInstanceWorkflow {
|
||||
}
|
||||
|
||||
default Mono<DeleteServiceInstanceResponseBuilder> buildResponse(DeleteServiceInstanceRequest request,
|
||||
DeleteServiceInstanceResponseBuilder responseBuilder) {
|
||||
DeleteServiceInstanceResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInsta
|
||||
import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInstanceResponse.UpdateServiceInstanceResponseBuilder;
|
||||
|
||||
public interface UpdateServiceInstanceWorkflow {
|
||||
|
||||
default Mono<Void> update(UpdateServiceInstanceRequest request, UpdateServiceInstanceResponse response) {
|
||||
return Mono.empty();
|
||||
}
|
||||
@@ -32,7 +33,8 @@ public interface UpdateServiceInstanceWorkflow {
|
||||
}
|
||||
|
||||
default Mono<UpdateServiceInstanceResponseBuilder> buildResponse(UpdateServiceInstanceRequest request,
|
||||
UpdateServiceInstanceResponseBuilder responseBuilder) {
|
||||
UpdateServiceInstanceResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
public class WorkflowServiceInstanceBindingService implements ServiceInstanceBindingService {
|
||||
|
||||
private final Logger log = Loggers.getLogger(WorkflowServiceInstanceBindingService.class);
|
||||
private static final Logger LOG = Loggers.getLogger(WorkflowServiceInstanceBindingService.class);
|
||||
|
||||
private final ServiceInstanceBindingStateRepository stateRepository;
|
||||
|
||||
@@ -58,10 +58,10 @@ public class WorkflowServiceInstanceBindingService implements ServiceInstanceBin
|
||||
private final List<DeleteServiceInstanceBindingWorkflow> deleteServiceInstanceBindingWorkflows = new ArrayList<>();
|
||||
|
||||
public WorkflowServiceInstanceBindingService(
|
||||
ServiceInstanceBindingStateRepository serviceInstanceBindingStateRepository,
|
||||
List<CreateServiceInstanceAppBindingWorkflow> createServiceInstanceAppBindingWorkflows,
|
||||
List<CreateServiceInstanceRouteBindingWorkflow> createServiceInstanceRouteBindingWorkflows,
|
||||
List<DeleteServiceInstanceBindingWorkflow> deleteServiceInstanceBindingWorkflows) {
|
||||
ServiceInstanceBindingStateRepository serviceInstanceBindingStateRepository,
|
||||
List<CreateServiceInstanceAppBindingWorkflow> createServiceInstanceAppBindingWorkflows,
|
||||
List<CreateServiceInstanceRouteBindingWorkflow> createServiceInstanceRouteBindingWorkflows,
|
||||
List<DeleteServiceInstanceBindingWorkflow> deleteServiceInstanceBindingWorkflows) {
|
||||
this.stateRepository = serviceInstanceBindingStateRepository;
|
||||
if (!CollectionUtils.isEmpty(createServiceInstanceAppBindingWorkflows)) {
|
||||
this.createServiceInstanceAppBindingWorkflows.addAll(createServiceInstanceAppBindingWorkflows);
|
||||
@@ -78,24 +78,29 @@ public class WorkflowServiceInstanceBindingService implements ServiceInstanceBin
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<CreateServiceInstanceBindingResponse> createServiceInstanceBinding(CreateServiceInstanceBindingRequest request) {
|
||||
public Mono<CreateServiceInstanceBindingResponse> createServiceInstanceBinding(
|
||||
CreateServiceInstanceBindingRequest request) {
|
||||
return invokeCreateResponseBuilders(request)
|
||||
.publishOn(Schedulers.parallel())
|
||||
.doOnNext(response -> create(request, response)
|
||||
.subscribe());
|
||||
}
|
||||
|
||||
private Mono<CreateServiceInstanceBindingResponse> invokeCreateResponseBuilders(CreateServiceInstanceBindingRequest request) {
|
||||
private Mono<CreateServiceInstanceBindingResponse> invokeCreateResponseBuilders(
|
||||
CreateServiceInstanceBindingRequest request) {
|
||||
return Mono.defer(() -> {
|
||||
if (isAppBindingRequest(request)) {
|
||||
CreateServiceInstanceAppBindingResponseBuilder builder = CreateServiceInstanceAppBindingResponse.builder();
|
||||
CreateServiceInstanceAppBindingResponseBuilder builder = CreateServiceInstanceAppBindingResponse
|
||||
.builder();
|
||||
return invokeAppBindingBuildResponse(builder, request, this.createServiceInstanceAppBindingWorkflows)
|
||||
.last(builder)
|
||||
.map(CreateServiceInstanceAppBindingResponseBuilder::build);
|
||||
}
|
||||
else if (isRouteBindingRequest(request)) {
|
||||
CreateServiceInstanceRouteBindingResponseBuilder builder = CreateServiceInstanceRouteBindingResponse.builder();
|
||||
return invokeRouteBindingBuildResponse(builder, request, this.createServiceInstanceRouteBindingWorkflows)
|
||||
CreateServiceInstanceRouteBindingResponseBuilder builder = CreateServiceInstanceRouteBindingResponse
|
||||
.builder();
|
||||
return invokeRouteBindingBuildResponse(builder, request,
|
||||
this.createServiceInstanceRouteBindingWorkflows)
|
||||
.last(builder)
|
||||
.map(CreateServiceInstanceRouteBindingResponseBuilder::build);
|
||||
}
|
||||
@@ -103,51 +108,58 @@ public class WorkflowServiceInstanceBindingService implements ServiceInstanceBin
|
||||
});
|
||||
}
|
||||
|
||||
Flux<CreateServiceInstanceAppBindingResponseBuilder> invokeAppBindingBuildResponse(CreateServiceInstanceAppBindingResponseBuilder builder, CreateServiceInstanceBindingRequest request, List<CreateServiceInstanceAppBindingWorkflow> workflows) {
|
||||
AtomicReference<CreateServiceInstanceAppBindingResponseBuilder> responseBuilder = new AtomicReference<>(builder);
|
||||
private Flux<CreateServiceInstanceAppBindingResponseBuilder> invokeAppBindingBuildResponse(
|
||||
CreateServiceInstanceAppBindingResponseBuilder builder, CreateServiceInstanceBindingRequest request,
|
||||
List<CreateServiceInstanceAppBindingWorkflow> workflows) {
|
||||
AtomicReference<CreateServiceInstanceAppBindingResponseBuilder> responseBuilder = new AtomicReference<>(
|
||||
builder);
|
||||
return Flux.fromIterable(workflows)
|
||||
.filterWhen(workflow -> workflow.accept(request))
|
||||
.concatMap(workflow -> workflow.buildResponse(request, responseBuilder.get())
|
||||
.doOnNext(responseBuilder::set));
|
||||
.filterWhen(workflow -> workflow.accept(request))
|
||||
.concatMap(workflow -> workflow.buildResponse(request, responseBuilder.get())
|
||||
.doOnNext(responseBuilder::set));
|
||||
}
|
||||
|
||||
Flux<CreateServiceInstanceRouteBindingResponseBuilder> invokeRouteBindingBuildResponse(CreateServiceInstanceRouteBindingResponseBuilder builder, CreateServiceInstanceBindingRequest request, List<CreateServiceInstanceRouteBindingWorkflow> workflows) {
|
||||
AtomicReference<CreateServiceInstanceRouteBindingResponseBuilder> responseBuilder = new AtomicReference<>(builder);
|
||||
private Flux<CreateServiceInstanceRouteBindingResponseBuilder> invokeRouteBindingBuildResponse(
|
||||
CreateServiceInstanceRouteBindingResponseBuilder builder, CreateServiceInstanceBindingRequest request,
|
||||
List<CreateServiceInstanceRouteBindingWorkflow> workflows) {
|
||||
AtomicReference<CreateServiceInstanceRouteBindingResponseBuilder> responseBuilder = new AtomicReference<>(
|
||||
builder);
|
||||
return Flux.fromIterable(workflows)
|
||||
.filterWhen(workflow -> workflow.accept(request))
|
||||
.concatMap(workflow -> workflow.buildResponse(request, responseBuilder.get())
|
||||
.doOnNext(responseBuilder::set));
|
||||
.filterWhen(workflow -> workflow.accept(request))
|
||||
.concatMap(workflow -> workflow.buildResponse(request, responseBuilder.get())
|
||||
.doOnNext(responseBuilder::set));
|
||||
}
|
||||
|
||||
private boolean isAppBindingRequest(CreateServiceInstanceBindingRequest request) {
|
||||
return request.getBindResource() != null
|
||||
&& StringUtils.isEmpty(request.getBindResource().getRoute());
|
||||
&& StringUtils.isEmpty(request.getBindResource().getRoute());
|
||||
}
|
||||
|
||||
private boolean isRouteBindingRequest(CreateServiceInstanceBindingRequest request) {
|
||||
return request.getBindResource() != null
|
||||
&& StringUtils.hasText(request.getBindResource().getRoute());
|
||||
&& StringUtils.hasText(request.getBindResource().getRoute());
|
||||
}
|
||||
|
||||
private Mono<Void> create(CreateServiceInstanceBindingRequest request,
|
||||
CreateServiceInstanceBindingResponse response) {
|
||||
CreateServiceInstanceBindingResponse response) {
|
||||
return stateRepository.saveState(request.getServiceInstanceId(), request.getBindingId(),
|
||||
OperationState.IN_PROGRESS, "create service instance binding started")
|
||||
.thenMany(invokeCreateWorkflows(request, response)
|
||||
.doOnRequest(l -> log.debug("Creating service instance binding"))
|
||||
.doOnComplete(() -> log.debug("Finished creating service instance binding"))
|
||||
.doOnError(exception -> log.error(String.format("Error creating service instance binding with error '%s'",
|
||||
exception.getMessage()), exception)))
|
||||
.doOnRequest(l -> LOG.debug("Creating service instance binding"))
|
||||
.doOnComplete(() -> LOG.debug("Finished creating service instance binding"))
|
||||
.doOnError(exception -> LOG.error(String.format("Error creating service instance binding with error " +
|
||||
"'%s'", exception.getMessage()), exception)))
|
||||
.thenEmpty(stateRepository.saveState(request.getServiceInstanceId(), request.getBindingId(),
|
||||
OperationState.SUCCEEDED, "create service instance binding completed")
|
||||
.then())
|
||||
.onErrorResume(exception -> stateRepository.saveState(request.getServiceInstanceId(), request.getBindingId(),
|
||||
OperationState.FAILED, exception.getMessage())
|
||||
.then());
|
||||
.onErrorResume(
|
||||
exception -> stateRepository.saveState(request.getServiceInstanceId(), request.getBindingId(),
|
||||
OperationState.FAILED, exception.getMessage())
|
||||
.then());
|
||||
}
|
||||
|
||||
private Flux<Void> invokeCreateWorkflows(CreateServiceInstanceBindingRequest request,
|
||||
CreateServiceInstanceBindingResponse response) {
|
||||
CreateServiceInstanceBindingResponse response) {
|
||||
return Flux.defer(() -> {
|
||||
if (isAppBindingRequest(request)) {
|
||||
return Flux.fromIterable(createServiceInstanceAppBindingWorkflows)
|
||||
@@ -159,21 +171,23 @@ public class WorkflowServiceInstanceBindingService implements ServiceInstanceBin
|
||||
return Flux.fromIterable(createServiceInstanceRouteBindingWorkflows)
|
||||
.filterWhen(workflow -> workflow.accept(request))
|
||||
.concatMap(workflow -> workflow.create(request,
|
||||
(CreateServiceInstanceRouteBindingResponse)response));
|
||||
(CreateServiceInstanceRouteBindingResponse) response));
|
||||
}
|
||||
return Flux.empty();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<DeleteServiceInstanceBindingResponse> deleteServiceInstanceBinding(DeleteServiceInstanceBindingRequest request) {
|
||||
public Mono<DeleteServiceInstanceBindingResponse> deleteServiceInstanceBinding(
|
||||
DeleteServiceInstanceBindingRequest request) {
|
||||
return invokeDeleteResponseBuilders(request)
|
||||
.publishOn(Schedulers.parallel())
|
||||
.doOnNext(response -> delete(request, response)
|
||||
.subscribe());
|
||||
}
|
||||
|
||||
private Mono<DeleteServiceInstanceBindingResponse> invokeDeleteResponseBuilders(DeleteServiceInstanceBindingRequest request) {
|
||||
private Mono<DeleteServiceInstanceBindingResponse> invokeDeleteResponseBuilders(
|
||||
DeleteServiceInstanceBindingRequest request) {
|
||||
AtomicReference<DeleteServiceInstanceBindingResponseBuilder> responseBuilder =
|
||||
new AtomicReference<>(DeleteServiceInstanceBindingResponse.builder());
|
||||
|
||||
@@ -186,31 +200,33 @@ public class WorkflowServiceInstanceBindingService implements ServiceInstanceBin
|
||||
}
|
||||
|
||||
private Mono<Void> delete(DeleteServiceInstanceBindingRequest request,
|
||||
DeleteServiceInstanceBindingResponse response) {
|
||||
DeleteServiceInstanceBindingResponse response) {
|
||||
return stateRepository.saveState(request.getServiceInstanceId(), request.getBindingId(),
|
||||
OperationState.IN_PROGRESS, "delete service instance binding started")
|
||||
.thenMany(invokeDeleteWorkflows(request, response)
|
||||
.doOnRequest(l -> log.debug("Deleting service instance binding"))
|
||||
.doOnComplete(() -> log.debug("Finished deleting service instance binding"))
|
||||
.doOnError(exception -> log.error(String.format("Error deleting service instance binding with error '%s'",
|
||||
exception.getMessage()), exception)))
|
||||
.doOnRequest(l -> LOG.debug("Deleting service instance binding"))
|
||||
.doOnComplete(() -> LOG.debug("Finished deleting service instance binding"))
|
||||
.doOnError(exception -> LOG.error(String.format("Error deleting service instance binding with error " +
|
||||
"'%s'", exception.getMessage()), exception)))
|
||||
.thenEmpty(stateRepository.saveState(request.getServiceInstanceId(), request.getBindingId(),
|
||||
OperationState.SUCCEEDED, "delete service instance binding completed")
|
||||
.then())
|
||||
.onErrorResume(exception -> stateRepository.saveState(request.getServiceInstanceId(), request.getBindingId(),
|
||||
OperationState.FAILED, exception.getMessage())
|
||||
.then());
|
||||
.onErrorResume(
|
||||
exception -> stateRepository.saveState(request.getServiceInstanceId(), request.getBindingId(),
|
||||
OperationState.FAILED, exception.getMessage())
|
||||
.then());
|
||||
}
|
||||
|
||||
private Flux<Void> invokeDeleteWorkflows(DeleteServiceInstanceBindingRequest request,
|
||||
DeleteServiceInstanceBindingResponse response) {
|
||||
DeleteServiceInstanceBindingResponse response) {
|
||||
return Flux.fromIterable(deleteServiceInstanceBindingWorkflows)
|
||||
.filterWhen(workflow -> workflow.accept(request))
|
||||
.concatMap(workflow -> workflow.delete(request, response));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<GetLastServiceBindingOperationResponse> getLastOperation(GetLastServiceBindingOperationRequest request) {
|
||||
public Mono<GetLastServiceBindingOperationResponse> getLastOperation(
|
||||
GetLastServiceBindingOperationRequest request) {
|
||||
return stateRepository.getState(request.getServiceInstanceId(), request.getBindingId())
|
||||
.doOnError(exception -> Mono.error(new ServiceInstanceBindingDoesNotExistException(request.getBindingId())))
|
||||
.map(serviceInstanceState -> GetLastServiceBindingOperationResponse.builder()
|
||||
|
||||
@@ -61,9 +61,9 @@ public class WorkflowServiceInstanceService implements ServiceInstanceService {
|
||||
private final ServiceInstanceStateRepository stateRepository;
|
||||
|
||||
public WorkflowServiceInstanceService(ServiceInstanceStateRepository serviceInstanceStateRepository,
|
||||
List<CreateServiceInstanceWorkflow> createServiceInstanceWorkflows,
|
||||
List<DeleteServiceInstanceWorkflow> deleteServiceInstanceWorkflows,
|
||||
List<UpdateServiceInstanceWorkflow> updateServiceInstanceWorkflows) {
|
||||
List<CreateServiceInstanceWorkflow> createServiceInstanceWorkflows,
|
||||
List<DeleteServiceInstanceWorkflow> deleteServiceInstanceWorkflows,
|
||||
List<UpdateServiceInstanceWorkflow> updateServiceInstanceWorkflows) {
|
||||
this.stateRepository = serviceInstanceStateRepository;
|
||||
this.createServiceInstanceWorkflows = createServiceInstanceWorkflows;
|
||||
this.deleteServiceInstanceWorkflows = deleteServiceInstanceWorkflows;
|
||||
@@ -102,7 +102,7 @@ public class WorkflowServiceInstanceService implements ServiceInstanceService {
|
||||
.doOnRequest(l -> log.debug("Creating service instance"))
|
||||
.doOnComplete(() -> log.debug("Finished creating service instance"))
|
||||
.doOnError(exception -> log.error(String.format("Error creating service instance with error '%s'",
|
||||
exception.getMessage()), exception)))
|
||||
exception.getMessage()), exception)))
|
||||
.thenEmpty(stateRepository.saveState(request.getServiceInstanceId(),
|
||||
OperationState.SUCCEEDED, "create service instance completed")
|
||||
.then())
|
||||
@@ -112,7 +112,7 @@ public class WorkflowServiceInstanceService implements ServiceInstanceService {
|
||||
}
|
||||
|
||||
private Flux<Void> invokeCreateWorkflows(CreateServiceInstanceRequest request,
|
||||
CreateServiceInstanceResponse response) {
|
||||
CreateServiceInstanceResponse response) {
|
||||
return Flux.fromIterable(createServiceInstanceWorkflows)
|
||||
.filterWhen(workflow -> workflow.accept(request))
|
||||
.concatMap(workflow -> workflow.create(request, response));
|
||||
@@ -155,7 +155,7 @@ public class WorkflowServiceInstanceService implements ServiceInstanceService {
|
||||
}
|
||||
|
||||
private Flux<Void> invokeDeleteWorkflows(DeleteServiceInstanceRequest request,
|
||||
DeleteServiceInstanceResponse response) {
|
||||
DeleteServiceInstanceResponse response) {
|
||||
return Flux.fromIterable(deleteServiceInstanceWorkflows)
|
||||
.filterWhen(workflow -> workflow.accept(request))
|
||||
.concatMap(workflow -> workflow.delete(request, response));
|
||||
@@ -198,7 +198,7 @@ public class WorkflowServiceInstanceService implements ServiceInstanceService {
|
||||
}
|
||||
|
||||
private Flux<Void> invokeUpdateWorkflows(UpdateServiceInstanceRequest request,
|
||||
UpdateServiceInstanceResponse response) {
|
||||
UpdateServiceInstanceResponse response) {
|
||||
return Flux.fromIterable(updateServiceInstanceWorkflows)
|
||||
.filterWhen(workflow -> workflow.accept(request))
|
||||
.concatMap(workflow -> workflow.update(request, response));
|
||||
@@ -219,4 +219,5 @@ public class WorkflowServiceInstanceService implements ServiceInstanceService {
|
||||
//TODO add functionality
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,11 +34,14 @@ public class InMemoryServiceInstanceBindingStateRepository implements ServiceIns
|
||||
private final Map<BindingKey, ServiceInstanceState> states = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public Mono<ServiceInstanceState> saveState(String serviceInstanceId, String bindingId, OperationState state, String description) {
|
||||
public Mono<ServiceInstanceState> saveState(String serviceInstanceId, String bindingId, OperationState state,
|
||||
String description) {
|
||||
return Mono.just(new BindingKey(serviceInstanceId, bindingId))
|
||||
.flatMap(bindingKey -> Mono.just(new ServiceInstanceState(state, description, new Timestamp(Instant.now().toEpochMilli())))
|
||||
.flatMap(serviceInstanceState -> Mono.fromCallable(() -> this.states.put(bindingKey, serviceInstanceState))
|
||||
.thenReturn(serviceInstanceState)));
|
||||
.flatMap(bindingKey -> Mono
|
||||
.just(new ServiceInstanceState(state, description, new Timestamp(Instant.now().toEpochMilli())))
|
||||
.flatMap(
|
||||
serviceInstanceState -> Mono.fromCallable(() -> this.states.put(bindingKey, serviceInstanceState))
|
||||
.thenReturn(serviceInstanceState)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,7 +90,7 @@ public class InMemoryServiceInstanceBindingStateRepository implements ServiceIns
|
||||
return this.bindingId;
|
||||
}
|
||||
|
||||
BindingKey(String serviceInstanceId, String bindingId) {
|
||||
public BindingKey(String serviceInstanceId, String bindingId) {
|
||||
this.serviceInstanceId = serviceInstanceId;
|
||||
this.bindingId = bindingId;
|
||||
}
|
||||
@@ -100,7 +103,7 @@ public class InMemoryServiceInstanceBindingStateRepository implements ServiceIns
|
||||
if (!(obj instanceof BindingKey)) {
|
||||
return false;
|
||||
}
|
||||
BindingKey that = (BindingKey)obj;
|
||||
BindingKey that = (BindingKey) obj;
|
||||
return Objects.equals(this.bindingId, that.bindingId) &&
|
||||
Objects.equals(this.serviceInstanceId, that.serviceInstanceId);
|
||||
}
|
||||
@@ -117,5 +120,7 @@ public class InMemoryServiceInstanceBindingStateRepository implements ServiceIns
|
||||
", bindingId='" + bindingId + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ public class InMemoryServiceInstanceStateRepository implements ServiceInstanceSt
|
||||
@Override
|
||||
public Mono<ServiceInstanceState> saveState(String serviceInstanceId, OperationState state, String description) {
|
||||
return Mono.just(new ServiceInstanceState(state, description, new Timestamp(Instant.now().toEpochMilli())))
|
||||
.flatMap(serviceInstanceState -> Mono.fromCallable(() -> this.states.put(serviceInstanceId, serviceInstanceState))
|
||||
.flatMap(serviceInstanceState -> Mono
|
||||
.fromCallable(() -> this.states.put(serviceInstanceId, serviceInstanceState))
|
||||
.thenReturn(serviceInstanceState));
|
||||
}
|
||||
|
||||
@@ -65,4 +66,5 @@ public class InMemoryServiceInstanceStateRepository implements ServiceInstanceSt
|
||||
private Mono<Boolean> containsState(String serviceInstanceId) {
|
||||
return Mono.fromCallable(() -> this.states.containsKey(serviceInstanceId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ import org.springframework.cloud.servicebroker.model.instance.OperationState;
|
||||
*/
|
||||
public interface ServiceInstanceBindingStateRepository {
|
||||
|
||||
default Mono<ServiceInstanceState> saveState(String serviceInstanceId, String bindingId, OperationState state, String description) {
|
||||
default Mono<ServiceInstanceState> saveState(String serviceInstanceId, String bindingId, OperationState state,
|
||||
String description) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.util.Logger;
|
||||
import reactor.util.Loggers;
|
||||
|
||||
import org.springframework.cloud.appbroker.deployer.BackingAppDeploymentService;
|
||||
import org.springframework.cloud.appbroker.deployer.BackingServicesProvisionService;
|
||||
import org.springframework.cloud.appbroker.deployer.BrokeredServices;
|
||||
import org.springframework.cloud.appbroker.extensions.credentials.CredentialProviderService;
|
||||
@@ -29,7 +30,6 @@ import org.springframework.cloud.appbroker.extensions.parameters.BackingServices
|
||||
import org.springframework.cloud.appbroker.extensions.targets.TargetService;
|
||||
import org.springframework.cloud.appbroker.service.CreateServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceRequest;
|
||||
import org.springframework.cloud.appbroker.deployer.BackingAppDeploymentService;
|
||||
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse;
|
||||
import org.springframework.cloud.servicebroker.model.instance.CreateServiceInstanceResponse.CreateServiceInstanceResponseBuilder;
|
||||
import org.springframework.core.annotation.Order;
|
||||
@@ -42,19 +42,24 @@ public class AppDeploymentCreateServiceInstanceWorkflow
|
||||
private final Logger log = Loggers.getLogger(AppDeploymentCreateServiceInstanceWorkflow.class);
|
||||
|
||||
private final BackingAppDeploymentService deploymentService;
|
||||
|
||||
private final BackingServicesProvisionService backingServicesProvisionService;
|
||||
|
||||
private final BackingApplicationsParametersTransformationService appsParametersTransformationService;
|
||||
|
||||
private final BackingServicesParametersTransformationService servicesParametersTransformationService;
|
||||
|
||||
private final CredentialProviderService credentialProviderService;
|
||||
|
||||
private final TargetService targetService;
|
||||
|
||||
public AppDeploymentCreateServiceInstanceWorkflow(BrokeredServices brokeredServices,
|
||||
BackingAppDeploymentService deploymentService,
|
||||
BackingServicesProvisionService backingServicesProvisionService,
|
||||
BackingApplicationsParametersTransformationService appsParametersTransformationService,
|
||||
BackingServicesParametersTransformationService servicesParametersTransformationService,
|
||||
CredentialProviderService credentialProviderService,
|
||||
TargetService targetService) {
|
||||
BackingAppDeploymentService deploymentService,
|
||||
BackingServicesProvisionService backingServicesProvisionService,
|
||||
BackingApplicationsParametersTransformationService appsParametersTransformationService,
|
||||
BackingServicesParametersTransformationService servicesParametersTransformationService,
|
||||
CredentialProviderService credentialProviderService,
|
||||
TargetService targetService) {
|
||||
super(brokeredServices);
|
||||
this.deploymentService = deploymentService;
|
||||
this.backingServicesProvisionService = backingServicesProvisionService;
|
||||
@@ -75,7 +80,7 @@ public class AppDeploymentCreateServiceInstanceWorkflow
|
||||
return getBackingServicesForService(request.getServiceDefinition(), request.getPlan())
|
||||
.flatMap(backingServices ->
|
||||
targetService.addToBackingServices(backingServices,
|
||||
getTargetForService(request.getServiceDefinition(), request.getPlan()) ,
|
||||
getTargetForService(request.getServiceDefinition(), request.getPlan()),
|
||||
request.getServiceInstanceId()))
|
||||
.flatMap(backingServices ->
|
||||
servicesParametersTransformationService.transformParameters(backingServices,
|
||||
@@ -86,7 +91,8 @@ public class AppDeploymentCreateServiceInstanceWorkflow
|
||||
.doOnComplete(() -> log.debug("Finished creating backing services for {}/{}",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName()))
|
||||
.doOnError(exception -> log.error(String.format("Error creating backing services for %s/%s with error '%s'",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()), exception));
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()),
|
||||
exception));
|
||||
}
|
||||
|
||||
private Flux<String> deployBackingApplications(CreateServiceInstanceRequest request) {
|
||||
@@ -94,7 +100,7 @@ public class AppDeploymentCreateServiceInstanceWorkflow
|
||||
.flatMap(backingApps ->
|
||||
targetService.addToBackingApplications(backingApps,
|
||||
getTargetForService(request.getServiceDefinition(),
|
||||
request.getPlan()) , request.getServiceInstanceId()))
|
||||
request.getPlan()), request.getServiceInstanceId()))
|
||||
.flatMap(backingApps ->
|
||||
appsParametersTransformationService.transformParameters(backingApps,
|
||||
request.getParameters()))
|
||||
@@ -106,8 +112,10 @@ public class AppDeploymentCreateServiceInstanceWorkflow
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName()))
|
||||
.doOnComplete(() -> log.debug("Finished deploying backing applications for {}/{}",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName()))
|
||||
.doOnError(exception -> log.error(String.format("Error deploying backing applications for %s/%s with error '%s'",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()), exception));
|
||||
.doOnError(
|
||||
exception -> log.error(String.format("Error deploying backing applications for %s/%s with error '%s'",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()),
|
||||
exception));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,7 +125,8 @@ public class AppDeploymentCreateServiceInstanceWorkflow
|
||||
|
||||
@Override
|
||||
public Mono<CreateServiceInstanceResponseBuilder> buildResponse(CreateServiceInstanceRequest request,
|
||||
CreateServiceInstanceResponseBuilder responseBuilder) {
|
||||
CreateServiceInstanceResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder.async(true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,15 +40,18 @@ public class AppDeploymentDeleteServiceInstanceWorkflow
|
||||
private final Logger log = Loggers.getLogger(AppDeploymentDeleteServiceInstanceWorkflow.class);
|
||||
|
||||
private final BackingAppDeploymentService deploymentService;
|
||||
|
||||
private final CredentialProviderService credentialProviderService;
|
||||
|
||||
private final TargetService targetService;
|
||||
|
||||
private final BackingServicesProvisionService backingServicesProvisionService;
|
||||
|
||||
public AppDeploymentDeleteServiceInstanceWorkflow(BrokeredServices brokeredServices,
|
||||
BackingAppDeploymentService deploymentService,
|
||||
BackingServicesProvisionService backingServicesProvisionService,
|
||||
CredentialProviderService credentialProviderService,
|
||||
TargetService targetService) {
|
||||
BackingAppDeploymentService deploymentService,
|
||||
BackingServicesProvisionService backingServicesProvisionService,
|
||||
CredentialProviderService credentialProviderService,
|
||||
TargetService targetService) {
|
||||
super(brokeredServices);
|
||||
this.deploymentService = deploymentService;
|
||||
this.credentialProviderService = credentialProviderService;
|
||||
@@ -67,7 +70,7 @@ public class AppDeploymentDeleteServiceInstanceWorkflow
|
||||
return getBackingServicesForService(request.getServiceDefinition(), request.getPlan())
|
||||
.flatMapMany(backingServices ->
|
||||
targetService.addToBackingServices(backingServices,
|
||||
getTargetForService(request.getServiceDefinition(), request.getPlan()) ,
|
||||
getTargetForService(request.getServiceDefinition(), request.getPlan()),
|
||||
request.getServiceInstanceId()))
|
||||
.flatMap(backingServicesProvisionService::deleteServiceInstance)
|
||||
.doOnRequest(l -> log.debug("Deleting backing services for{}/{}",
|
||||
@@ -75,7 +78,8 @@ public class AppDeploymentDeleteServiceInstanceWorkflow
|
||||
.doOnComplete(() -> log.debug("Finished deleting backing services for {}/{}",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName()))
|
||||
.doOnError(exception -> log.error(String.format("Error deleting backing services for %s/%s with error '%s'",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()), exception));
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()),
|
||||
exception));
|
||||
}
|
||||
|
||||
private Flux<String> undeployBackingApplications(DeleteServiceInstanceRequest request) {
|
||||
@@ -92,8 +96,10 @@ public class AppDeploymentDeleteServiceInstanceWorkflow
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName()))
|
||||
.doOnComplete(() -> log.debug("Finished undeploying backing applications for {}/{}",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName()))
|
||||
.doOnError(exception -> log.error(String.format("Error undeploying backing applications for %s/%s with error '%s'",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()), exception));
|
||||
.doOnError(
|
||||
exception -> log.error(String.format("Error undeploying backing applications for %s/%s with error '%s'",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()),
|
||||
exception));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,7 +109,8 @@ public class AppDeploymentDeleteServiceInstanceWorkflow
|
||||
|
||||
@Override
|
||||
public Mono<DeleteServiceInstanceResponseBuilder> buildResponse(DeleteServiceInstanceRequest request,
|
||||
DeleteServiceInstanceResponseBuilder responseBuilder) {
|
||||
DeleteServiceInstanceResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder.async(true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,38 +31,38 @@ import org.springframework.cloud.servicebroker.model.catalog.Plan;
|
||||
import org.springframework.cloud.servicebroker.model.catalog.ServiceDefinition;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
class AppDeploymentInstanceWorkflow {
|
||||
public class AppDeploymentInstanceWorkflow {
|
||||
|
||||
final BrokeredServices brokeredServices;
|
||||
private final BrokeredServices brokeredServices;
|
||||
|
||||
AppDeploymentInstanceWorkflow(BrokeredServices brokeredServices) {
|
||||
protected AppDeploymentInstanceWorkflow(BrokeredServices brokeredServices) {
|
||||
this.brokeredServices = brokeredServices;
|
||||
}
|
||||
|
||||
Mono<Boolean> accept(ServiceDefinition serviceDefinition, Plan plan) {
|
||||
protected Mono<Boolean> accept(ServiceDefinition serviceDefinition, Plan plan) {
|
||||
return getBackingApplicationsForService(serviceDefinition, plan)
|
||||
.map(backingApplications -> !backingApplications.isEmpty())
|
||||
.defaultIfEmpty(false);
|
||||
}
|
||||
|
||||
TargetSpec getTargetForService(ServiceDefinition serviceDefinition, Plan plan) {
|
||||
protected TargetSpec getTargetForService(ServiceDefinition serviceDefinition, Plan plan) {
|
||||
BrokeredService brokeredService = findBrokeredService(serviceDefinition, plan);
|
||||
return brokeredService == null ? null : brokeredService.getTarget();
|
||||
}
|
||||
|
||||
Mono<List<BackingApplication>> getBackingApplicationsForService(ServiceDefinition serviceDefinition,
|
||||
Plan plan) {
|
||||
protected Mono<List<BackingApplication>> getBackingApplicationsForService(ServiceDefinition serviceDefinition,
|
||||
Plan plan) {
|
||||
return Mono.defer(() ->
|
||||
Mono.justOrEmpty(findBackingApplications(serviceDefinition, plan)));
|
||||
}
|
||||
|
||||
Mono<List<BackingService>> getBackingServicesForService(ServiceDefinition serviceDefinition, Plan plan) {
|
||||
protected Mono<List<BackingService>> getBackingServicesForService(ServiceDefinition serviceDefinition, Plan plan) {
|
||||
return Mono.defer(() ->
|
||||
Mono.justOrEmpty(findBackingServices(serviceDefinition, plan)));
|
||||
}
|
||||
|
||||
private BackingApplications findBackingApplications(ServiceDefinition serviceDefinition,
|
||||
Plan plan) {
|
||||
Plan plan) {
|
||||
BrokeredService brokeredService = findBrokeredService(serviceDefinition, plan);
|
||||
BackingApplications backingApplications = null;
|
||||
if (brokeredService != null) {
|
||||
@@ -74,7 +74,7 @@ class AppDeploymentInstanceWorkflow {
|
||||
}
|
||||
|
||||
private BackingServices findBackingServices(ServiceDefinition serviceDefinition,
|
||||
Plan plan) {
|
||||
Plan plan) {
|
||||
BrokeredService brokeredService = findBrokeredService(serviceDefinition, plan);
|
||||
BackingServices backingServices = null;
|
||||
if (brokeredService != null && !CollectionUtils.isEmpty(brokeredService.getServices())) {
|
||||
@@ -86,15 +86,16 @@ class AppDeploymentInstanceWorkflow {
|
||||
}
|
||||
|
||||
private BrokeredService findBrokeredService(ServiceDefinition serviceDefinition,
|
||||
Plan plan) {
|
||||
Plan plan) {
|
||||
String serviceName = serviceDefinition.getName();
|
||||
String planName = plan.getName();
|
||||
|
||||
return brokeredServices.stream()
|
||||
.filter(brokeredService ->
|
||||
brokeredService.getServiceName().equals(serviceName)
|
||||
&& brokeredService.getPlanName().equals(planName))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
.filter(brokeredService ->
|
||||
brokeredService.getServiceName().equals(serviceName)
|
||||
&& brokeredService.getPlanName().equals(planName))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,24 +34,27 @@ import org.springframework.cloud.servicebroker.model.instance.UpdateServiceInsta
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
@Order(0)
|
||||
public class AppDeploymentUpdateServiceInstanceWorkflow
|
||||
extends AppDeploymentInstanceWorkflow
|
||||
public class AppDeploymentUpdateServiceInstanceWorkflow extends AppDeploymentInstanceWorkflow
|
||||
implements UpdateServiceInstanceWorkflow {
|
||||
|
||||
private final Logger log = Loggers.getLogger(AppDeploymentUpdateServiceInstanceWorkflow.class);
|
||||
|
||||
private final BackingAppDeploymentService deploymentService;
|
||||
|
||||
private final BackingServicesProvisionService backingServicesProvisionService;
|
||||
|
||||
private final BackingApplicationsParametersTransformationService appsParametersTransformationService;
|
||||
|
||||
private final BackingServicesParametersTransformationService servicesParametersTransformationService;
|
||||
|
||||
private final TargetService targetService;
|
||||
|
||||
public AppDeploymentUpdateServiceInstanceWorkflow(BrokeredServices brokeredServices,
|
||||
BackingAppDeploymentService deploymentService,
|
||||
BackingServicesProvisionService backingServicesProvisionService,
|
||||
BackingApplicationsParametersTransformationService appsParametersTransformationService,
|
||||
BackingServicesParametersTransformationService servicesParametersTransformationService,
|
||||
TargetService targetService) {
|
||||
BackingAppDeploymentService deploymentService,
|
||||
BackingServicesProvisionService backingServicesProvisionService,
|
||||
BackingApplicationsParametersTransformationService appsParametersTransformationService,
|
||||
BackingServicesParametersTransformationService servicesParametersTransformationService,
|
||||
TargetService targetService) {
|
||||
super(brokeredServices);
|
||||
this.deploymentService = deploymentService;
|
||||
this.backingServicesProvisionService = backingServicesProvisionService;
|
||||
@@ -60,6 +63,7 @@ public class AppDeploymentUpdateServiceInstanceWorkflow
|
||||
this.targetService = targetService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> update(UpdateServiceInstanceRequest request, UpdateServiceInstanceResponse response) {
|
||||
return updateBackingServices(request)
|
||||
.thenMany(updateBackingApplications(request))
|
||||
@@ -81,7 +85,8 @@ public class AppDeploymentUpdateServiceInstanceWorkflow
|
||||
.doOnComplete(() -> log.debug("Finished updating backing services for {}/{}",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName()))
|
||||
.doOnError(exception -> log.error(String.format("Error updating backing services for %s/%s with error '%s'",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()), exception));
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()),
|
||||
exception));
|
||||
}
|
||||
|
||||
private Flux<String> updateBackingApplications(UpdateServiceInstanceRequest request) {
|
||||
@@ -97,8 +102,10 @@ public class AppDeploymentUpdateServiceInstanceWorkflow
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName()))
|
||||
.doOnComplete(() -> log.debug("Finished updating backing applications for {}/{}",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName()))
|
||||
.doOnError(exception -> log.error(String.format("Error updating backing applications for %s/%s with error '%s'",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()), exception));
|
||||
.doOnError(
|
||||
exception -> log.error(String.format("Error updating backing applications for %s/%s with error '%s'",
|
||||
request.getServiceDefinition().getName(), request.getPlan().getName(), exception.getMessage()),
|
||||
exception));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,7 +115,8 @@ public class AppDeploymentUpdateServiceInstanceWorkflow
|
||||
|
||||
@Override
|
||||
public Mono<UpdateServiceInstanceResponseBuilder> buildResponse(UpdateServiceInstanceRequest request,
|
||||
UpdateServiceInstanceResponseBuilder responseBuilder) {
|
||||
UpdateServiceInstanceResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder.async(true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,4 +45,5 @@ class BackingApplicationTest {
|
||||
backingApp.setEnvironment(null);
|
||||
assertThat(backingApp.toString()).isNotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.cloud.appbroker.deployer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -24,9 +27,6 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@@ -36,6 +36,7 @@ class DefaultBackingAppDeploymentServiceTest {
|
||||
private DeployerClient deployerClient;
|
||||
|
||||
private BackingAppDeploymentService backingAppDeploymentService;
|
||||
|
||||
private BackingApplications backingApps;
|
||||
|
||||
@BeforeEach
|
||||
@@ -92,4 +93,5 @@ class DefaultBackingAppDeploymentServiceTest {
|
||||
.expectNextMatches(expectedValues::remove)
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,24 +38,25 @@ class DefaultBackingServicesProvisionServiceTest {
|
||||
private DeployerClient deployerClient;
|
||||
|
||||
private BackingServicesProvisionService backingServicesProvisionService;
|
||||
|
||||
private BackingServices backingServices;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
backingServicesProvisionService = new DefaultBackingServicesProvisionService(deployerClient);
|
||||
backingServices = BackingServices.builder()
|
||||
.backingService(BackingService.builder()
|
||||
.serviceInstanceName("si1")
|
||||
.name("service1")
|
||||
.plan("standard")
|
||||
.parameters(Collections.singletonMap("key1", "value1"))
|
||||
.build())
|
||||
.backingService(BackingService.builder()
|
||||
.serviceInstanceName("si2")
|
||||
.name("service2")
|
||||
.plan("free")
|
||||
.build())
|
||||
.build();
|
||||
.backingService(BackingService.builder()
|
||||
.serviceInstanceName("si1")
|
||||
.name("service1")
|
||||
.plan("standard")
|
||||
.parameters(Collections.singletonMap("key1", "value1"))
|
||||
.build())
|
||||
.backingService(BackingService.builder()
|
||||
.serviceInstanceName("si2")
|
||||
.name("service2")
|
||||
.plan("free")
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -118,4 +119,4 @@ class DefaultBackingServicesProvisionServiceTest {
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ import reactor.test.StepVerifier;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@SuppressWarnings("UnassignedFluxMonoInstance")
|
||||
@@ -73,14 +73,13 @@ class DeployerClientTest {
|
||||
.expectNext(APP_NAME)
|
||||
.verifyComplete();
|
||||
|
||||
verify(appDeployer).deploy(argThat(matchesRequest(APP_NAME, APP_PATH, Collections.emptyMap(),
|
||||
then(appDeployer).should().deploy(argThat(matchesRequest(APP_NAME, APP_PATH, Collections.emptyMap(),
|
||||
Collections.emptyMap(), Collections.emptyList())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("serial")
|
||||
void shouldDeployAppWithProperties() {
|
||||
// given
|
||||
setupAppDeployer();
|
||||
|
||||
Map<String, String> properties = new HashMap<String, String>() {{
|
||||
@@ -99,14 +98,13 @@ class DeployerClientTest {
|
||||
.expectNext(APP_NAME)
|
||||
.verifyComplete();
|
||||
|
||||
verify(appDeployer).deploy(argThat(matchesRequest(APP_NAME, APP_PATH, properties,
|
||||
then(appDeployer).should().deploy(argThat(matchesRequest(APP_NAME, APP_PATH, properties,
|
||||
Collections.emptyMap(), Collections.emptyList())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("serial")
|
||||
void shouldDeployAppWithService() {
|
||||
// given
|
||||
setupAppDeployer();
|
||||
|
||||
BackingApplication application =
|
||||
@@ -115,8 +113,8 @@ class DeployerClientTest {
|
||||
.name(APP_NAME)
|
||||
.path(APP_PATH)
|
||||
.services(ServicesSpec.builder()
|
||||
.serviceInstanceName("my-db-service")
|
||||
.build())
|
||||
.serviceInstanceName("my-db-service")
|
||||
.build())
|
||||
.build();
|
||||
|
||||
// when
|
||||
@@ -125,14 +123,13 @@ class DeployerClientTest {
|
||||
.expectNext(APP_NAME)
|
||||
.verifyComplete();
|
||||
|
||||
verify(appDeployer).deploy(argThat(matchesRequest(APP_NAME, APP_PATH, Collections.emptyMap(),
|
||||
then(appDeployer).should().deploy(argThat(matchesRequest(APP_NAME, APP_PATH, Collections.emptyMap(),
|
||||
Collections.emptyMap(), Collections.singletonList("my-db-service"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("serial")
|
||||
void shouldDeployAppWithEnvironmentVariables() {
|
||||
// given
|
||||
setupAppDeployer();
|
||||
|
||||
Map<String, Object> environment = new HashMap<String, Object>() {{
|
||||
@@ -151,15 +148,14 @@ class DeployerClientTest {
|
||||
.expectNext(APP_NAME)
|
||||
.verifyComplete();
|
||||
|
||||
verify(appDeployer).deploy(argThat(matchesRequest(APP_NAME, APP_PATH, Collections.emptyMap(),
|
||||
then(appDeployer).should().deploy(argThat(matchesRequest(APP_NAME, APP_PATH, Collections.emptyMap(),
|
||||
environment, Collections.emptyList())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUndeployApp() {
|
||||
// given
|
||||
when(appDeployer.undeploy(any()))
|
||||
.thenReturn(Mono.just(UndeployApplicationResponse.builder()
|
||||
given(appDeployer.undeploy(any()))
|
||||
.willReturn(Mono.just(UndeployApplicationResponse.builder()
|
||||
.name(APP_NAME)
|
||||
.build()));
|
||||
|
||||
@@ -174,14 +170,13 @@ class DeployerClientTest {
|
||||
.expectNext(APP_NAME)
|
||||
.verifyComplete();
|
||||
|
||||
verify(appDeployer).undeploy(argThat(request -> APP_NAME.equals(request.getName())));
|
||||
then(appDeployer).should().undeploy(argThat(request -> APP_NAME.equals(request.getName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotReturnErrorWhenUndeployingAppThatDoesNotExist() {
|
||||
// given
|
||||
when(appDeployer.undeploy(any()))
|
||||
.thenReturn(Mono.error(new IllegalStateException("app does not exist")));
|
||||
given(appDeployer.undeploy(any()))
|
||||
.willReturn(Mono.error(new IllegalStateException("app does not exist")));
|
||||
|
||||
BackingApplication application = BackingApplication.builder()
|
||||
.name(APP_NAME)
|
||||
@@ -194,14 +189,13 @@ class DeployerClientTest {
|
||||
.expectNext(APP_NAME)
|
||||
.verifyComplete();
|
||||
|
||||
verify(appDeployer).undeploy(argThat(request -> APP_NAME.equals(request.getName())));
|
||||
then(appDeployer).should().undeploy(argThat(request -> APP_NAME.equals(request.getName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCreateServiceInstance() {
|
||||
// given
|
||||
when(appDeployer.createServiceInstance(any()))
|
||||
.thenReturn(Mono.just(CreateServiceInstanceResponse.builder()
|
||||
given(appDeployer.createServiceInstance(any()))
|
||||
.willReturn(Mono.just(CreateServiceInstanceResponse.builder()
|
||||
.name(SERVICE_INSTANCE_NAME)
|
||||
.build()));
|
||||
|
||||
@@ -215,15 +209,14 @@ class DeployerClientTest {
|
||||
.expectNext(SERVICE_INSTANCE_NAME)
|
||||
.verifyComplete();
|
||||
|
||||
verify(appDeployer).createServiceInstance(argThat(request ->
|
||||
then(appDeployer).should().createServiceInstance(argThat(request ->
|
||||
SERVICE_INSTANCE_NAME.equals(request.getServiceInstanceName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUpdateServiceInstance() {
|
||||
// given
|
||||
when(appDeployer.updateServiceInstance(any()))
|
||||
.thenReturn(Mono.just(UpdateServiceInstanceResponse.builder()
|
||||
given(appDeployer.updateServiceInstance(any()))
|
||||
.willReturn(Mono.just(UpdateServiceInstanceResponse.builder()
|
||||
.name(SERVICE_INSTANCE_NAME)
|
||||
.build()));
|
||||
|
||||
@@ -237,15 +230,14 @@ class DeployerClientTest {
|
||||
.expectNext(SERVICE_INSTANCE_NAME)
|
||||
.verifyComplete();
|
||||
|
||||
verify(appDeployer).updateServiceInstance(argThat(request ->
|
||||
then(appDeployer).should().updateServiceInstance(argThat(request ->
|
||||
SERVICE_INSTANCE_NAME.equals(request.getServiceInstanceName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnErrorWhenUpdatingServiceInstanceThatDoesNotExist() {
|
||||
// given
|
||||
when(appDeployer.updateServiceInstance(any()))
|
||||
.thenReturn(Mono.error(new IllegalStateException("service instance does not exist")));
|
||||
given(appDeployer.updateServiceInstance(any()))
|
||||
.willReturn(Mono.error(new IllegalStateException("service instance does not exist")));
|
||||
|
||||
BackingService service = BackingService.builder()
|
||||
.serviceInstanceName(SERVICE_INSTANCE_NAME)
|
||||
@@ -257,15 +249,14 @@ class DeployerClientTest {
|
||||
.expectErrorMessage("service instance does not exist")
|
||||
.verify();
|
||||
|
||||
verify(appDeployer).updateServiceInstance(argThat(request ->
|
||||
then(appDeployer).should().updateServiceInstance(argThat(request ->
|
||||
SERVICE_INSTANCE_NAME.equals(request.getServiceInstanceName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDeleteServiceInstance() {
|
||||
// given
|
||||
when(appDeployer.deleteServiceInstance(any()))
|
||||
.thenReturn(Mono.just(DeleteServiceInstanceResponse.builder()
|
||||
given(appDeployer.deleteServiceInstance(any()))
|
||||
.willReturn(Mono.just(DeleteServiceInstanceResponse.builder()
|
||||
.name(SERVICE_INSTANCE_NAME)
|
||||
.build()));
|
||||
|
||||
@@ -279,15 +270,14 @@ class DeployerClientTest {
|
||||
.expectNext(SERVICE_INSTANCE_NAME)
|
||||
.verifyComplete();
|
||||
|
||||
verify(appDeployer).deleteServiceInstance(argThat(request ->
|
||||
then(appDeployer).should().deleteServiceInstance(argThat(request ->
|
||||
SERVICE_INSTANCE_NAME.equals(request.getServiceInstanceName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotReturnErrorWhenDeletingServiceInstanceThatDoesNotExist() {
|
||||
// given
|
||||
when(appDeployer.deleteServiceInstance(any()))
|
||||
.thenReturn(Mono.error(new IllegalStateException("service instance does not exist")));
|
||||
given(appDeployer.deleteServiceInstance(any()))
|
||||
.willReturn(Mono.error(new IllegalStateException("service instance does not exist")));
|
||||
|
||||
BackingService service = BackingService.builder()
|
||||
.serviceInstanceName(SERVICE_INSTANCE_NAME)
|
||||
@@ -299,14 +289,14 @@ class DeployerClientTest {
|
||||
.expectNext(SERVICE_INSTANCE_NAME)
|
||||
.verifyComplete();
|
||||
|
||||
verify(appDeployer).deleteServiceInstance(argThat(request ->
|
||||
then(appDeployer).should().deleteServiceInstance(argThat(request ->
|
||||
SERVICE_INSTANCE_NAME.equals(request.getServiceInstanceName())));
|
||||
}
|
||||
|
||||
private ArgumentMatcher<DeployApplicationRequest> matchesRequest(String appName, String appArchive,
|
||||
Map<String, String> properties,
|
||||
Map<String, Object> environment,
|
||||
List<String> services) {
|
||||
Map<String, String> properties,
|
||||
Map<String, Object> environment,
|
||||
List<String> services) {
|
||||
return request ->
|
||||
request.getName().equals(appName) &&
|
||||
request.getPath().equals(appArchive) &&
|
||||
@@ -316,9 +306,10 @@ class DeployerClientTest {
|
||||
}
|
||||
|
||||
private void setupAppDeployer() {
|
||||
when(appDeployer.deploy(any()))
|
||||
.thenReturn(Mono.just(DeployApplicationResponse.builder()
|
||||
given(appDeployer.deploy(any()))
|
||||
.willReturn(Mono.just(DeployApplicationResponse.builder()
|
||||
.name(APP_NAME)
|
||||
.build()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user