diff --git a/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/CloudFoundryAcceptanceTest.java b/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/CloudFoundryAcceptanceTest.java index 2b20711..34a8917 100644 --- a/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/CloudFoundryAcceptanceTest.java +++ b/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/CloudFoundryAcceptanceTest.java @@ -143,8 +143,8 @@ abstract class CloudFoundryAcceptanceTest { @BeforeEach void setUp(TestInfo testInfo, BrokerProperties brokerProperties) { List appBrokerProperties = getAppBrokerProperties(brokerProperties); - blockingSubscribe(initializeBroker(appBrokerProperties)); blockingSubscribe(initializeUser()); + blockingSubscribe(initializeBroker(appBrokerProperties)); } void setUpForBrokerUpdate(BrokerProperties brokerProperties) { @@ -219,10 +219,7 @@ abstract class CloudFoundryAcceptanceTest { .flatMap(orgId -> cloudFoundryService .getOrCreateSpace(userCloudFoundryService.getOrgName(), userCloudFoundryService.getSpaceName()) .map(SpaceSummary::getId) - .flatMap(spaceId -> uaaService.createClient( - USER_CLIENT_ID, - USER_CLIENT_SECRET, - USER_CLIENT_AUTHORITIES) + .flatMap(spaceId -> uaaService.createClient(USER_CLIENT_ID, USER_CLIENT_SECRET, USER_CLIENT_AUTHORITIES) .then(cloudFoundryService .associateClientWithOrgAndSpace(USER_CLIENT_ID, orgId, spaceId)))); } @@ -421,8 +418,8 @@ abstract class CloudFoundryAcceptanceTest { .flatMap(appRoute -> webClient.get() .uri(URI.create(appRoute + "/" + operation + "/" + serviceName + "/" + planName + "/" + serviceInstanceId)) - .exchange() - .flatMap(clientResponse -> clientResponse.toEntity(String.class)) + .retrieve() + .toEntity(String.class) .map(HttpEntity::getBody))); } diff --git a/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/cf/CloudFoundryService.java b/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/cf/CloudFoundryService.java index 405bd71..154fe4d 100644 --- a/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/cf/CloudFoundryService.java +++ b/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/cf/CloudFoundryService.java @@ -176,10 +176,13 @@ public class CloudFoundryService { } public Mono deleteApp(String appName) { - return cloudFoundryOperations.applications().delete(DeleteApplicationRequest.builder() - .name(appName) - .deleteRoutes(true) - .build()) + return cloudFoundryOperations.applications().list() + .filter(app -> appName.equals(app.getName())) + .singleOrEmpty() + .flatMap(app -> cloudFoundryOperations.applications().delete(DeleteApplicationRequest.builder() + .name(appName) + .deleteRoutes(true) + .build())) .doOnSuccess(item -> LOG.info("Success deleting app. appName={}", appName)) .doOnError(e -> LOG.warn(String.format("Error deleting app. appName=%s, error=%s", appName, e.getMessage()), e)) @@ -187,9 +190,12 @@ public class CloudFoundryService { } public Mono deleteServiceBroker(String brokerName) { - return cloudFoundryOperations.serviceAdmin().delete(DeleteServiceBrokerRequest.builder() - .name(brokerName) - .build()) + return cloudFoundryOperations.serviceAdmin().list() + .filter(serviceBroker -> brokerName.equals(serviceBroker.getName())) + .singleOrEmpty() + .flatMap(serviceBroker -> cloudFoundryOperations.serviceAdmin() + .delete(DeleteServiceBrokerRequest.builder().name(brokerName).build()) + ) .doOnSuccess(item -> LOG.info("Success deleting service broker. brokerName={}", brokerName)) .doOnError(e -> LOG.warn(String.format("Error deleting service broker. brokerName=%s, error=%s ", brokerName, e.getMessage()), e)) diff --git a/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/cf/UserCloudFoundryService.java b/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/cf/UserCloudFoundryService.java index 819312b..84dcd6f 100644 --- a/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/cf/UserCloudFoundryService.java +++ b/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/cf/UserCloudFoundryService.java @@ -18,6 +18,7 @@ package org.springframework.cloud.appbroker.acceptance.fixtures.cf; import java.util.Map; +import org.cloudfoundry.UnknownCloudFoundryException; import org.cloudfoundry.operations.CloudFoundryOperations; import org.cloudfoundry.operations.DefaultCloudFoundryOperations; import org.cloudfoundry.operations.services.CreateServiceInstanceRequest; @@ -86,11 +87,9 @@ public final class UserCloudFoundryService { .build()) .doOnSuccess(v -> LOG.info("Success deleting service instance. serviceInstanceName={}", serviceInstanceName)) - .doOnError(e -> LOG.error(String.format("Error deleting service instance. serviceInstanceName=%s, " + - "error=%s", serviceInstanceName, e.getMessage()), e)) + .doOnError(error -> logError("deleting service instance", serviceInstanceName, error)) .onErrorResume(e -> Mono.empty())) - .doOnError(e -> LOG.warn(String.format("Error getting service instance. serviceInstanceName=%s, " + - "error=%s", serviceInstanceName, e.getMessage()), e)) + .doOnError(error -> logError("getting service instance", serviceInstanceName, error)) .onErrorResume(e -> Mono.empty()); } @@ -106,8 +105,7 @@ public final class UserCloudFoundryService { .build()) .doOnSuccess(item -> LOG.info("Success creating service instance. serviceInstanceName={}", serviceInstanceName)) - .doOnError(e -> LOG.error(String.format("Error creating service instance. serviceInstanceName=%s, " + - "error=%s", serviceInstanceName, e.getMessage()), e)); + .doOnError(error -> logError("creating service instance", serviceInstanceName, error)); } public Mono updateServiceInstance(String serviceInstanceName, Map parameters) { @@ -117,7 +115,7 @@ public final class UserCloudFoundryService { .parameters(parameters) .build()) .doOnSuccess(item -> LOG.info("Updated service instance " + serviceInstanceName)) - .doOnError(error -> LOG.error("Error updating service instance " + serviceInstanceName + ": " + error)); + .doOnError(error -> logError("updating service instance", serviceInstanceName, error)); } public Mono getServiceInstance(String serviceInstanceName) { @@ -126,6 +124,19 @@ public final class UserCloudFoundryService { .name(serviceInstanceName) .build()) .doOnSuccess(item -> LOG.info("Got service instance " + serviceInstanceName)) - .doOnError(error -> LOG.error("Error getting service instance " + serviceInstanceName + ": " + error)); + .doOnError(error -> logError("getting service instance", serviceInstanceName, error)); + } + + private static void logError(String operation, String serviceInstanceName, Throwable error) { + String logMessage; + if (error instanceof UnknownCloudFoundryException) { + UnknownCloudFoundryException unknownCloudFoundryException = (UnknownCloudFoundryException) error; + logMessage = String.format("Error %s %s: %s %s", operation, serviceInstanceName, + unknownCloudFoundryException.getMessage(), unknownCloudFoundryException.getPayload()); + } + else { + logMessage = String.format("Error %s %s: %s", operation, serviceInstanceName, error); + } + LOG.error(logMessage, error); } } diff --git a/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/uaa/UaaService.java b/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/uaa/UaaService.java index 08b4ace..3cbfe01 100644 --- a/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/uaa/UaaService.java +++ b/spring-cloud-app-broker-acceptance-tests/src/test/java/org/springframework/cloud/appbroker/acceptance/fixtures/uaa/UaaService.java @@ -16,6 +16,8 @@ package org.springframework.cloud.appbroker.acceptance.fixtures.uaa; +import java.util.Arrays; + import org.cloudfoundry.uaa.UaaClient; import org.cloudfoundry.uaa.clients.CreateClientRequest; import org.cloudfoundry.uaa.clients.DeleteClientRequest; @@ -48,22 +50,37 @@ public class UaaService { } public Mono createClient(String clientId, String clientSecret, String... authorities) { - return uaaClient.clients().delete(DeleteClientRequest - .builder() - .clientId(clientId) - .build()) - .doOnError(error -> LOG.warn("Error deleting client: " + clientId + " with error: " + error)) - .onErrorResume(e -> Mono.empty()) - .then(uaaClient.clients().create(CreateClientRequest - .builder() - .clientId(clientId) - .clientSecret(clientSecret) - .authorizedGrantType(GrantType.CLIENT_CREDENTIALS) - .authorities(authorities) + final String clientNotFound = "CLIENT_NOT_FOUND"; + return getUaaClient(clientId) + .defaultIfEmpty(GetClientResponse.builder() + .clientId(clientNotFound) + .authorities(clientNotFound) .build()) - .doOnError(error -> LOG.error("Error creating client: " + clientId + " with error: " + error)) - .onErrorResume(e -> Mono.empty())) + .filter(response -> authoritiesChanged(response, authorities)) + .delayUntil(response -> { + if (!clientNotFound.equals(response.getClientId())) { + return uaaClient.clients() + .delete(DeleteClientRequest.builder().clientId(clientId).build()) + .doOnError(error -> LOG.error("Error deleting client: " + clientId + " with error: " + error)); + } + return Mono.empty(); + }) + .flatMap(response -> uaaClient.clients() + .create(CreateClientRequest + .builder() + .clientId(clientId) + .clientSecret(clientSecret) + .authorizedGrantType(GrantType.CLIENT_CREDENTIALS) + .authorities(authorities) + .build()) + .onErrorResume(e -> e.getMessage().contains("Client already exists: " + clientId), e -> Mono.empty()) + .doOnError(error -> LOG.error("Error creating client: " + clientId + " with error: " + error))) .then(); } + private boolean authoritiesChanged(GetClientResponse response, String... authorities) { + return !response.getAuthorities().containsAll(Arrays.asList(authorities)) || + response.getAuthorities().size() != authorities.length; + } + } diff --git a/spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/streaming/ServiceInstanceLogStreamingTest.java b/spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/streaming/ServiceInstanceLogStreamingTest.java index f612515..6fa84b6 100644 --- a/spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/streaming/ServiceInstanceLogStreamingTest.java +++ b/spring-cloud-app-broker-logging/src/test/java/org/springframework/cloud/appbroker/logging/streaming/ServiceInstanceLogStreamingTest.java @@ -18,7 +18,6 @@ package org.springframework.cloud.appbroker.logging.streaming; import java.io.IOException; import java.net.URI; -import java.time.Duration; import java.time.Instant; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; @@ -121,8 +120,7 @@ class ServiceInstanceLogStreamingTest { void shouldPublishWebSocketEndpoint() { Disposable subscription = connectToLogsStreamEndpoint(); - await().atMost(Duration.ofSeconds(1)) - .untilAsserted(() -> assertThat(actualEnvelope).hasValue(expectedEnvelope)); + await().untilAsserted(() -> assertThat(actualEnvelope).hasValue(expectedEnvelope)); subscription.dispose(); } @@ -131,13 +129,11 @@ class ServiceInstanceLogStreamingTest { void shouldPublishEventOnDisconnect() { Disposable subscription = connectToLogsStreamEndpoint(); - await().atMost(Duration.ofSeconds(1)) - .untilAsserted(() -> assertThat(actualEnvelope.get()).isNotNull()); + await().untilAsserted(() -> assertThat(actualEnvelope.get()).isNotNull()); subscription.dispose(); - await().atMost(Duration.ofSeconds(1)) - .untilAsserted(() -> assertThat(LogStreamingTestApp.isReceivedStopEvent()).isTrue()); + await().untilAsserted(() -> assertThat(LogStreamingTestApp.isReceivedStopEvent()).isTrue()); } @Test @@ -149,8 +145,7 @@ class ServiceInstanceLogStreamingTest { subscription.dispose(); applicationEventPublisher.publishEvent(new ServiceInstanceLogEvent(this, serviceInstanceId, expectedEnvelope)); - await().atMost(Duration.ofSeconds(1)) - .untilAsserted(() -> assertThat(LogStreamingTestApp.getReceivedStopEventServiceInstanceId()).isEqualTo(serviceInstanceId)); + await().untilAsserted(() -> assertThat(LogStreamingTestApp.getReceivedStopEventServiceInstanceId()).isEqualTo(serviceInstanceId)); } private Disposable connectToLogsStreamEndpoint() {