Simplify environment variables added by extensions. Use property-style names for env var keys.

This commit is contained in:
Scott Frederick
2019-02-01 14:53:33 -06:00
parent 2315ec7324
commit f7646f08a7
14 changed files with 153 additions and 159 deletions

View File

@@ -92,9 +92,9 @@ class CreateInstanceAcceptanceTest extends CloudFoundryAcceptanceTest {
}
private void assertBasicAuthCredentialsProvided(DocumentContext json) {
assertThat(json).jsonPathAsString("$.spring.security.user.name")
assertThat(json).jsonPathAsString("$.['spring.security.user.name']")
.matches("[a-zA-Z]{14}");
assertThat(json).jsonPathAsString("$.spring.security.user.password")
assertThat(json).jsonPathAsString("$.['spring.security.user.password']")
.matches("[a-zA-Z]{14}");
}
}

View File

@@ -16,9 +16,6 @@
package org.springframework.cloud.appbroker.extensions.credentials;
import java.util.Collections;
import java.util.HashMap;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuple2;
@@ -29,11 +26,8 @@ public class SpringSecurityBasicAuthCredentialProviderFactory extends
private static final String CREDENTIAL_DESCRIPTOR = "basic";
static final String SPRING_KEY = "spring";
static final String SPRING_SECURITY_KEY = "security";
static final String SPRING_SECURITY_USER_KEY = "user";
static final String SPRING_SECURITY_USER_NAME_KEY = "name";
static final String SPRING_SECURITY_USER_PASSWORD_KEY = "password";
static final String SPRING_SECURITY_USER_NAME_KEY = "spring.security.user.name";
static final String SPRING_SECURITY_USER_PASSWORD_KEY = "spring.security.user.password";
private final CredentialGenerator credentialGenerator;
@@ -71,14 +65,8 @@ public class SpringSecurityBasicAuthCredentialProviderFactory extends
}
private Mono<Void> addUserToEnvironment(BackingApplication backingApplication, Tuple2<String, String> user) {
return Mono.just(new HashMap<>(2))
.flatMap(userProperties -> {
userProperties.put(SPRING_SECURITY_USER_NAME_KEY, user.getT1());
userProperties.put(SPRING_SECURITY_USER_PASSWORD_KEY, user.getT2());
backingApplication.addEnvironment(SPRING_KEY,
Collections.singletonMap(SPRING_SECURITY_KEY,
Collections.singletonMap(SPRING_SECURITY_USER_KEY, userProperties)));
return Mono.empty();
});
backingApplication.addEnvironment(SPRING_SECURITY_USER_NAME_KEY, user.getT1());
backingApplication.addEnvironment(SPRING_SECURITY_USER_PASSWORD_KEY, user.getT2());
return Mono.empty();
}
}

View File

