From 43950e446ccae8a6fb2577bc1475141c52ccb893 Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Mon, 8 Oct 2018 14:12:28 -0500 Subject: [PATCH] Allow CF deployment properties defaults to be provided via configuration. --- .../AppBrokerAutoConfiguration.java | 2 +- .../AppDeployerAutoConfiguration.java | 45 ------- ...udFoundryAppDeployerAutoConfiguration.java | 126 ++++++++++++++++++ .../CloudFoundryClientAutoConfiguration.java | 98 -------------- .../main/resources/META-INF/spring.factories | 3 +- .../AppBrokerAutoConfigurationTest.java | 5 +- ...ndryAppDeployerAutoConfigurationTest.java} | 37 +++-- .../targets/SpacePerServiceInstance.java | 6 +- .../cloudfoundry/CloudFoundryAppDeployer.java | 23 ++-- .../CloudFoundryDeploymentProperties.java | 107 +-------------- .../CloudFoundryTargetProperties.java | 9 +- .../CloudFoundryAppDeployerTest.java | 12 +- .../deployer/DeploymentProperties.java | 87 +++++++----- ...teInstanceWithPropertiesComponentTest.java | 8 +- 14 files changed, 245 insertions(+), 323 deletions(-) delete mode 100644 spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppDeployerAutoConfiguration.java create mode 100644 spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryAppDeployerAutoConfiguration.java delete mode 100644 spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryClientAutoConfiguration.java rename spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/{CloudFoundryClientAutoConfigurationTest.java => CloudFoundryAppDeployerAutoConfigurationTest.java} (61%) rename spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryProperties.java => spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryTargetProperties.java (87%) diff --git a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfiguration.java b/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfiguration.java index 3a893b1..a5bbb95 100644 --- a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfiguration.java +++ b/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfiguration.java @@ -51,7 +51,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration -@AutoConfigureAfter(AppDeployerAutoConfiguration.class) +@AutoConfigureAfter(CloudFoundryAppDeployerAutoConfiguration.class) @ConditionalOnBean(AppDeployer.class) public class AppBrokerAutoConfiguration { diff --git a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppDeployerAutoConfiguration.java b/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppDeployerAutoConfiguration.java deleted file mode 100644 index c5a5c51..0000000 --- a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/AppDeployerAutoConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.cloudfoundry.operations.CloudFoundryOperations; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.cloud.appbroker.deployer.AppDeployer; -import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryAppDeployer; -import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryDeploymentProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.ResourceLoader; - -@Configuration -@AutoConfigureAfter(CloudFoundryClientAutoConfiguration.class) -public class AppDeployerAutoConfiguration { - - @Bean - @ConditionalOnBean(CloudFoundryOperations.class) - public AppDeployer cloudFoundryAppDeployer(CloudFoundryOperations cloudFoundryOperations, - CloudFoundryProperties cloudFoundryProperties, - ResourceLoader resourceLoader) { - CloudFoundryDeploymentProperties cloudFoundryDeploymentProperties = new CloudFoundryDeploymentProperties(); - - cloudFoundryDeploymentProperties.setDefaultOrg(cloudFoundryProperties.getDefaultOrg()); - cloudFoundryDeploymentProperties.setUsername(cloudFoundryProperties.getUsername()); - return new CloudFoundryAppDeployer(cloudFoundryDeploymentProperties, cloudFoundryOperations, resourceLoader); - } -} diff --git a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryAppDeployerAutoConfiguration.java b/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryAppDeployerAutoConfiguration.java new file mode 100644 index 0000000..61c4071 --- /dev/null +++ b/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryAppDeployerAutoConfiguration.java @@ -0,0 +1,126 @@ +/* + * 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.cloudfoundry.client.CloudFoundryClient; +import org.cloudfoundry.doppler.DopplerClient; +import org.cloudfoundry.operations.CloudFoundryOperations; + +import org.cloudfoundry.operations.DefaultCloudFoundryOperations; +import org.cloudfoundry.reactor.ConnectionContext; +import org.cloudfoundry.reactor.DefaultConnectionContext; +import org.cloudfoundry.reactor.TokenProvider; +import org.cloudfoundry.reactor.client.ReactorCloudFoundryClient; +import org.cloudfoundry.reactor.doppler.ReactorDopplerClient; +import org.cloudfoundry.reactor.tokenprovider.PasswordGrantTokenProvider; +import org.cloudfoundry.reactor.uaa.ReactorUaaClient; +import org.cloudfoundry.uaa.UaaClient; +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.CloudFoundryAppDeployer; +import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryDeploymentProperties; +import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryTargetProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ResourceLoader; + +import java.util.Optional; + +@Configuration +@ConditionalOnProperty(CloudFoundryAppDeployerAutoConfiguration.PROPERTY_PREFIX + ".api-host") +@EnableConfigurationProperties +public class CloudFoundryAppDeployerAutoConfiguration { + static final String PROPERTY_PREFIX = "spring.cloud.appbroker.deployer.cloudfoundry"; + + @Bean + @ConfigurationProperties(PROPERTY_PREFIX + ".properties") + public CloudFoundryDeploymentProperties cloudFoundryDeploymentProperties() { + return new CloudFoundryDeploymentProperties(); + } + + @Bean + @ConfigurationProperties(PROPERTY_PREFIX) + CloudFoundryTargetProperties cloudFoundryTargetProperties() { + return new CloudFoundryTargetProperties(); + } + + @Bean + public AppDeployer cloudFoundryAppDeployer(CloudFoundryOperations cloudFoundryOperations, + CloudFoundryTargetProperties targetProperties, + CloudFoundryDeploymentProperties deploymentProperties, + ResourceLoader resourceLoader) { + return new CloudFoundryAppDeployer(targetProperties, deploymentProperties, cloudFoundryOperations, resourceLoader); + } + + @Bean + ReactorCloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext, TokenProvider tokenProvider) { + return ReactorCloudFoundryClient.builder() + .connectionContext(connectionContext) + .tokenProvider(tokenProvider) + .build(); + } + + @Bean + CloudFoundryOperations cloudFoundryOperations(CloudFoundryTargetProperties properties, CloudFoundryClient client, + DopplerClient dopplerClient, UaaClient uaaClient) { + return DefaultCloudFoundryOperations.builder() + .cloudFoundryClient(client) + .dopplerClient(dopplerClient) + .uaaClient(uaaClient) + .organization(properties.getDefaultOrg()) + .space(properties.getDefaultSpace()) + .build(); + } + + @Bean + DefaultConnectionContext connectionContext(CloudFoundryTargetProperties properties) { + return DefaultConnectionContext.builder() + .apiHost(properties.getApiHost()) + .port(Optional.ofNullable(properties.getApiPort())) + .skipSslValidation(properties.isSkipSslValidation()) + .secure(properties.isSecure()) + .build(); + } + + @Bean + ReactorDopplerClient dopplerClient(ConnectionContext connectionContext, TokenProvider tokenProvider) { + return ReactorDopplerClient.builder() + .connectionContext(connectionContext) + .tokenProvider(tokenProvider) + .build(); + } + + @Bean + @ConditionalOnProperty({CloudFoundryAppDeployerAutoConfiguration.PROPERTY_PREFIX + ".username", + CloudFoundryAppDeployerAutoConfiguration.PROPERTY_PREFIX + ".password"}) + PasswordGrantTokenProvider tokenProvider(CloudFoundryTargetProperties properties) { + return PasswordGrantTokenProvider.builder() + .password(properties.getPassword()) + .username(properties.getUsername()) + .build(); + } + + @Bean + ReactorUaaClient uaaClient(ConnectionContext connectionContext, TokenProvider tokenProvider) { + return ReactorUaaClient.builder() + .connectionContext(connectionContext) + .tokenProvider(tokenProvider) + .build(); + } +} diff --git a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryClientAutoConfiguration.java b/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryClientAutoConfiguration.java deleted file mode 100644 index e2aef3a..0000000 --- a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryClientAutoConfiguration.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 java.util.Optional; -import org.cloudfoundry.client.CloudFoundryClient; -import org.cloudfoundry.doppler.DopplerClient; -import org.cloudfoundry.operations.CloudFoundryOperations; -import org.cloudfoundry.operations.DefaultCloudFoundryOperations; -import org.cloudfoundry.reactor.ConnectionContext; -import org.cloudfoundry.reactor.DefaultConnectionContext; -import org.cloudfoundry.reactor.TokenProvider; -import org.cloudfoundry.reactor.client.ReactorCloudFoundryClient; -import org.cloudfoundry.reactor.doppler.ReactorDopplerClient; -import org.cloudfoundry.reactor.tokenprovider.PasswordGrantTokenProvider; -import org.cloudfoundry.reactor.uaa.ReactorUaaClient; -import org.cloudfoundry.uaa.UaaClient; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ConditionalOnProperty(CloudFoundryProperties.PROPERTY_PREFIX + ".api-host") -@EnableConfigurationProperties(CloudFoundryProperties.class) -public class CloudFoundryClientAutoConfiguration { - - @Bean - ReactorCloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext, TokenProvider tokenProvider) { - return ReactorCloudFoundryClient.builder() - .connectionContext(connectionContext) - .tokenProvider(tokenProvider) - .build(); - } - - @Bean - CloudFoundryOperations cloudFoundryOperations(CloudFoundryProperties properties, CloudFoundryClient client, - DopplerClient dopplerClient, UaaClient uaaClient) { - return DefaultCloudFoundryOperations.builder() - .cloudFoundryClient(client) - .dopplerClient(dopplerClient) - .uaaClient(uaaClient) - .organization(properties.getDefaultOrg()) - .space(properties.getDefaultSpace()) - .build(); - } - - @Bean - DefaultConnectionContext connectionContext(CloudFoundryProperties properties) { - return DefaultConnectionContext.builder() - .apiHost(properties.getApiHost()) - .port(Optional.ofNullable(properties.getApiPort())) - .skipSslValidation(properties.isSkipSslValidation()) - .secure(properties.isSecure()) - .build(); - } - - @Bean - ReactorDopplerClient dopplerClient(ConnectionContext connectionContext, TokenProvider tokenProvider) { - return ReactorDopplerClient.builder() - .connectionContext(connectionContext) - .tokenProvider(tokenProvider) - .build(); - } - - @Bean - @ConditionalOnProperty({CloudFoundryProperties.PROPERTY_PREFIX + ".username", - CloudFoundryProperties.PROPERTY_PREFIX + ".password"}) - PasswordGrantTokenProvider tokenProvider(CloudFoundryProperties properties) { - return PasswordGrantTokenProvider.builder() - .password(properties.getPassword()) - .username(properties.getUsername()) - .build(); - } - - @Bean - ReactorUaaClient uaaClient(ConnectionContext connectionContext, TokenProvider tokenProvider) { - return ReactorUaaClient.builder() - .connectionContext(connectionContext) - .tokenProvider(tokenProvider) - .build(); - } - -} diff --git a/spring-cloud-app-broker-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-cloud-app-broker-autoconfigure/src/main/resources/META-INF/spring.factories index cef5be4..4fe3741 100644 --- a/spring-cloud-app-broker-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-app-broker-autoconfigure/src/main/resources/META-INF/spring.factories @@ -1,4 +1,3 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.appbroker.autoconfigure.CloudFoundryClientAutoConfiguration,\ -org.springframework.cloud.appbroker.autoconfigure.AppDeployerAutoConfiguration,\ +org.springframework.cloud.appbroker.autoconfigure.CloudFoundryAppDeployerAutoConfiguration,\ org.springframework.cloud.appbroker.autoconfigure.AppBrokerAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfigurationTest.java b/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfigurationTest.java index 5814e6b..aab9fa3 100644 --- a/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfigurationTest.java +++ b/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/AppBrokerAutoConfigurationTest.java @@ -40,10 +40,9 @@ class AppBrokerAutoConfigurationTest { .withConfiguration(AutoConfigurations.of(AppBrokerAutoConfiguration.class)); @Test - void servicesAreCreatedWithAppDeployerConfigured() { + void servicesAreCreatedWithCloudFoundryConfigured() { this.contextRunner - .withConfiguration(AutoConfigurations.of(AppDeployerAutoConfiguration.class, - CloudFoundryClientAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(CloudFoundryAppDeployerAutoConfiguration.class)) .withPropertyValues( "spring.cloud.appbroker.services[0].service-name=service1", "spring.cloud.appbroker.services[0].plan-name=service1-plan1", diff --git a/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryClientAutoConfigurationTest.java b/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryAppDeployerAutoConfigurationTest.java similarity index 61% rename from spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryClientAutoConfigurationTest.java rename to spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryAppDeployerAutoConfigurationTest.java index 61af4ba..20b70dd 100644 --- a/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryClientAutoConfigurationTest.java +++ b/spring-cloud-app-broker-autoconfigure/src/test/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryAppDeployerAutoConfigurationTest.java @@ -28,13 +28,16 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.cloud.appbroker.deployer.AppDeployer; +import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryDeploymentProperties; +import org.springframework.cloud.appbroker.deployer.cloudfoundry.CloudFoundryTargetProperties; import static org.assertj.core.api.Assertions.assertThat; -class CloudFoundryClientAutoConfigurationTest { +class CloudFoundryAppDeployerAutoConfigurationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(CloudFoundryClientAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(CloudFoundryAppDeployerAutoConfiguration.class)); @Test void clientIsCreatedWithPasswordGrantConfiguration() { @@ -45,15 +48,28 @@ class CloudFoundryClientAutoConfigurationTest { "spring.cloud.appbroker.deployer.cloudfoundry.default-org=example-org", "spring.cloud.appbroker.deployer.cloudfoundry.default-space=example-space", "spring.cloud.appbroker.deployer.cloudfoundry.username=user", - "spring.cloud.appbroker.deployer.cloudfoundry.password=secret" + "spring.cloud.appbroker.deployer.cloudfoundry.password=secret", + "spring.cloud.appbroker.deployer.cloudfoundry.properties.memory=2G", + "spring.cloud.appbroker.deployer.cloudfoundry.properties.count=3", + "spring.cloud.appbroker.deployer.cloudfoundry.properties.buildpack=example-buildpack", + "spring.cloud.appbroker.deployer.cloudfoundry.properties.domain=example.com" ) .run((context) -> { - assertThat(context).hasSingleBean(CloudFoundryProperties.class); - CloudFoundryProperties cloudFoundryProperties = context.getBean(CloudFoundryProperties.class); - assertThat(cloudFoundryProperties.getApiHost()).isEqualTo("api.example.com"); - assertThat(cloudFoundryProperties.getApiPort()).isEqualTo(443); - assertThat(cloudFoundryProperties.getDefaultOrg()).isEqualTo("example-org"); - assertThat(cloudFoundryProperties.getDefaultSpace()).isEqualTo("example-space"); + assertThat(context).hasSingleBean(CloudFoundryTargetProperties.class); + CloudFoundryTargetProperties targetProperties = context.getBean(CloudFoundryTargetProperties.class); + assertThat(targetProperties.getApiHost()).isEqualTo("api.example.com"); + assertThat(targetProperties.getApiPort()).isEqualTo(443); + assertThat(targetProperties.getDefaultOrg()).isEqualTo("example-org"); + assertThat(targetProperties.getDefaultSpace()).isEqualTo("example-space"); + + assertThat(context).hasSingleBean(CloudFoundryDeploymentProperties.class); + CloudFoundryDeploymentProperties deploymentProperties = context.getBean(CloudFoundryDeploymentProperties.class); + assertThat(deploymentProperties.getMemory()).isEqualTo("2G"); + assertThat(deploymentProperties.getCount()).isEqualTo(3); + assertThat(deploymentProperties.getBuildpack()).isEqualTo("example-buildpack"); + assertThat(deploymentProperties.getDomain()).isEqualTo("example.com"); + + assertThat(context).hasSingleBean(AppDeployer.class); assertThat(context).hasSingleBean(ReactorCloudFoundryClient.class); assertThat(context).hasSingleBean(ReactorDopplerClient.class); @@ -68,7 +84,8 @@ class CloudFoundryClientAutoConfigurationTest { void clientIsNotCreatedWithoutConfiguration() { this.contextRunner .run((context) -> { - assertThat(context).doesNotHaveBean(CloudFoundryProperties.class); + assertThat(context).doesNotHaveBean(CloudFoundryTargetProperties.class); + assertThat(context).doesNotHaveBean(CloudFoundryDeploymentProperties.class); assertThat(context).doesNotHaveBean(ReactorCloudFoundryClient.class); assertThat(context).doesNotHaveBean(ReactorDopplerClient.class); assertThat(context).doesNotHaveBean(ReactorUaaClient.class); diff --git a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/targets/SpacePerServiceInstance.java b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/targets/SpacePerServiceInstance.java index db11087..6e1a85d 100644 --- a/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/targets/SpacePerServiceInstance.java +++ b/spring-cloud-app-broker-core/src/main/java/org/springframework/cloud/appbroker/extensions/targets/SpacePerServiceInstance.java @@ -33,8 +33,10 @@ public class SpacePerServiceInstance extends TargetFactory apply(BackingApplication backingApplication, String serviceInstanceId) { - backingApplication.getProperties().put(DeploymentProperties.HOST_KEY, backingApplication.getName() + "-" + serviceInstanceId); - backingApplication.getProperties().put(DeploymentProperties.TARGET_KEY, serviceInstanceId); + backingApplication.addProperty(DeploymentProperties.HOST_PROPERTY_KEY, + backingApplication.getName() + "-" + serviceInstanceId); + backingApplication.addProperty(DeploymentProperties.TARGET_PROPERTY_KEY, + serviceInstanceId); return Mono.just(backingApplication); } 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 6f7e1bd..f72643e 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 @@ -74,15 +74,18 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private final CloudFoundryTargetProperties targetProperties; private final CloudFoundryDeploymentProperties defaultDeploymentProperties; private final CloudFoundryOperations operations; private ResourceLoader resourceLoader; - public CloudFoundryAppDeployer(CloudFoundryDeploymentProperties deploymentProperties, + public CloudFoundryAppDeployer(CloudFoundryTargetProperties targetProperties, + CloudFoundryDeploymentProperties deploymentProperties, CloudFoundryOperations operations, ResourceLoader resourceLoader) { + this.targetProperties = targetProperties; this.defaultDeploymentProperties = deploymentProperties; this.operations = operations; this.resourceLoader = resourceLoader; @@ -133,8 +136,8 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware .build(); Mono requestPushApplication = requestPushApplication(applicationManifestRequest); - if (deploymentProperties.containsKey(DeploymentProperties.TARGET_KEY)) { - String space = deploymentProperties.get(DeploymentProperties.TARGET_KEY); + if (deploymentProperties.containsKey(DeploymentProperties.TARGET_PROPERTY_KEY)) { + String space = deploymentProperties.get(DeploymentProperties.TARGET_PROPERTY_KEY); requestPushApplication = requestPushApplicationInSpace(applicationManifestRequest, space); } @@ -202,7 +205,7 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware private Mono getOrganizationIdPublisher() { OrganizationInfoRequest organizationInfoRequest = - OrganizationInfoRequest.builder().name(this.defaultDeploymentProperties.getDefaultOrg()).build(); + OrganizationInfoRequest.builder().name(this.targetProperties.getDefaultOrg()).build(); return this.operations.organizations().get(organizationInfoRequest).map(OrganizationDetail::getId); } @@ -214,8 +217,8 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware Map deploymentProperties = request.getProperties(); Mono requestDeleteApplication; - if (deploymentProperties.containsKey(DeploymentProperties.TARGET_KEY)) { - String space = deploymentProperties.get(DeploymentProperties.TARGET_KEY); + if (deploymentProperties.containsKey(DeploymentProperties.TARGET_PROPERTY_KEY)) { + String space = deploymentProperties.get(DeploymentProperties.TARGET_PROPERTY_KEY); requestDeleteApplication = requestDeleteApplicationInSpace(appName, space) .then(createSpaceOperations().delete(DeleteSpaceRequest.builder().name(space).build())); } else { @@ -259,7 +262,7 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware return new DefaultSpaces( ((DefaultCloudFoundryOperations) this.operations).getCloudFoundryClientPublisher() , getOrganizationIdPublisher(), - Mono.just(this.defaultDeploymentProperties.getUsername())); + Mono.just(this.targetProperties.getUsername())); } private Map getEnvironmentVariables(Map environment) { @@ -309,7 +312,7 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware } private boolean useSpringApplicationJson(Map environment) { - return Optional.ofNullable(environment.get(CloudFoundryDeploymentProperties.USE_SPRING_APPLICATION_JSON_KEY)) + return Optional.ofNullable(environment.get(DeploymentProperties.USE_SPRING_APPLICATION_JSON_KEY)) .map(Boolean::valueOf) .orElse(this.defaultDeploymentProperties.isUseSpringApplicationJson()); } @@ -348,11 +351,11 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware private Integer instances(Map properties) { return Optional.ofNullable(properties.get(DeploymentProperties.COUNT_PROPERTY_KEY)) .map(Integer::parseInt) - .orElse(this.defaultDeploymentProperties.getInstances()); + .orElse(this.defaultDeploymentProperties.getCount()); } private String host(Map properties) { - return Optional.ofNullable(properties.get(CloudFoundryDeploymentProperties.HOST_PROPERTY)) + return Optional.ofNullable(properties.get(DeploymentProperties.HOST_PROPERTY_KEY)) .orElse(this.defaultDeploymentProperties.getHost()); } diff --git a/spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryDeploymentProperties.java b/spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryDeploymentProperties.java index 770ee92..da3d5fb 100644 --- a/spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryDeploymentProperties.java +++ b/spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryDeploymentProperties.java @@ -17,7 +17,7 @@ package org.springframework.cloud.appbroker.deployer.cloudfoundry; import org.cloudfoundry.operations.applications.ApplicationHealthCheck; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.appbroker.deployer.DeploymentProperties; import java.time.Duration; import java.util.HashSet; @@ -32,7 +32,7 @@ import java.util.Set; * @author Ilayaperumal Gopinathan */ @SuppressWarnings({"unused", "PMD.TooManyFields"}) -public class CloudFoundryDeploymentProperties { +public class CloudFoundryDeploymentProperties extends DeploymentProperties { static final String HEALTHCHECK_PROPERTY_KEY = "health-check"; static final String HEALTHCHECK_HTTP_ENDPOINT_PROPERTY_KEY = "health-check-http-endpoint"; @@ -47,21 +47,12 @@ public class CloudFoundryDeploymentProperties { static final String NO_ROUTE_PROPERTY = "no-route"; - static final String HOST_PROPERTY = "host"; - static final String DOMAIN_PROPERTY = "domain"; static final String BUILDPACK_PROPERTY_KEY = "buildpack"; static final String JAVA_OPTS_PROPERTY_KEY = "javaOpts"; - static final String USE_SPRING_APPLICATION_JSON_KEY = "use-spring-application-json"; - - /** - * The host name to use as part of the route. Defaults to hostname derived by Cloud Foundry. - */ - private String host; - /** * The domain to use when mapping routes for applications. */ @@ -78,16 +69,6 @@ public class CloudFoundryDeploymentProperties { */ private String buildpack; - /** - * The amount of memory to allocate, if not overridden per-app. Default unit is mebibytes, 'M' and 'G" suffixes supported. - */ - private String memory; - - /** - * The amount of disk space to allocate, if not overridden per-app. Default unit is mebibytes, 'M' and 'G" suffixes supported. - */ - private String disk; - /** * The type of health check to perform on deployed application, if not overridden per-app. Defaults to PORT */ @@ -103,11 +84,6 @@ public class CloudFoundryDeploymentProperties { */ private Integer healthCheckTimeout; - /** - * The number of instances to run. - */ - private Integer instances; - /** * Flag to enable prefixing the app name with a random prefix. */ @@ -123,11 +99,6 @@ public class CloudFoundryDeploymentProperties { */ private long statusTimeout = 5_000L; - /** - * Flag to indicate whether application properties are fed into SPRING_APPLICATION_JSON or ENVIRONMENT VARIABLES. - */ - private boolean useSpringApplicationJson = true; - /** * If set, override the timeout allocated for staging the app by the client. */ @@ -138,12 +109,6 @@ public class CloudFoundryDeploymentProperties { */ private Duration startupTimeout = Duration.ofMinutes(5L); - /** - * String to use as prefix for name of deployed app. Defaults to spring.application.name. - */ - @Value("${spring.application.name:}") - private String appNamePrefix; - /** * Whether to also delete routes when un-deploying an application. */ @@ -151,10 +116,6 @@ public class CloudFoundryDeploymentProperties { private String javaOpts; - private String defaultOrg; - - private String username; - public String getBuildpack() { return buildpack; } @@ -163,30 +124,6 @@ public class CloudFoundryDeploymentProperties { this.buildpack = buildpack; } - public String getMemory() { - return memory; - } - - public void setMemory(String memory) { - this.memory = memory; - } - - public String getDisk() { - return disk; - } - - public void setDisk(String disk) { - this.disk = disk; - } - - public Integer getInstances() { - return instances; - } - - public void setInstances(int instances) { - this.instances = instances; - } - public boolean isEnableRandomAppNamePrefix() { return enableRandomAppNamePrefix; } @@ -195,14 +132,6 @@ public class CloudFoundryDeploymentProperties { this.enableRandomAppNamePrefix = enableRandomAppNamePrefix; } - public String getAppNamePrefix() { - return appNamePrefix; - } - - public void setAppNamePrefix(String appNamePrefix) { - this.appNamePrefix = appNamePrefix; - } - public long getApiTimeout() { return apiTimeout; } @@ -211,14 +140,6 @@ public class CloudFoundryDeploymentProperties { this.apiTimeout = apiTimeout; } - public boolean isUseSpringApplicationJson() { - return useSpringApplicationJson; - } - - public void setUseSpringApplicationJson(boolean useSpringApplicationJson) { - this.useSpringApplicationJson = useSpringApplicationJson; - } - public ApplicationHealthCheck getHealthCheck() { return healthCheck; } @@ -251,14 +172,6 @@ public class CloudFoundryDeploymentProperties { this.domain = domain; } - public String getHost() { - return host; - } - - public void setHost(String host) { - this.host = host; - } - public Set getRoutes() { return routes; } @@ -306,20 +219,4 @@ public class CloudFoundryDeploymentProperties { public void setJavaOpts(String javaOpts) { this.javaOpts = javaOpts; } - - public String getDefaultOrg() { - return defaultOrg; - } - - public void setDefaultOrg(String defaultOrg) { - this.defaultOrg = defaultOrg; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } } diff --git a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryProperties.java b/spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryTargetProperties.java similarity index 87% rename from spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryProperties.java rename to spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryTargetProperties.java index 1ba5a56..39b9c26 100644 --- a/spring-cloud-app-broker-autoconfigure/src/main/java/org/springframework/cloud/appbroker/autoconfigure/CloudFoundryProperties.java +++ b/spring-cloud-app-broker-deployer-cloudfoundry/src/main/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryTargetProperties.java @@ -14,18 +14,13 @@ * limitations under the License. */ -package org.springframework.cloud.appbroker.autoconfigure; +package org.springframework.cloud.appbroker.deployer.cloudfoundry; import java.net.URI; import org.cloudfoundry.reactor.ProxyConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@ConfigurationProperties(CloudFoundryProperties.PROPERTY_PREFIX) -public class CloudFoundryProperties { - - static final String PROPERTY_PREFIX = "spring.cloud.appbroker.deployer.cloudfoundry"; +public class CloudFoundryTargetProperties { private String apiHost; private Integer apiPort; diff --git a/spring-cloud-app-broker-deployer-cloudfoundry/src/test/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployerTest.java b/spring-cloud-app-broker-deployer-cloudfoundry/src/test/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployerTest.java index 4801e34..be08cfe 100644 --- a/spring-cloud-app-broker-deployer-cloudfoundry/src/test/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployerTest.java +++ b/spring-cloud-app-broker-deployer-cloudfoundry/src/test/java/org/springframework/cloud/appbroker/deployer/cloudfoundry/CloudFoundryAppDeployerTest.java @@ -61,7 +61,7 @@ class CloudFoundryAppDeployerTest { @Mock private ResourceLoader resourceLoader; - + private CloudFoundryDeploymentProperties deploymentProperties; @BeforeEach @@ -76,7 +76,7 @@ class CloudFoundryAppDeployerTest { .thenReturn(new FileSystemResource(APP_PATH)); appDeployer = new CloudFoundryAppDeployer( - deploymentProperties, cloudFoundryOperations, resourceLoader); + new CloudFoundryTargetProperties(), deploymentProperties, cloudFoundryOperations, resourceLoader); } @Test @@ -110,7 +110,7 @@ class CloudFoundryAppDeployerTest { .property(CloudFoundryDeploymentProperties.HEALTHCHECK_HTTP_ENDPOINT_PROPERTY_KEY, "/healthcheck") .property(CloudFoundryDeploymentProperties.BUILDPACK_PROPERTY_KEY, "buildpack") .property(CloudFoundryDeploymentProperties.DOMAIN_PROPERTY, "domain") - .property(CloudFoundryDeploymentProperties.HOST_PROPERTY, "host") + .property(DeploymentProperties.HOST_PROPERTY_KEY, "host") .property(CloudFoundryDeploymentProperties.NO_ROUTE_PROPERTY, "true") .build(); @@ -137,7 +137,7 @@ class CloudFoundryAppDeployerTest { @Test void deployAppWithDefaultProperties() { - deploymentProperties.setInstances(3); + deploymentProperties.setCount(3); deploymentProperties.setMemory("2G"); deploymentProperties.setDisk("3G"); deploymentProperties.setBuildpack("buildpack"); @@ -173,7 +173,7 @@ class CloudFoundryAppDeployerTest { @Test void deployAppWithRequestOverridingDefaultProperties() { - deploymentProperties.setInstances(3); + deploymentProperties.setCount(3); deploymentProperties.setMemory("2G"); deploymentProperties.setDisk("3G"); deploymentProperties.setBuildpack("buildpack1"); @@ -192,7 +192,7 @@ class CloudFoundryAppDeployerTest { .property(CloudFoundryDeploymentProperties.HEALTHCHECK_HTTP_ENDPOINT_PROPERTY_KEY, "/healthcheck2") .property(CloudFoundryDeploymentProperties.BUILDPACK_PROPERTY_KEY, "buildpack2") .property(CloudFoundryDeploymentProperties.DOMAIN_PROPERTY, "domain2") - .property(CloudFoundryDeploymentProperties.HOST_PROPERTY, "host2") + .property(DeploymentProperties.HOST_PROPERTY_KEY, "host2") .property(CloudFoundryDeploymentProperties.NO_ROUTE_PROPERTY, "true") .build(); diff --git a/spring-cloud-app-broker-deployer/src/main/java/org/springframework/cloud/appbroker/deployer/DeploymentProperties.java b/spring-cloud-app-broker-deployer/src/main/java/org/springframework/cloud/appbroker/deployer/DeploymentProperties.java index 61e7525..d157867 100644 --- a/spring-cloud-app-broker-deployer/src/main/java/org/springframework/cloud/appbroker/deployer/DeploymentProperties.java +++ b/spring-cloud-app-broker-deployer/src/main/java/org/springframework/cloud/appbroker/deployer/DeploymentProperties.java @@ -16,8 +16,6 @@ package org.springframework.cloud.appbroker.deployer; -import org.springframework.cloud.appbroker.deployer.util.ByteSizeUtils; - public class DeploymentProperties { /** * The deployment property for the count (number of app instances). @@ -31,23 +29,6 @@ public class DeploymentProperties { */ public static final String GROUP_PROPERTY_KEY = "group"; - /** - * The deployment property that indicates if each app instance should have an index value - * within a sequence from 0 to N-1, where N is the value of the {@value #COUNT_PROPERTY_KEY} - * property. If not provided, a deployer should assume app instance indexing is not necessary. - */ - public static final String INDEXED_PROPERTY_KEY = "indexed"; - - /** - * The property to be set at each instance level to specify the sequence number - * amongst 0 to N-1, where N is the value of the {@value #COUNT_PROPERTY_KEY} property. - * Specified as CAPITAL_WITH_UNDERSCORES as this is typically passed as an environment - * variable, but when targeting a Spring app, other variations may apply. - * - * @see #INDEXED_PROPERTY_KEY - */ - public static final String INSTANCE_INDEX_PROPERTY_KEY = "INSTANCE_INDEX"; - /** * The deployment property for the memory setting for the container that will run the app. * The memory is specified in Mebibytes, @@ -57,8 +38,6 @@ public class DeploymentProperties { * 1 MiB = 2^20 bytes = 1024*1024 bytes vs. the decimal based 1MB = 10^6 bytes = 1000*1000 bytes, *

* Implementations are expected to translate this value to the target platform as faithfully as possible. - * - * @see ByteSizeUtils */ public static final String MEMORY_PROPERTY_KEY = "memory"; @@ -71,27 +50,69 @@ public class DeploymentProperties { * 1 MiB = 2^20 bytes = 1024*1024 bytes vs. the decimal based 1MB = 10^6 bytes = 1000*1000 bytes, *

* Implementations are expected to translate this value to the target platform as faithfully as possible. - * - * @see ByteSizeUtils */ public static final String DISK_PROPERTY_KEY = "disk"; - /** - * The deployment property for the cpu setting for the container that will run the app. - * The cpu is specified as whole multiples or decimal fractions of virtual cores. Some platforms will not - * support setting cpu and will ignore this setting. Other platforms may require whole numbers and might - * round up. Exactly how this property affects the deployments will vary between implementations. - */ - public static final String CPU_PROPERTY_KEY = "cpu"; - /** * The deployment property for the host that will be used in the app. */ - public static final String HOST_KEY = "host"; + public static final String HOST_PROPERTY_KEY = "host"; /** * The deployment property for the location where the app will be deployed. * The location will vary between implementations. */ - public static final String TARGET_KEY = "target"; + public static final String TARGET_PROPERTY_KEY = "target"; + + public static final String USE_SPRING_APPLICATION_JSON_KEY = "use-spring-application-json"; + + private String host; + + private String memory; + + private String disk; + + private Integer count; + + private boolean useSpringApplicationJson = true; + + public String getMemory() { + return memory; + } + + public void setMemory(String memory) { + this.memory = memory; + } + + public String getDisk() { + return disk; + } + + public void setDisk(String disk) { + this.disk = disk; + } + + public Integer getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public boolean isUseSpringApplicationJson() { + return useSpringApplicationJson; + } + + public void setUseSpringApplicationJson(boolean useSpringApplicationJson) { + this.useSpringApplicationJson = useSpringApplicationJson; + } } diff --git a/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithPropertiesComponentTest.java b/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithPropertiesComponentTest.java index 52447e7..32ba2f8 100644 --- a/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithPropertiesComponentTest.java +++ b/spring-cloud-app-broker-sample/src/test/java/org.springframework.cloud.appbroker/sample/CreateInstanceWithPropertiesComponentTest.java @@ -32,6 +32,10 @@ import static org.hamcrest.Matchers.is; import static org.springframework.cloud.appbroker.sample.CreateInstanceWithPropertiesComponentTest.APP_NAME; @TestPropertySource(properties = { + "spring.cloud.appbroker.deployer.cloudfoundry.properties.memory=1G", + "spring.cloud.appbroker.deployer.cloudfoundry.properties.count=1", + "spring.cloud.appbroker.deployer.cloudfoundry.properties.health-check=http", + "spring.cloud.appbroker.deployer.cloudfoundry.properties.health-check-http-endpoint=/myhealth", "spring.cloud.appbroker.services[0].service-name=example", "spring.cloud.appbroker.services[0].plan-name=standard", "spring.cloud.appbroker.services[0].apps[0].path=classpath:demo.jar", @@ -56,7 +60,9 @@ class CreateInstanceWithPropertiesComponentTest extends WiremockComponentTest { cloudControllerFixture.stubPushApp(APP_NAME, matchingJsonPath("$.[?(@.memory == '2048')]"), matchingJsonPath("$.[?(@.instances == '2')]"), - matchingJsonPath("$.[?(@.health_check_timeout == '180')]")); + matchingJsonPath("$.[?(@.health_check_timeout == '180')]"), + matchingJsonPath("$.[?(@.health_check_type == 'http')]"), + matchingJsonPath("$.[?(@.health_check_http_endpoint == '/myhealth')]")); // when a service instance is created given(brokerFixture.serviceInstanceRequest())