Allow CF deployment properties defaults to be provided via configuration.
This commit is contained in:
@@ -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 {
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
@@ -33,8 +33,10 @@ public class SpacePerServiceInstance extends TargetFactory<SpacePerServiceInstan
|
||||
}
|
||||
|
||||
private Mono<BackingApplication> 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);
|
||||
}
|
||||
|
||||
@@ -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<Void> 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<String> 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<String, String> deploymentProperties = request.getProperties();
|
||||
Mono<Void> 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<String, String> getEnvironmentVariables(Map<String, String> environment) {
|
||||
@@ -309,7 +312,7 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware
|
||||
}
|
||||
|
||||
private boolean useSpringApplicationJson(Map<String, String> 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<String, String> 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<String, String> properties) {
|
||||
return Optional.ofNullable(properties.get(CloudFoundryDeploymentProperties.HOST_PROPERTY))
|
||||
return Optional.ofNullable(properties.get(DeploymentProperties.HOST_PROPERTY_KEY))
|
||||
.orElse(this.defaultDeploymentProperties.getHost());
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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 <a href="https://en.wikipedia.org/wiki/Mebibyte">Mebibytes</a>,
|
||||
@@ -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,
|
||||
* <p>
|
||||
* 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,
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user