@@ -16,10 +16,6 @@
package org.springframework.cloud.appbroker.extensions.credentials;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;
@@ -36,13 +32,9 @@ public class SpringSecurityOAuth2CredentialProviderFactory extends
private static final String CREDENTIAL_DESCRIPTOR = "oauth2";
static final String SPRING_KEY = "spring";
static final String SPRING_SECURITY_KEY = "security";
static final String SPRING_SECURITY_OAUTH2_KEY = "oauth2";
static final String SPRING_SECURITY_CLIENT_KEY = "client";
static final String SPRING_SECURITY_REGISTRATION_KEY = "registration";
static final String SPRING_SECURITY_CLIENT_ID_KEY = "client-id";
static final String SPRING_SECURITY_CLIENT_SECRET_KEY = "client-secret";
static final String SPRING_SECURITY_OAUTH2_REGISTRATION_KEY = "spring.security.oauth2.client.registration.";
static final String SPRING_SECURITY_OAUTH2_CLIENT_ID_KEY = ".client-id";
static final String SPRING_SECURITY_OAUTH2_CLIENT_SECRET_KEY = ".client-secret";
private final CredentialGenerator credentialGenerator;
private final OAuth2Client oAuth2Client;
@@ -86,20 +78,12 @@ public class SpringSecurityOAuth2CredentialProviderFactory extends
}
private Mono<Tuple2<String, String>> addClientToEnvironment(Config config,
BackingApplication backingApplication,
Tuple2<String, String> client) {
BackingApplication backingApplication,
Tuple2<String, String> client) {
String registrationKey = SPRING_SECURITY_OAUTH2_REGISTRATION_KEY + config.getRegistration();
Map<String, String> clientProperties = new HashMap<>(2);
clientProperties.put(SPRING_SECURITY_CLIENT_ID_KEY, client.getT1());
clientProperties.put(SPRING_SECURITY_CLIENT_SECRET_KEY, client.getT2());
backingApplication.addEnvironment(SPRING_KEY,
Collections.singletonMap(SPRING_SECURITY_KEY,
Collections.singletonMap(SPRING_SECURITY_OAUTH2_KEY,
Collections.singletonMap(SPRING_SECURITY_CLIENT_KEY,
Collections.singletonMap(SPRING_SECURITY_REGISTRATION_KEY,
Collections.singletonMap(config.getRegistration(), clientProperties))))));
backingApplication.addEnvironment(registrationKey + SPRING_SECURITY_OAUTH2_CLIENT_ID_KEY, client.getT1());
backingApplication.addEnvironment(registrationKey + SPRING_SECURITY_OAUTH2_CLIENT_SECRET_KEY, client.getT2());
return Mono.just(client);
}

View File

@@ -1,35 +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.extensions.credentials;
import java.util.Arrays;
import java.util.Map;
final class MapUtils {
private MapUtils() {
}
@SuppressWarnings("unchecked")
static Map<String, Object> getNestedMap(Map<String, Object> map, String... keys) {
if (keys.length > 0 && map.containsKey(keys[0])) {
Map<String, Object> nested = (Map<String, Object>) map.get(keys[0]);
String[] newKeys = Arrays.copyOfRange(keys, 1, keys.length);
return getNestedMap(nested, newKeys);
}
return map;
}
}

View File

@@ -16,8 +16,6 @@
package org.springframework.cloud.appbroker.extensions.credentials;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -34,9 +32,6 @@ import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityBasicAuthCredentialProviderFactory.SPRING_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityBasicAuthCredentialProviderFactory.SPRING_SECURITY_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityBasicAuthCredentialProviderFactory.SPRING_SECURITY_USER_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityBasicAuthCredentialProviderFactory.SPRING_SECURITY_USER_NAME_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityBasicAuthCredentialProviderFactory.SPRING_SECURITY_USER_PASSWORD_KEY;
@@ -75,11 +70,7 @@ class SpringSecurityBasicAuthCredentialProviderFactoryTest {
.expectNext(backingApplication)
.verifyComplete();
Map<String, Object> environment = backingApplication.getEnvironment();
Map<String, Object> userProperties = MapUtils.getNestedMap(environment,
SPRING_KEY, SPRING_SECURITY_KEY, SPRING_SECURITY_USER_KEY);
assertThat(userProperties)
assertThat(backingApplication.getEnvironment())
.containsEntry(SPRING_SECURITY_USER_NAME_KEY, "username")
.containsEntry(SPRING_SECURITY_USER_PASSWORD_KEY, "password");
}

View File

