diff --git a/spring-cloud-app-broker-acceptance-tests/src/test/java/org.springframework.cloud.appbroker.acceptance/UpdateInstanceAcceptanceTest.java b/spring-cloud-app-broker-acceptance-tests/src/test/java/org.springframework.cloud.appbroker.acceptance/UpdateInstanceAcceptanceTest.java index 9c82223..e922dea 100644 --- a/spring-cloud-app-broker-acceptance-tests/src/test/java/org.springframework.cloud.appbroker.acceptance/UpdateInstanceAcceptanceTest.java +++ b/spring-cloud-app-broker-acceptance-tests/src/test/java/org.springframework.cloud.appbroker.acceptance/UpdateInstanceAcceptanceTest.java @@ -48,7 +48,9 @@ class UpdateInstanceAcceptanceTest extends CloudFoundryAcceptanceTest { "spring.cloud.appbroker.services[0].apps[0].environment.parameter3=config3", "spring.cloud.appbroker.services[0].apps[0].environment.parameter4=config4", "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[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=count" }) void deployAppsOnUpdateService() { // given a service instance is created @@ -72,6 +74,7 @@ class UpdateInstanceAcceptanceTest extends CloudFoundryAcceptanceTest { parameters.put("parameter1", "value1"); parameters.put("parameter2", "value2"); parameters.put("parameter3", "value3"); + parameters.put("count", 2); updateServiceInstance(SI_NAME, parameters); // then the backing application was updated with zero downtime @@ -86,6 +89,10 @@ class UpdateInstanceAcceptanceTest extends CloudFoundryAcceptanceTest { assertThat(json.read("$.parameter3").toString()).isEqualTo("value3"); assertThat(json.read("$.parameter4").toString()).isEqualTo("config4"); + backingApplication = getApplicationSummary(APP_NAME); + assertThat(backingApplication).hasValueSatisfying(app -> + assertThat(app.getRunningInstances()).isEqualTo(2)); + // when the service instance is deleted deleteServiceInstance(SI_NAME); diff --git a/spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployer.java b/spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployer.java index faa127c..0300251 100644 --- a/spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployer.java +++ b/spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployer.java @@ -193,7 +193,7 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware .doOnError(e -> logger.warn(String.format("Error getting application %s: %s", name, e.getMessage()))) .map(ApplicationDetail::getId) .flatMap(applicationId -> - updateApplicationEnvironment(applicationId, environmentVariables).thenReturn(applicationId) + updateApplicationEnvironment(applicationId, environmentVariables, request.getProperties()).thenReturn(applicationId) ) .flatMap(applicationId -> Mono.zip(Mono.just(applicationId), createPackageForApplication(applicationId))) @@ -342,12 +342,15 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware } private Mono updateApplicationEnvironment( - String applicationId, Map environmentVariables) { + String applicationId, Map environmentVariables, Map properties) { return this.client .applicationsV2() .update(org.cloudfoundry.client.v2.applications.UpdateApplicationRequest .builder() .applicationId(applicationId) + .instances(instances(properties)) + .diskQuota(diskQuota(properties)) + .memory(memory(properties)) .putAllEnvironmentJsons(environmentVariables) .build()) .doOnRequest(l -> logger.debug("Updating environment for application {}", applicationId)) diff --git a/spring-cloud-app-broker-deployer-cloudfoundry/src/test/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployerUpdateApplicationTest.java b/spring-cloud-app-broker-deployer-cloudfoundry/src/test/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployerUpdateApplicationTest.java index da4ca82..cce1f6e 100644 --- a/spring-cloud-app-broker-deployer-cloudfoundry/src/test/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployerUpdateApplicationTest.java +++ b/spring-cloud-app-broker-deployer-cloudfoundry/src/test/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployerUpdateApplicationTest.java @@ -16,6 +16,9 @@ package org.springframework.cloud.appbroker.deployer.cloudfoundry; +import java.util.HashMap; +import java.util.Map; + import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.ApplicationsV2; import org.cloudfoundry.client.v2.applications.UpdateApplicationResponse; @@ -46,6 +49,7 @@ import org.cloudfoundry.operations.applications.Applications; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; @@ -118,14 +122,10 @@ class CloudFoundryAppDeployerUpdateApplicationTest { appDeployer = new CloudFoundryAppDeployer(deploymentProperties, cloudFoundryOperations, cloudFoundryClient, operationsUtils, targetProperties, resourceLoader); - } - @Test - void updateApp() { when(operationsApplications.get(any())) .thenReturn(Mono.just(createApplicationDetail())); - when(applicationsV2.update(any())) - .thenReturn(Mono.just(UpdateApplicationResponse.builder().build())); + when(packages.create(any())) .thenReturn(Mono.just(CreatePackageResponse .builder() @@ -193,6 +193,13 @@ class CloudFoundryAppDeployerUpdateApplicationTest { .createdAt("DATETIME") .id("deployment-id") .build())); + } + + + @Test + void updateApp() { + when(applicationsV2.update(any())) + .thenReturn(Mono.just(UpdateApplicationResponse.builder().build())); UpdateApplicationRequest request = UpdateApplicationRequest @@ -206,6 +213,37 @@ class CloudFoundryAppDeployerUpdateApplicationTest { .verifyComplete(); } + @Test + void updateAppProperties() { + ArgumentCaptor updateApplicationRequestCaptor = + ArgumentCaptor.forClass(org.cloudfoundry.client.v2.applications.UpdateApplicationRequest.class); + + when(applicationsV2.update(updateApplicationRequestCaptor.capture())) + .thenReturn(Mono.just(UpdateApplicationResponse.builder().build())); + + Map properties = new HashMap<>(); + properties.put("count", "2"); + properties.put("disk", "2G"); + properties.put("memory", "1G"); + + UpdateApplicationRequest request = + UpdateApplicationRequest + .builder() + .name(APP_NAME) + .path(APP_PATH) + .properties(properties) + .build(); + + StepVerifier.create(appDeployer.update(request)) + .assertNext(response -> assertThat(response.getName()).isEqualTo(APP_NAME)) + .verifyComplete(); + + org.cloudfoundry.client.v2.applications.UpdateApplicationRequest updateApplicationRequest = updateApplicationRequestCaptor.getValue(); + assertThat(updateApplicationRequest.getInstances()).isEqualTo(2); + assertThat(updateApplicationRequest.getDiskQuota()).isEqualTo(2048); + assertThat(updateApplicationRequest.getMemory()).isEqualTo(1024); + } + private ApplicationDetail createApplicationDetail() { return ApplicationDetail .builder()