committed by
Scott Frederick
parent
e9010c2851
commit
255a9cad2b
@@ -48,6 +48,7 @@ configure(allprojects) {
|
||||
springVersion = project.findProperty("springVersion") ?: "5.0.10.RELEASE"
|
||||
reactorVersion = project.findProperty("reactorVersion") ?: "Bismuth-SR14"
|
||||
openServiceBrokerVersion = "3.0.0.BUILD-SNAPSHOT"
|
||||
springCredhubVersion = "2.0.0.BUILD-SNAPSHOT"
|
||||
cfJavaClientVersion = "3.13.0.RELEASE"
|
||||
mockitoVersion = "2.23.4"
|
||||
immutablesVersion = "2.7.3"
|
||||
|
||||
@@ -6,5 +6,5 @@ include "spring-cloud-app-broker-core"
|
||||
include "spring-cloud-app-broker-autoconfigure"
|
||||
include "spring-cloud-app-broker-sample"
|
||||
include "spring-cloud-app-broker-acceptance-tests"
|
||||
include "spring-cloud-app-broker-security-credhub"
|
||||
include 'spring-cloud-starter-app-broker'
|
||||
|
||||
|
||||
@@ -26,20 +26,29 @@ dependencies {
|
||||
implementation project(":spring-cloud-app-broker-core")
|
||||
implementation project(":spring-cloud-app-broker-deployer")
|
||||
implementation project(":spring-cloud-app-broker-deployer-cloudfoundry")
|
||||
implementation project(":spring-cloud-app-broker-security-credhub")
|
||||
implementation("org.springframework.boot:spring-boot-starter")
|
||||
implementation("org.cloudfoundry:cloudfoundry-client-reactor:${cfJavaClientVersion}")
|
||||
implementation("org.cloudfoundry:cloudfoundry-operations:${cfJavaClientVersion}")
|
||||
implementation("io.projectreactor:reactor-core")
|
||||
implementation("io.projectreactor.ipc:reactor-netty")
|
||||
api("org.immutables:value:${immutablesVersion}")
|
||||
|
||||
compileOnly("org.cloudfoundry:cloudfoundry-client-reactor:${cfJavaClientVersion}")
|
||||
compileOnly("org.cloudfoundry:cloudfoundry-operations:${cfJavaClientVersion}")
|
||||
compileOnly("org.springframework.credhub:spring-credhub-starter:${springCredhubVersion}")
|
||||
|
||||
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
|
||||
annotationProcessor("org.springframework.boot:spring-boot-autoconfigure-processor")
|
||||
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
|
||||
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-webflux")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api")
|
||||
testImplementation("org.mockito:mockito-junit-jupiter:${mockitoVersion}")
|
||||
|
||||
testCompileOnly("org.cloudfoundry:cloudfoundry-client-reactor:${cfJavaClientVersion}")
|
||||
testCompileOnly("org.cloudfoundry:cloudfoundry-operations:${cfJavaClientVersion}")
|
||||
testCompileOnly("org.springframework.credhub:spring-credhub-starter:${springCredhubVersion}")
|
||||
}
|
||||
|
||||
compileJava.dependsOn(processResources)
|
||||
|
||||
@@ -211,13 +211,13 @@ public class AppBrokerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public WorkflowServiceInstanceBindingService serviceInstanceBindingService(
|
||||
ServiceInstanceBindingStateRepository stateRepository,
|
||||
@Autowired(required = false) List<CreateServiceInstanceAppBindingWorkflow> createServiceInstanceAppBindingWorkflows,
|
||||
@Autowired(required = false) List<CreateServiceInstanceRouteBindingWorkflow> createServiceInstanceRouteBindingWorkflows,
|
||||
@Autowired(required = false) List<DeleteServiceInstanceBindingWorkflow> deleteServiceInstanceBindingWorkflows) {
|
||||
ServiceInstanceBindingStateRepository stateRepository,
|
||||
@Autowired(required = false) List<CreateServiceInstanceAppBindingWorkflow> createServiceInstanceAppBindingWorkflows,
|
||||
@Autowired(required = false) List<CreateServiceInstanceRouteBindingWorkflow> createServiceInstanceRouteBindingWorkflows,
|
||||
@Autowired(required = false) List<DeleteServiceInstanceBindingWorkflow> deleteServiceInstanceBindingWorkflows) {
|
||||
return new WorkflowServiceInstanceBindingService(stateRepository,
|
||||
createServiceInstanceAppBindingWorkflows,
|
||||
createServiceInstanceRouteBindingWorkflows,
|
||||
deleteServiceInstanceBindingWorkflows);
|
||||
createServiceInstanceAppBindingWorkflows,
|
||||
createServiceInstanceRouteBindingWorkflows,
|
||||
deleteServiceInstanceBindingWorkflows);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2016-2018 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.appbroker.autoconfigure;
|
||||
|
||||
import org.springframework.cloud.appbroker.workflow.binding.CredHubPersistingCreateServiceInstanceAppBindingWorkflow;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.cloud.appbroker.service.CreateServiceInstanceAppBindingWorkflow;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.credhub.core.ReactiveCredHubOperations;
|
||||
|
||||
@Configuration
|
||||
@AutoConfigureBefore(AppBrokerAutoConfiguration.class)
|
||||
public class CredHubAutoConfiguration {
|
||||
|
||||
@Value("${spring.application.name}")
|
||||
private String appName;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(ReactiveCredHubOperations.class)
|
||||
public CreateServiceInstanceAppBindingWorkflow credhubPersistingCreateServiceInstanceAppBindingWorkflow(ReactiveCredHubOperations credHubOperations) {
|
||||
return new CredHubPersistingCreateServiceInstanceAppBindingWorkflow(credHubOperations, appName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.appbroker.autoconfigure.CloudFoundryAppDeployerAutoConfiguration,\
|
||||
org.springframework.cloud.appbroker.autoconfigure.CredHubAutoConfiguration,\
|
||||
org.springframework.cloud.appbroker.autoconfigure.AppBrokerAutoConfiguration
|
||||
@@ -17,8 +17,11 @@
|
||||
package org.springframework.cloud.appbroker.autoconfigure;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.cloud.appbroker.workflow.binding.CredHubPersistingCreateServiceInstanceAppBindingWorkflow;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.cloud.appbroker.deployer.BackingAppDeploymentService;
|
||||
import org.springframework.cloud.appbroker.deployer.BackingApplications;
|
||||
@@ -35,6 +38,7 @@ import org.springframework.cloud.appbroker.extensions.parameters.ParameterMappin
|
||||
import org.springframework.cloud.appbroker.extensions.parameters.PropertyMappingParametersTransformerFactory;
|
||||
import org.springframework.cloud.appbroker.extensions.targets.SpacePerServiceInstance;
|
||||
import org.springframework.cloud.appbroker.extensions.targets.TargetService;
|
||||
import org.springframework.cloud.appbroker.service.CreateServiceInstanceAppBindingWorkflow;
|
||||
import org.springframework.cloud.appbroker.service.WorkflowServiceInstanceBindingService;
|
||||
import org.springframework.cloud.appbroker.service.WorkflowServiceInstanceService;
|
||||
import org.springframework.cloud.appbroker.state.ServiceInstanceBindingStateRepository;
|
||||
@@ -42,17 +46,47 @@ import org.springframework.cloud.appbroker.state.ServiceInstanceStateRepository;
|
||||
import org.springframework.cloud.appbroker.workflow.instance.AppDeploymentCreateServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.appbroker.workflow.instance.AppDeploymentDeleteServiceInstanceWorkflow;
|
||||
import org.springframework.cloud.appbroker.workflow.instance.AppDeploymentUpdateServiceInstanceWorkflow;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.credhub.core.ReactiveCredHubOperations;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
class AppBrokerAutoConfigurationTest {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(AppBrokerAutoConfiguration.class));
|
||||
.withConfiguration(AutoConfigurations.of(AppBrokerAutoConfiguration.class, CredHubAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void servicesAreCreatedWithCloudFoundryConfigured() {
|
||||
configuredContext()
|
||||
.run(this::assertContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
void servicesAreCreatedWithCloudFoundryAndCredHubConfigured() {
|
||||
configuredContext()
|
||||
.withUserConfiguration(CredHubConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertContext(context);
|
||||
assertThat(context)
|
||||
.hasSingleBean(CreateServiceInstanceAppBindingWorkflow.class)
|
||||
.getBean(CreateServiceInstanceAppBindingWorkflow.class)
|
||||
.isExactlyInstanceOf(CredHubPersistingCreateServiceInstanceAppBindingWorkflow.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void servicesAreNotCreatedWithoutDeployerConfiguration() {
|
||||
this.contextRunner
|
||||
.run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(BackingApplications.class);
|
||||
assertThat(context).doesNotHaveBean(DeployerClient.class);
|
||||
});
|
||||
}
|
||||
|
||||
private ApplicationContextRunner configuredContext() {
|
||||
return this.contextRunner
|
||||
.withConfiguration(AutoConfigurations.of(CloudFoundryAppDeployerAutoConfiguration.class))
|
||||
.withPropertyValues(
|
||||
"spring.cloud.appbroker.services[0].service-name=service1",
|
||||
@@ -76,70 +110,70 @@ class AppBrokerAutoConfigurationTest {
|
||||
"spring.cloud.appbroker.deployer.cloudfoundry.api-host=https://api.example.com",
|
||||
"spring.cloud.appbroker.deployer.cloudfoundry.username=user",
|
||||
"spring.cloud.appbroker.deployer.cloudfoundry.password=secret"
|
||||
)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(BrokeredServices.class);
|
||||
BrokeredServices brokeredServices = context.getBean(BrokeredServices.class);
|
||||
assertThat(brokeredServices).hasSize(2);
|
||||
|
||||
assertThat(brokeredServices.get(0).getServiceName()).isEqualTo("service1");
|
||||
assertThat(brokeredServices.get(0).getPlanName()).isEqualTo("service1-plan1");
|
||||
|
||||
assertThat(brokeredServices.get(0).getApps().get(0).getName()).isEqualTo("app1");
|
||||
assertThat(brokeredServices.get(0).getApps().get(0).getPath()).isEqualTo("classpath:app1.jar");
|
||||
assertThat(brokeredServices.get(0).getApps().get(0).getProperties().get("memory")).isEqualTo("1G");
|
||||
assertThat(brokeredServices.get(0).getApps().get(0).getProperties().get("instances")).isNull();
|
||||
|
||||
assertThat(brokeredServices.get(0).getApps().get(1).getName()).isEqualTo("app2");
|
||||
assertThat(brokeredServices.get(0).getApps().get(1).getPath()).isEqualTo("classpath:app2.jar");
|
||||
assertThat(brokeredServices.get(0).getApps().get(1).getProperties().get("memory")).isEqualTo("2G");
|
||||
assertThat(brokeredServices.get(0).getApps().get(1).getProperties().get("instances")).isEqualTo("2");
|
||||
|
||||
assertThat(brokeredServices.get(1).getServiceName()).isEqualTo("service2");
|
||||
assertThat(brokeredServices.get(1).getPlanName()).isEqualTo("service2-plan1");
|
||||
|
||||
assertThat(brokeredServices.get(1).getApps().get(0).getName()).isEqualTo("app3");
|
||||
assertThat(brokeredServices.get(1).getApps().get(0).getPath()).isEqualTo("classpath:app3.jar");
|
||||
|
||||
assertThat(context).hasSingleBean(DeployerClient.class);
|
||||
assertThat(context).hasSingleBean(BrokeredServices.class);
|
||||
|
||||
assertThat(context).hasSingleBean(ServiceInstanceStateRepository.class);
|
||||
assertThat(context).hasSingleBean(ServiceInstanceBindingStateRepository.class);
|
||||
|
||||
assertThat(context).hasSingleBean(BackingAppDeploymentService.class);
|
||||
assertThat(context).hasSingleBean(BackingServicesProvisionService.class);
|
||||
|
||||
assertThat(context).hasSingleBean(BackingApplicationsParametersTransformationService.class);
|
||||
assertThat(context).hasSingleBean(EnvironmentMappingParametersTransformerFactory.class);
|
||||
assertThat(context).hasSingleBean(PropertyMappingParametersTransformerFactory.class);
|
||||
assertThat(context).hasSingleBean(ParameterMappingParametersTransformerFactory.class);
|
||||
|
||||
assertThat(context).hasSingleBean(BackingServicesParametersTransformationService.class);
|
||||
|
||||
assertThat(context).hasSingleBean(CredentialProviderService.class);
|
||||
assertThat(context).hasSingleBean(SpringSecurityBasicAuthCredentialProviderFactory.class);
|
||||
assertThat(context).hasSingleBean(SpringSecurityOAuth2CredentialProviderFactory.class);
|
||||
|
||||
assertThat(context).hasSingleBean(TargetService.class);
|
||||
assertThat(context).hasSingleBean(SpacePerServiceInstance.class);
|
||||
|
||||
assertThat(context).hasSingleBean(WorkflowServiceInstanceService.class);
|
||||
assertThat(context).hasSingleBean(WorkflowServiceInstanceBindingService.class);
|
||||
|
||||
assertThat(context).hasSingleBean(AppDeploymentCreateServiceInstanceWorkflow.class);
|
||||
assertThat(context).hasSingleBean(AppDeploymentDeleteServiceInstanceWorkflow.class);
|
||||
assertThat(context).hasSingleBean(AppDeploymentUpdateServiceInstanceWorkflow.class);
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void servicesAreNotCreatedWithoutDeployerConfiguration() {
|
||||
this.contextRunner
|
||||
.run((context) -> {
|
||||
assertThat(context).doesNotHaveBean(BackingApplications.class);
|
||||
assertThat(context).doesNotHaveBean(DeployerClient.class);
|
||||
});
|
||||
private void assertContext(AssertableApplicationContext context) {
|
||||
assertThat(context).hasSingleBean(BrokeredServices.class);
|
||||
BrokeredServices brokeredServices = context.getBean(BrokeredServices.class);
|
||||
assertThat(brokeredServices).hasSize(2);
|
||||
|
||||
assertThat(brokeredServices.get(0).getServiceName()).isEqualTo("service1");
|
||||
assertThat(brokeredServices.get(0).getPlanName()).isEqualTo("service1-plan1");
|
||||
|
||||
assertThat(brokeredServices.get(0).getApps().get(0).getName()).isEqualTo("app1");
|
||||
assertThat(brokeredServices.get(0).getApps().get(0).getPath()).isEqualTo("classpath:app1.jar");
|
||||
assertThat(brokeredServices.get(0).getApps().get(0).getProperties().get("memory")).isEqualTo("1G");
|
||||
assertThat(brokeredServices.get(0).getApps().get(0).getProperties().get("instances")).isNull();
|
||||
|
||||
assertThat(brokeredServices.get(0).getApps().get(1).getName()).isEqualTo("app2");
|
||||
assertThat(brokeredServices.get(0).getApps().get(1).getPath()).isEqualTo("classpath:app2.jar");
|
||||
assertThat(brokeredServices.get(0).getApps().get(1).getProperties().get("memory")).isEqualTo("2G");
|
||||
assertThat(brokeredServices.get(0).getApps().get(1).getProperties().get("instances")).isEqualTo("2");
|
||||
|
||||
assertThat(brokeredServices.get(1).getServiceName()).isEqualTo("service2");
|
||||
assertThat(brokeredServices.get(1).getPlanName()).isEqualTo("service2-plan1");
|
||||
|
||||
assertThat(brokeredServices.get(1).getApps().get(0).getName()).isEqualTo("app3");
|
||||
assertThat(brokeredServices.get(1).getApps().get(0).getPath()).isEqualTo("classpath:app3.jar");
|
||||
|
||||
assertThat(context).hasSingleBean(DeployerClient.class);
|
||||
assertThat(context).hasSingleBean(BrokeredServices.class);
|
||||
|
||||
assertThat(context).hasSingleBean(ServiceInstanceStateRepository.class);
|
||||
assertThat(context).hasSingleBean(ServiceInstanceBindingStateRepository.class);
|
||||
|
||||
assertThat(context).hasSingleBean(BackingAppDeploymentService.class);
|
||||
assertThat(context).hasSingleBean(BackingServicesProvisionService.class);
|
||||
|
||||
assertThat(context).hasSingleBean(BackingApplicationsParametersTransformationService.class);
|
||||
assertThat(context).hasSingleBean(EnvironmentMappingParametersTransformerFactory.class);
|
||||
assertThat(context).hasSingleBean(PropertyMappingParametersTransformerFactory.class);
|
||||
assertThat(context).hasSingleBean(ParameterMappingParametersTransformerFactory.class);
|
||||
|
||||
assertThat(context).hasSingleBean(BackingServicesParametersTransformationService.class);
|
||||
|
||||
assertThat(context).hasSingleBean(CredentialProviderService.class);
|
||||
assertThat(context).hasSingleBean(SpringSecurityBasicAuthCredentialProviderFactory.class);
|
||||
assertThat(context).hasSingleBean(SpringSecurityOAuth2CredentialProviderFactory.class);
|
||||
|
||||
assertThat(context).hasSingleBean(TargetService.class);
|
||||
assertThat(context).hasSingleBean(SpacePerServiceInstance.class);
|
||||
|
||||
assertThat(context).hasSingleBean(WorkflowServiceInstanceService.class);
|
||||
assertThat(context).hasSingleBean(WorkflowServiceInstanceBindingService.class);
|
||||
|
||||
assertThat(context).hasSingleBean(AppDeploymentCreateServiceInstanceWorkflow.class);
|
||||
assertThat(context).hasSingleBean(AppDeploymentDeleteServiceInstanceWorkflow.class);
|
||||
assertThat(context).hasSingleBean(AppDeploymentUpdateServiceInstanceWorkflow.class);
|
||||
}
|
||||
|
||||
@TestConfiguration
|
||||
public static class CredHubConfiguration {
|
||||
@Bean
|
||||
public ReactiveCredHubOperations credHubOperations() {
|
||||
return mock(ReactiveCredHubOperations.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
spring:
|
||||
application:
|
||||
name: foo-app
|
||||
logging:
|
||||
level:
|
||||
cloudfoundry-client: DEBUG
|
||||
38
spring-cloud-app-broker-security-credhub/build.gradle
Normal file
38
spring-cloud-app-broker-security-credhub/build.gradle
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2016-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
description = "Spring Cloud App Broker Deployer Security CredHub"
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootVersion}"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(":spring-cloud-app-broker-core")
|
||||
implementation("io.projectreactor:reactor-core")
|
||||
implementation("org.springframework.cloud:spring-cloud-open-service-broker-core:${openServiceBrokerVersion}")
|
||||
implementation("org.springframework.credhub:spring-credhub-starter:${springCredhubVersion}")
|
||||
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
|
||||
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-webflux")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||
testImplementation("io.projectreactor:reactor-test")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api")
|
||||
testImplementation("org.mockito:mockito-junit-jupiter:${mockitoVersion}")
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2016-2018 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.appbroker.workflow.binding;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.Logger;
|
||||
import reactor.util.Loggers;
|
||||
|
||||
import org.springframework.cloud.appbroker.service.CreateServiceInstanceAppBindingWorkflow;
|
||||
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.core.annotation.Order;
|
||||
import org.springframework.credhub.core.ReactiveCredHubOperations;
|
||||
import org.springframework.credhub.support.json.JsonCredentialRequest;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Order(50)
|
||||
public class CredHubPersistingCreateServiceInstanceAppBindingWorkflow implements CreateServiceInstanceAppBindingWorkflow {
|
||||
|
||||
private static final Logger LOG = Loggers.getLogger(CredHubPersistingCreateServiceInstanceAppBindingWorkflow.class);
|
||||
|
||||
private static final String CREDENTIALS_KEY = "credhub-ref";
|
||||
|
||||
private static final String CREDENTIALS_VALUE_TEMPLATE = "/c/%s/%s/%s/credentials-json";
|
||||
|
||||
private final String appName;
|
||||
|
||||
private final ReactiveCredHubOperations credHubOperations;
|
||||
|
||||
public CredHubPersistingCreateServiceInstanceAppBindingWorkflow(ReactiveCredHubOperations credHubOperations, String appName) {
|
||||
this.credHubOperations = credHubOperations;
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Void> create(CreateServiceInstanceBindingRequest request) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<CreateServiceInstanceAppBindingResponseBuilder> buildResponse(CreateServiceInstanceBindingRequest request,
|
||||
CreateServiceInstanceAppBindingResponseBuilder responseBuilder) {
|
||||
return Mono.just(responseBuilder.build())
|
||||
.flatMap(response -> {
|
||||
if (!CollectionUtils.isEmpty(response.getCredentials())) {
|
||||
return persistBindingCredentials(request, response)
|
||||
.doOnRequest(l -> LOG.debug("Storing binding credentials in CredHub"))
|
||||
.doOnSuccess(r -> LOG.debug("Finished storing binding credentials in CredHub"))
|
||||
.doOnError(exception -> LOG.debug("Error storing binding credentials in CredHub with error {}", exception));
|
||||
}
|
||||
return Mono.just(responseBuilder);
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<CreateServiceInstanceAppBindingResponseBuilder> persistBindingCredentials(CreateServiceInstanceBindingRequest request,
|
||||
CreateServiceInstanceAppBindingResponse response) {
|
||||
return credHubOperations
|
||||
.credentials()
|
||||
.write(JsonCredentialRequest
|
||||
.builder()
|
||||
.value(response.getCredentials())
|
||||
.build())
|
||||
.thenReturn(CreateServiceInstanceAppBindingResponse
|
||||
.builder()
|
||||
.async(response.isAsync())
|
||||
.bindingExisted(response.isBindingExisted())
|
||||
.credentials(CREDENTIALS_KEY, formatCredentials(request))
|
||||
.operation(response.getOperation())
|
||||
.syslogDrainUrl(response.getSyslogDrainUrl())
|
||||
.volumeMounts(response.getVolumeMounts()));
|
||||
}
|
||||
|
||||
private String formatCredentials(CreateServiceInstanceBindingRequest request) {
|
||||
return String.format(CREDENTIALS_VALUE_TEMPLATE, this.appName, request.getServiceDefinitionId(), request.getBindingId());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2016-2018 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.appbroker.workflow.binding;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
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.VolumeMount;
|
||||
import org.springframework.credhub.core.ReactiveCredHubOperations;
|
||||
import org.springframework.credhub.core.credential.ReactiveCredHubCredentialOperations;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CredHubPersistingCreateServiceInstanceAppBindingWorkflowTest {
|
||||
|
||||
@Mock
|
||||
private ReactiveCredHubOperations credHubOperations;
|
||||
|
||||
@Mock
|
||||
private ReactiveCredHubCredentialOperations credHubCredentialOperations;
|
||||
|
||||
private CredHubPersistingCreateServiceInstanceAppBindingWorkflow workflow;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
this.workflow = new CredHubPersistingCreateServiceInstanceAppBindingWorkflow(credHubOperations, "test-app-name");
|
||||
}
|
||||
|
||||
@Test
|
||||
void noBindingCredentials() {
|
||||
CreateServiceInstanceBindingRequest request = CreateServiceInstanceBindingRequest
|
||||
.builder()
|
||||
.bindingId("foo-binding-id")
|
||||
.serviceInstanceId("foo-instance-id")
|
||||
.serviceDefinitionId("foo-definition-id")
|
||||
.build();
|
||||
|
||||
CreateServiceInstanceAppBindingResponseBuilder responseBuilder = CreateServiceInstanceAppBindingResponse
|
||||
.builder()
|
||||
.bindingExisted(true)
|
||||
.syslogDrainUrl("https://logs.example.com")
|
||||
.volumeMounts(VolumeMount.builder().build())
|
||||
.volumeMounts(VolumeMount.builder().build())
|
||||
.volumeMounts(Arrays.asList(
|
||||
VolumeMount.builder().build(),
|
||||
VolumeMount.builder().build()
|
||||
));
|
||||
|
||||
StepVerifier
|
||||
.create(this.workflow.buildResponse(request, responseBuilder))
|
||||
.assertNext(createServiceInstanceAppBindingResponseBuilder -> {
|
||||
CreateServiceInstanceAppBindingResponse response = createServiceInstanceAppBindingResponseBuilder.build();
|
||||
assertThat(response.isBindingExisted()).isEqualTo(true);
|
||||
assertThat(response.getCredentials()).hasSize(0);
|
||||
assertThat(response.getSyslogDrainUrl()).isEqualTo("https://logs.example.com");
|
||||
assertThat(response.getVolumeMounts()).hasSize(4);
|
||||
|
||||
})
|
||||
.verifyComplete();
|
||||
|
||||
verifyZeroInteractions(this.credHubCredentialOperations);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("serial")
|
||||
void storeCredentialsInCredHub() {
|
||||
CreateServiceInstanceBindingRequest request = CreateServiceInstanceBindingRequest
|
||||
.builder()
|
||||
.bindingId("foo-binding-id")
|
||||
.serviceInstanceId("foo-instance-id")
|
||||
.serviceDefinitionId("foo-definition-id")
|
||||
.build();
|
||||
|
||||
Map<String, Object> credentials = new HashMap<String, Object>() {{
|
||||
put("credential4", "value4");
|
||||
put("credential5", "value5");
|
||||
}};
|
||||
|
||||
CreateServiceInstanceAppBindingResponseBuilder responseBuilder = CreateServiceInstanceAppBindingResponse
|
||||
.builder()
|
||||
.bindingExisted(true)
|
||||
.credentials("credential1", "value1")
|
||||
.credentials("credential2", 2)
|
||||
.credentials("credential3", true)
|
||||
.credentials(credentials)
|
||||
.syslogDrainUrl("https://logs.example.com")
|
||||
.volumeMounts(VolumeMount.builder().build())
|
||||
.volumeMounts(VolumeMount.builder().build())
|
||||
.volumeMounts(Arrays.asList(
|
||||
VolumeMount.builder().build(),
|
||||
VolumeMount.builder().build()
|
||||
));
|
||||
|
||||
given(this.credHubOperations.credentials())
|
||||
.willReturn(credHubCredentialOperations);
|
||||
|
||||
given(this.credHubCredentialOperations.write(any()))
|
||||
.willReturn(Mono.empty());
|
||||
|
||||
StepVerifier
|
||||
.create(this.workflow.buildResponse(request, responseBuilder))
|
||||
.assertNext(createServiceInstanceAppBindingResponseBuilder -> {
|
||||
CreateServiceInstanceAppBindingResponse response = createServiceInstanceAppBindingResponseBuilder.build();
|
||||
assertThat(response.isBindingExisted()).isEqualTo(true);
|
||||
assertThat(response.getCredentials()).hasSize(1);
|
||||
assertThat(response.getCredentials().get("credhub-ref")).isEqualTo("/c/test-app-name/foo-definition-id/foo-binding-id/credentials-json");
|
||||
assertThat(response.getSyslogDrainUrl()).isEqualTo("https://logs.example.com");
|
||||
assertThat(response.getVolumeMounts()).hasSize(4);
|
||||
|
||||
})
|
||||
.verifyComplete();
|
||||
|
||||
verify(this.credHubCredentialOperations).write(any());
|
||||
verifyNoMoreInteractions(this.credHubCredentialOperations);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user