@@ -38,13 +38,9 @@ import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityOAuth2CredentialProviderFactory.SPRING_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityOAuth2CredentialProviderFactory.SPRING_SECURITY_CLIENT_ID_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityOAuth2CredentialProviderFactory.SPRING_SECURITY_CLIENT_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityOAuth2CredentialProviderFactory.SPRING_SECURITY_CLIENT_SECRET_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityOAuth2CredentialProviderFactory.SPRING_SECURITY_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityOAuth2CredentialProviderFactory.SPRING_SECURITY_OAUTH2_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityOAuth2CredentialProviderFactory.SPRING_SECURITY_REGISTRATION_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityOAuth2CredentialProviderFactory.SPRING_SECURITY_OAUTH2_CLIENT_ID_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityOAuth2CredentialProviderFactory.SPRING_SECURITY_OAUTH2_CLIENT_SECRET_KEY;
import static org.springframework.cloud.appbroker.extensions.credentials.SpringSecurityOAuth2CredentialProviderFactory.SPRING_SECURITY_OAUTH2_REGISTRATION_KEY;
@ExtendWith(MockitoExtension.class)
class SpringSecurityOAuth2CredentialProviderFactoryTest {
@@ -113,13 +109,11 @@ class SpringSecurityOAuth2CredentialProviderFactoryTest {
private void assertEnvironmentContainsProperties(BackingApplication backingApplication, String id) {
Map<String, Object> environment = backingApplication.getEnvironment();
Map<String, Object> clientProperties = MapUtils.getNestedMap(environment,
SPRING_KEY, SPRING_SECURITY_KEY, SPRING_SECURITY_OAUTH2_KEY, SPRING_SECURITY_CLIENT_KEY,
SPRING_SECURITY_REGISTRATION_KEY, CLIENT_REGISTRATION);
assertThat(clientProperties)
.containsEntry(SPRING_SECURITY_CLIENT_ID_KEY, id)
.containsEntry(SPRING_SECURITY_CLIENT_SECRET_KEY, "test-secret");
assertThat(environment)
.containsEntry(SPRING_SECURITY_OAUTH2_REGISTRATION_KEY + CLIENT_REGISTRATION +
SPRING_SECURITY_OAUTH2_CLIENT_ID_KEY, id)
.containsEntry(SPRING_SECURITY_OAUTH2_REGISTRATION_KEY + CLIENT_REGISTRATION +
SPRING_SECURITY_OAUTH2_CLIENT_SECRET_KEY, "test-secret");
}
@Test

View File

@@ -168,7 +168,7 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware
public Mono<UpdateApplicationResponse> update(UpdateApplicationRequest request) {
final String name = request.getName();
final Map<String, Object> environmentVariables =
getApplicationEnvironment(request.getProperties(), request.getEnvironment());
getApplicationEnvironment(request.getProperties(), request.getEnvironment(), request.getServiceInstanceId());
Map<String, String> deploymentProperties = request.getProperties();
CloudFoundryOperations operations;
@@ -536,24 +536,25 @@ public class CloudFoundryAppDeployer implements AppDeployer, ResourceLoaderAware
private Map<String, Object> getEnvironmentVariables(Map<String, String> properties,
Map<String, Object> environment,
String serviceInstanceId) {
Map<String, Object> envVariables = getApplicationEnvironment(properties, environment);
Map<String, Object> envVariables = getApplicationEnvironment(properties, environment, serviceInstanceId);
String javaOpts = javaOpts(properties);
if (StringUtils.hasText(javaOpts)) {
envVariables.put("JAVA_OPTS", javaOpts);
}
if (serviceInstanceId != null) {
envVariables.put("SPRING_CLOUD_APPBROKER_SERVICE_INSTANCE_ID", serviceInstanceId);
}
return envVariables;
}
private Map<String, Object> getApplicationEnvironment(Map<String, String> properties,
Map<String, Object> environment) {
Map<String, Object> environment,
String serviceInstanceId) {
Map<String, Object> applicationEnvironment = sanitizeApplicationEnvironment(environment);
if (serviceInstanceId != null) {
applicationEnvironment.put("spring.cloud.appbroker.service-instance-id", serviceInstanceId);
}
if (!applicationEnvironment.isEmpty() && useSpringApplicationJson(properties)) {
try {
String jsonEnvironment = OBJECT_MAPPER.writeValueAsString(applicationEnvironment);

View File

@@ -125,7 +125,7 @@ class CloudFoundryAppDeployerTest {
.assertNext(response -> assertThat(response.getName()).isEqualTo(APP_NAME))
.verifyComplete();
ApplicationManifest expectedManifest = baseManifest()
ApplicationManifest expectedManifest = baseManifestWithSpringAppJson()
.name(APP_NAME)
.path(new File(APP_PATH).toPath())
.build();
@@ -154,7 +154,7 @@ class CloudFoundryAppDeployerTest {
.assertNext(response -> assertThat(response.getName()).isEqualTo(APP_NAME))
.verifyComplete();
ApplicationManifest expectedManifest = baseManifest()
ApplicationManifest expectedManifest = baseManifestWithSpringAppJson()
.name(APP_NAME)
.path(new File(APP_PATH).toPath())
.instances(3)
@@ -192,7 +192,7 @@ class CloudFoundryAppDeployerTest {
.assertNext(response -> assertThat(response.getName()).isEqualTo(APP_NAME))
.verifyComplete();
ApplicationManifest expectedManifest = baseManifest()
ApplicationManifest expectedManifest = baseManifestWithSpringAppJson()
.name(APP_NAME)
.path(new File(APP_PATH).toPath())
.instances(3)
@@ -238,7 +238,7 @@ class CloudFoundryAppDeployerTest {
.assertNext(response -> assertThat(response.getName()).isEqualTo(APP_NAME))
.verifyComplete();
ApplicationManifest expectedManifest = baseManifest()
ApplicationManifest expectedManifest = baseManifestWithSpringAppJson()
.name(APP_NAME)
.path(new File(APP_PATH).toPath())
.instances(5)
@@ -272,11 +272,10 @@ class CloudFoundryAppDeployerTest {
.assertNext(response -> assertThat(response.getName()).isEqualTo(APP_NAME))
.verifyComplete();
ApplicationManifest expectedManifest = baseManifest()
ApplicationManifest expectedManifest = baseManifestWithSpringAppJson("\"ENV_VAR_2\":\"value2\",\"ENV_VAR_1\":\"value1\"")
.name(APP_NAME)
.path(new File(APP_PATH).toPath())
.environmentVariable("JAVA_OPTS", "-Xms512m -Xmx1024m")
.environmentVariable("SPRING_APPLICATION_JSON", "{\"ENV_VAR_2\":\"value2\",\"ENV_VAR_1\":\"value1\"}")
.build();
verify(operationsApplications).pushManifest(argThat(matchesManifest(expectedManifest)));
@@ -303,6 +302,7 @@ class CloudFoundryAppDeployerTest {
.name(APP_NAME)
.path(new File(APP_PATH).toPath())
.environmentVariable("JAVA_OPTS", "-Xms512m -Xmx1024m")
.environmentVariable("spring.cloud.appbroker.service-instance-id", SERVICE_INSTANCE_ID)
.environmentVariable("ENV_VAR_1", "value1")
.environmentVariable("ENV_VAR_2", "value2")
.build();
@@ -476,7 +476,20 @@ class CloudFoundryAppDeployerTest {
private ApplicationManifest.Builder baseManifest() {
return ApplicationManifest.builder()
.environmentVariable("SPRING_CLOUD_APPBROKER_SERVICE_INSTANCE_ID", SERVICE_INSTANCE_ID)
.services(new ArrayList<>());
}
private ApplicationManifest.Builder baseManifestWithSpringAppJson() {
return ApplicationManifest.builder()
.environmentVariable("SPRING_APPLICATION_JSON",
"{\"spring.cloud.appbroker.service-instance-id\":\"" + SERVICE_INSTANCE_ID + "\"}")
.services(new ArrayList<>());
}
private ApplicationManifest.Builder baseManifestWithSpringAppJson(String json) {
return ApplicationManifest.builder()
.environmentVariable("SPRING_APPLICATION_JSON",
"{" + json + ",\"spring.cloud.appbroker.service-instance-id\":\"" + SERVICE_INSTANCE_ID + "\"}")
.services(new ArrayList<>());
}

View File

@@ -58,12 +58,12 @@ class CreateInstanceComponentTest extends WiremockComponentTest {
void pushAppsWhenTheyDoNotExist() {
cloudControllerFixture.stubAppDoesNotExist(APP_NAME_1);
cloudControllerFixture.stubPushApp(APP_NAME_1,
matchingJsonPath("$.environment_json[?(@.SPRING_CLOUD_APPBROKER_SERVICE_INSTANCE_ID =~ " +
"/.*" + SERVICE_INSTANCE_ID + ".*/)]"));
matchingJsonPath("$.environment_json[?(@.SPRING_APPLICATION_JSON =~ " +
"/.*spring.cloud.appbroker.service-instance-id.*:.*" + SERVICE_INSTANCE_ID + ".*/)]"));
cloudControllerFixture.stubAppDoesNotExist(APP_NAME_2);
cloudControllerFixture.stubPushApp(APP_NAME_2,
matchingJsonPath("$.environment_json[?(@.SPRING_CLOUD_APPBROKER_SERVICE_INSTANCE_ID =~ " +
"/.*" + SERVICE_INSTANCE_ID + ".*/)]"));
matchingJsonPath("$.environment_json[?(@.['spring.cloud.appbroker.service-instance-id'] =~ " +
"/" + SERVICE_INSTANCE_ID + "/)]"));
// when a service instance is created
given(brokerFixture.serviceInstanceRequest())

View File

@@ -29,23 +29,38 @@ import static io.restassured.RestAssured.given;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.springframework.cloud.appbroker.integration.CreateInstanceWithBasicAuthCredentialsComponentTest.APP_NAME;
import static org.springframework.cloud.appbroker.integration.CreateInstanceWithBasicAuthCredentialsComponentTest.APP_NAME_1;
import static org.springframework.cloud.appbroker.integration.CreateInstanceWithBasicAuthCredentialsComponentTest.APP_NAME_2;
@TestPropertySource(properties = {
"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",
"spring.cloud.appbroker.services[0].apps[0].name=" + APP_NAME,
"spring.cloud.appbroker.services[0].apps[0].name=" + APP_NAME_1,
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].name=SpringSecurityBasicAuth",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.length=14",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.include-uppercase-alpha=true",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.include-lowercase-alpha=true",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.include-numeric=false",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.include-special=false"
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.include-special=false",
"spring.cloud.appbroker.services[0].apps[1].path=classpath:demo.jar",
"spring.cloud.appbroker.services[0].apps[1].name=" + APP_NAME_2,
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].name=SpringSecurityBasicAuth",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.length=14",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.include-uppercase-alpha=true",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.include-lowercase-alpha=true",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.include-numeric=false",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.include-special=false",
"spring.cloud.appbroker.services[0].apps[1].properties.use-spring-application-json=false"
})
class CreateInstanceWithBasicAuthCredentialsComponentTest extends WiremockComponentTest {
static final String APP_NAME = "app-with-credentials";
static final String APP_NAME_1 = "app-with-credentials1";
static final String APP_NAME_2 = "app-with-credentials2";
private static final String SERVICE_INSTANCE_ID = "instance-id";
@Autowired
private OpenServiceBrokerApiFixture brokerFixture;
@@ -55,27 +70,32 @@ class CreateInstanceWithBasicAuthCredentialsComponentTest extends WiremockCompon
@Test
void pushAppWithCredentials() {
cloudControllerFixture.stubAppDoesNotExist(APP_NAME);
cloudControllerFixture.stubPushApp(APP_NAME,
matchingJsonPath("$.environment_json[?(@.SPRING_APPLICATION_JSON =~ /.*security.*user.*name.*:.*[a-zA-Z]{14}.*/)]"),
matchingJsonPath("$.environment_json[?(@.SPRING_APPLICATION_JSON =~ /.*security.*user.*password.*:.*[a-zA-Z]{14}.*/)]"));
cloudControllerFixture.stubAppDoesNotExist(APP_NAME_1);
cloudControllerFixture.stubPushApp(APP_NAME_1,
matchingJsonPath("$.environment_json[?(@.SPRING_APPLICATION_JSON =~ /.*spring.security.user.name.*:.*[a-zA-Z]{14}.*/)]"),
matchingJsonPath("$.environment_json[?(@.SPRING_APPLICATION_JSON =~ /.*spring.security.user.password.*:.*[a-zA-Z]{14}.*/)]"));
cloudControllerFixture.stubAppDoesNotExist(APP_NAME_2);
cloudControllerFixture.stubPushApp(APP_NAME_2,
matchingJsonPath("$.environment_json[?(@.['spring.security.user.name'] =~ /[a-zA-Z]{14}/)]"),
matchingJsonPath("$.environment_json[?(@.['spring.security.user.password'] =~ /[a-zA-Z]{14}/)]"));
// when a service instance is created
given(brokerFixture.serviceInstanceRequest())
.when()
.put(brokerFixture.createServiceInstanceUrl(), "instance-id")
.put(brokerFixture.createServiceInstanceUrl(), SERVICE_INSTANCE_ID)
.then()
.statusCode(HttpStatus.ACCEPTED.value());
// when the "last_operation" API is polled
given(brokerFixture.serviceInstanceRequest())
.when()
.get(brokerFixture.getLastInstanceOperationUrl(), "instance-id")
.get(brokerFixture.getLastInstanceOperationUrl(), SERVICE_INSTANCE_ID)
.then()
.statusCode(HttpStatus.OK.value())
.body("state", is(equalTo(OperationState.IN_PROGRESS.toString())));
String state = brokerFixture.waitForAsyncOperationComplete("instance-id");
String state = brokerFixture.waitForAsyncOperationComplete(SERVICE_INSTANCE_ID);
assertThat(state).isEqualTo(OperationState.SUCCEEDED.toString());
}
}

View File

@@ -79,7 +79,7 @@ class CreateInstanceWithCredHubCredentialsComponentTest extends WiremockComponen
cloudControllerFixture.stubAppDoesNotExist(APP_NAME);
cloudControllerFixture.stubPushApp(APP_NAME);
uaaFixture.stubCreateClient();
uaaFixture.stubCreateClient("test-client");
credHubFixture.stubGenerateUser(APP_NAME, SERVICE_INSTANCE_ID, "basic", 14);
credHubFixture.stubGeneratePassword(APP_NAME, SERVICE_INSTANCE_ID, "oauth2", 12);

View File

@@ -30,26 +30,44 @@ import static io.restassured.RestAssured.given;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.springframework.cloud.appbroker.integration.CreateInstanceWithOAuth2CredentialsComponentTest.APP_NAME;
import static org.springframework.cloud.appbroker.integration.CreateInstanceWithOAuth2CredentialsComponentTest.APP_NAME_1;
import static org.springframework.cloud.appbroker.integration.CreateInstanceWithOAuth2CredentialsComponentTest.APP_NAME_2;
@TestPropertySource(properties = {
"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",
"spring.cloud.appbroker.services[0].apps[0].name=" + APP_NAME,
"spring.cloud.appbroker.services[0].apps[0].name=" + APP_NAME_1,
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].name=SpringSecurityOAuth2",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.registration=example-app-client",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.client-id=test-client",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.client-id=test-client1",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.grant-types=[\"client_credentials\"]",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.length=14",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.include-uppercase-alpha=true",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.include-lowercase-alpha=true",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.include-numeric=false",
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.include-special=false"
"spring.cloud.appbroker.services[0].apps[0].credential-providers[0].args.include-special=false",
"spring.cloud.appbroker.services[0].apps[1].path=classpath:demo.jar",
"spring.cloud.appbroker.services[0].apps[1].name=" + APP_NAME_2,
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].name=SpringSecurityOAuth2",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.registration=example-app-client",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.client-id=test-client2",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.grant-types=[\"client_credentials\"]",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.length=14",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.include-uppercase-alpha=true",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.include-lowercase-alpha=true",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.include-numeric=false",
"spring.cloud.appbroker.services[0].apps[1].credential-providers[0].args.include-special=false",
"spring.cloud.appbroker.services[0].apps[1].properties.use-spring-application-json=false"
})
class CreateInstanceWithOAuth2CredentialsComponentTest extends WiremockComponentTest {
static final String APP_NAME = "app-with-outh2-credentials";
static final String APP_NAME_1 = "app-with-outh2-credentials1";
static final String APP_NAME_2 = "app-with-outh2-credentials2";
private static final String SERVICE_INSTANCE_ID = "instance-id";
@Autowired
private OpenServiceBrokerApiFixture brokerFixture;
@@ -62,58 +80,71 @@ class CreateInstanceWithOAuth2CredentialsComponentTest extends WiremockComponent
@Test
void pushAppWithOAuth2Credentials() {
cloudControllerFixture.stubAppDoesNotExist(APP_NAME);
cloudControllerFixture.stubPushApp(APP_NAME,
cloudControllerFixture.stubAppDoesNotExist(APP_NAME_1);
cloudControllerFixture.stubPushApp(APP_NAME_1,
matchingJsonPath("$.environment_json[?(@.SPRING_APPLICATION_JSON =~ " +
"/.*spring.*security.*oauth2.*client.*registration.*example-app-client.*client-id.*:.*test-client.*/)]"),
"/.*spring.security.oauth2.client.registration.example-app-client.client-id.*:.*test-client1.*/)]"),
matchingJsonPath("$.environment_json[?(@.SPRING_APPLICATION_JSON =~ " +
"/.*spring.*security.*oauth2.*client.*registration.*example-app-client.*client-secret.*:.*[a-zA-Z]{14}.*/)]"));
"/.*spring.security.oauth2.client.registration.example-app-client.client-secret.*:.*[a-zA-Z]{14}.*/)]"));
uaaFixture.stubCreateClient();
cloudControllerFixture.stubAppDoesNotExist(APP_NAME_2);
cloudControllerFixture.stubPushApp(APP_NAME_2,
matchingJsonPath("$.environment_json[?(@.['spring.security.oauth2.client.registration.example-app-client.client-id'] =~ " +
"/test-client2/)]"),
matchingJsonPath("$.environment_json[?(@.['spring.security.oauth2.client.registration.example-app-client.client-secret'] =~ " +
"/[a-zA-Z]{14}/)]"));
uaaFixture.stubCreateClient("test-client1");
uaaFixture.stubCreateClient("test-client2");
// when a service instance is created
given(brokerFixture.serviceInstanceRequest())
.when()
.put(brokerFixture.createServiceInstanceUrl(), "instance-id")
.put(brokerFixture.createServiceInstanceUrl(), SERVICE_INSTANCE_ID)
.then()
.statusCode(HttpStatus.ACCEPTED.value());
// when the "last_operation" API is polled
given(brokerFixture.serviceInstanceRequest())
.when()
.get(brokerFixture.getLastInstanceOperationUrl(), "instance-id")
.get(brokerFixture.getLastInstanceOperationUrl(), SERVICE_INSTANCE_ID)
.then()
.statusCode(HttpStatus.OK.value())
.body("state", is(equalTo(OperationState.IN_PROGRESS.toString())));
String state = brokerFixture.waitForAsyncOperationComplete("instance-id");
String state = brokerFixture.waitForAsyncOperationComplete(SERVICE_INSTANCE_ID);
assertThat(state).isEqualTo(OperationState.SUCCEEDED.toString());
}
@Test
void deleteAppWithOAuth2Credentials() {
cloudControllerFixture.stubAppExists(APP_NAME);
cloudControllerFixture.stubServiceBindingDoesNotExist(APP_NAME);
cloudControllerFixture.stubDeleteApp(APP_NAME);
cloudControllerFixture.stubAppExists(APP_NAME_1);
cloudControllerFixture.stubServiceBindingDoesNotExist(APP_NAME_1);
cloudControllerFixture.stubDeleteApp(APP_NAME_1);
uaaFixture.stubDeleteClient("test-client");
cloudControllerFixture.stubAppExists(APP_NAME_2);
cloudControllerFixture.stubServiceBindingDoesNotExist(APP_NAME_2);
cloudControllerFixture.stubDeleteApp(APP_NAME_2);
uaaFixture.stubDeleteClient("test-client1");
uaaFixture.stubDeleteClient("test-client2");
// when the service instance is deleted
given(brokerFixture.serviceInstanceRequest())
.when()
.delete(brokerFixture.deleteServiceInstanceUrl(), "instance-id")
.delete(brokerFixture.deleteServiceInstanceUrl(), SERVICE_INSTANCE_ID)
.then()
.statusCode(HttpStatus.ACCEPTED.value());
// when the "last_operation" API is polled
given(brokerFixture.serviceInstanceRequest())
.when()
.get(brokerFixture.getLastInstanceOperationUrl(), "instance-id")
.get(brokerFixture.getLastInstanceOperationUrl(), SERVICE_INSTANCE_ID)
.then()
.statusCode(HttpStatus.OK.value())
.body("state", is(equalTo(OperationState.IN_PROGRESS.toString())));
String state = brokerFixture.waitForAsyncOperationComplete("instance-id");
String state = brokerFixture.waitForAsyncOperationComplete(SERVICE_INSTANCE_ID);
assertThat(state).isEqualTo(OperationState.SUCCEEDED.toString());
}

View File

@@ -20,6 +20,7 @@ import org.springframework.boot.test.context.TestComponent;
import static com.github.tomakehurst.wiremock.client.WireMock.delete;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath;
import static com.github.tomakehurst.wiremock.client.WireMock.ok;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
@@ -94,10 +95,12 @@ public class UaaStubFixture extends WiremockStubFixture {
.withBody(uaa("get-token-keys"))));
}
public void stubCreateClient() {
public void stubCreateClient(String clientId) {
stubFor(post(urlPathEqualTo("/oauth/clients"))
.withRequestBody(matchingJsonPath("$.[?(@.client_id == '" + clientId + "')]"))
.willReturn(ok()
.withBody(uaa("post-oauth-clients"))));
.withBody(uaa("post-oauth-clients",
replace("@client-id", clientId)))));
}
public void stubDeleteClient(String clientId) {
@@ -106,7 +109,11 @@ public class UaaStubFixture extends WiremockStubFixture {
.withBody(uaa("delete-oauth-clients"))));
}
private String uaa(String fileRoot) {
return readResponseFromFile(fileRoot, "uaa");
private String uaa(String fileRoot, StringReplacementPair... replacements) {
String response = readResponseFromFile(fileRoot, "uaa");
for (StringReplacementPair pair : replacements) {
response = response.replaceAll(pair.getRegex(), pair.getReplacement());
}
return response;
}
}

View File

@@ -1,7 +1,7 @@
{
"client_id" : "foo",
"name" : "Foo Client Name",
"client_secret" : "fooclientsecret",
"name" : "Client Name",
"client_id" : "@client-id",
"client_secret" : "client-secret",
"scope" : ["uaa.none"],
"authorities" : ["cloud_controller.read","cloud_controller.write","openid"],
"authorized_grant_types" : ["client_credentials"],