Fix rebinding of backing services on update

This commit is contained in:
Scott Frederick
2019-01-10 14:30:09 -06:00
parent 9ada941b69
commit 71f12d951e
3 changed files with 42 additions and 9 deletions

View File

@@ -18,7 +18,6 @@ package org.springframework.cloud.appbroker.acceptance;
import org.cloudfoundry.operations.applications.ApplicationSummary;
import org.cloudfoundry.operations.services.ServiceInstance;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
@@ -40,7 +39,6 @@ class UpdateInstanceWithServicesAcceptanceTest extends CloudFoundryAcceptanceTes
private HealthListener healthListener;
@Test
@Disabled
@AppBrokerTestProperties({
"spring.cloud.appbroker.services[0].service-name=" + APP_SERVICE_NAME,
"spring.cloud.appbroker.services[0].plan-name=" + PLAN_NAME,

View File

@@ -72,6 +72,7 @@ import org.cloudfoundry.operations.applications.PushApplicationManifestRequest;
import org.cloudfoundry.operations.applications.Route;
import org.cloudfoundry.operations.organizations.OrganizationDetail;
import org.cloudfoundry.operations.organizations.OrganizationInfoRequest;
import org.cloudfoundry.operations.services.BindServiceInstanceRequest;
import org.cloudfoundry.operations.services.GetServiceInstanceRequest;
import org.cloudfoundry.operations.services.ServiceInstance;
import org.cloudfoundry.operations.services.UnbindServiceInstanceRequest;
@@ -174,7 +175,7 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware
.get(GetApplicationRequest.builder().name(name).build())
.map(ApplicationDetail::getId)
.flatMap(applicationId ->
updateApplicationEnvironment(environmentVariables, applicationId)
updateApplicationEnvironment(applicationId, environmentVariables)
.thenReturn(applicationId)
)
.flatMap(applicationId -> Mono.zip(Mono.just(applicationId),
@@ -298,7 +299,7 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware
}
private Mono<org.cloudfoundry.client.v2.applications.UpdateApplicationResponse> updateApplicationEnvironment(
Map<String, Object> environmentVariables, String applicationId) {
String applicationId, Map<String, Object> environmentVariables) {
return this.client.applicationsV2()
.update(org.cloudfoundry.client.v2.applications.UpdateApplicationRequest
.builder()
@@ -699,7 +700,7 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware
@Override
public Mono<UpdateServiceInstanceResponse> updateServiceInstance(UpdateServiceInstanceRequest request) {
CloudFoundryOperations cloudFoundryOperations = getOperations(request.getProperties());
return unbindServiceInstanceIfNecessary(request, cloudFoundryOperations)
return rebindServiceInstanceIfNecessary(request, cloudFoundryOperations)
.then(updateServiceInstanceIfNecessary(request, cloudFoundryOperations));
}
@@ -725,7 +726,7 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware
}
private Mono<Void> unbindServiceInstance(String serviceInstanceName,
CloudFoundryOperations cloudFoundryOperations) {
CloudFoundryOperations cloudFoundryOperations) {
return cloudFoundryOperations.services().getInstance(GetServiceInstanceRequest.builder()
.name(serviceInstanceName)
.build())
@@ -740,10 +741,31 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware
.then(Mono.empty()));
}
private Mono<Void> unbindServiceInstanceIfNecessary(UpdateServiceInstanceRequest request,
private Mono<Void> rebindServiceInstance(String serviceInstanceName,
CloudFoundryOperations cloudFoundryOperations) {
return cloudFoundryOperations.services().getInstance(GetServiceInstanceRequest.builder()
.name(serviceInstanceName)
.build())
.map(ServiceInstance::getApplications)
.flatMap(applications -> Flux.fromIterable(applications)
.flatMap(application -> cloudFoundryOperations.services().unbind(
UnbindServiceInstanceRequest.builder()
.applicationName(application)
.serviceInstanceName(serviceInstanceName)
.build())
.then(cloudFoundryOperations.services().bind(
BindServiceInstanceRequest.builder()
.applicationName(application)
.serviceInstanceName(serviceInstanceName)
.build()))
)
.then(Mono.empty()));
}
private Mono<Void> rebindServiceInstanceIfNecessary(UpdateServiceInstanceRequest request,
CloudFoundryOperations cloudFoundryOperations) {
if (request.isRebindOnUpdate()) {
return unbindServiceInstance(request.getServiceInstanceName(), cloudFoundryOperations);
return rebindServiceInstance(request.getServiceInstanceName(), cloudFoundryOperations);
}
return Mono.empty();
}

View File

@@ -28,6 +28,7 @@ import org.cloudfoundry.operations.applications.ApplicationHealthCheck;
import org.cloudfoundry.operations.applications.ApplicationManifest;
import org.cloudfoundry.operations.applications.Applications;
import org.cloudfoundry.operations.applications.PushApplicationManifestRequest;
import org.cloudfoundry.operations.services.BindServiceInstanceRequest;
import org.cloudfoundry.operations.services.GetServiceInstanceRequest;
import org.cloudfoundry.operations.services.ServiceInstance;
import org.cloudfoundry.operations.services.ServiceInstanceType;
@@ -392,7 +393,7 @@ class CloudFoundryAppDeployerTest {
}
@Test
void updateServiceInstanceUnbindsWhenRequired() {
void updateServiceInstanceRebindsWhenRequired() {
when(operationsServices.updateInstance(
org.cloudfoundry.operations.services.UpdateServiceInstanceRequest.builder()
.serviceInstanceName("service-instance-name")
@@ -422,6 +423,18 @@ class CloudFoundryAppDeployerTest {
.build()))
.thenReturn(Mono.empty());
when(operationsServices.bind(BindServiceInstanceRequest.builder()
.applicationName("app1")
.serviceInstanceName("service-instance-name")
.build()))
.thenReturn(Mono.empty());
when(operationsServices.bind(BindServiceInstanceRequest.builder()
.applicationName("app2")
.serviceInstanceName("service-instance-name")
.build()))
.thenReturn(Mono.empty());
UpdateServiceInstanceRequest request =
UpdateServiceInstanceRequest.builder()
.serviceInstanceName("service-instance-name")