From bfbd700a5a6d8fac3aee96b4cd7f444575d912c3 Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Tue, 17 Feb 2026 17:51:51 +0100 Subject: [PATCH 01/14] Support skipping CF API V2 tests TODO: I am unsure about this one. Needs more exploration # Conflicts: # README.md # integration-test/src/test/java/org/cloudfoundry/operations/StacksTest.java --- README.md | 1 + .../org/cloudfoundry/CloudFoundryCleaner.java | 98 ++++++++++++++----- .../IntegrationTestConfiguration.java | 8 ++ .../java/org/cloudfoundry/RequiresV2Api.java | 72 ++++++++++++++ .../client/v2/ApplicationsTest.java | 2 + .../client/v2/BlobstoresTest.java | 2 + .../client/v2/BuildpacksTest.java | 2 + .../cloudfoundry/client/v2/DomainsTest.java | 2 + .../cloudfoundry/client/v2/EventsTest.java | 2 + .../client/v2/FeatureFlagsTest.java | 2 + .../org/cloudfoundry/client/v2/InfoTest.java | 2 + .../org/cloudfoundry/client/v2/JobsTest.java | 2 + .../v2/OrganizationQuotaDefinitionsTest.java | 2 + .../client/v2/OrganizationsTest.java | 6 +- .../client/v2/PrivateDomainsTest.java | 2 + .../client/v2/RouteMappingsTest.java | 2 + .../cloudfoundry/client/v2/RoutesTest.java | 2 + .../client/v2/SecurityGroupsTest.java | 2 + .../client/v2/ServiceBindingsTest.java | 2 + .../client/v2/ServiceBrokersTest.java | 6 +- .../client/v2/ServiceInstancesTest.java | 6 +- .../client/v2/ServiceKeysTest.java | 6 +- .../v2/ServicePlanVisibilitiesTest.java | 2 + .../client/v2/ServicePlansTest.java | 6 +- .../client/v2/ServiceUsageEventsTest.java | 6 +- .../cloudfoundry/client/v2/ServicesTest.java | 6 +- .../client/v2/SharedDomainsTest.java | 2 + .../client/v2/SpaceQuotaDefinitionsTest.java | 2 + .../cloudfoundry/client/v2/SpacesTest.java | 6 +- .../cloudfoundry/client/v2/StacksTest.java | 2 + .../client/v2/UserProvidedServicesTest.java | 2 + .../org/cloudfoundry/client/v2/UsersTest.java | 2 + .../org/cloudfoundry/client/v3/AdminTest.java | 3 + .../client/v3/DeploymentsTest.java | 2 + .../client/v3/IsolationSegmentsTest.java | 2 + .../client/v3/OrganizationsTest.java | 2 + .../cloudfoundry/client/v3/ProcessesTest.java | 2 + .../client/v3/ServiceBindingsTest.java | 6 +- .../client/v3/ServiceBrokersTest.java | 6 +- .../client/v3/ServiceInstancesTest.java | 6 +- .../client/v3/ServiceOfferingsTest.java | 6 +- .../client/v3/ServicePlansTest.java | 6 +- .../org/cloudfoundry/client/v3/TasksTest.java | 2 + .../cloudfoundry/operations/AdvancedTest.java | 2 + .../operations/ApplicationsTest.java | 2 + .../operations/BuildpacksTest.java | 2 + .../cloudfoundry/operations/DomainsTest.java | 2 + .../operations/NetworkPoliciesTest.java | 2 + .../operations/OrganizationAdminTest.java | 2 + .../operations/OrganizationsTest.java | 2 + .../cloudfoundry/operations/RoutesTest.java | 2 + .../operations/ServiceAdminTest.java | 2 + .../cloudfoundry/operations/ServicesTest.java | 6 +- .../cloudfoundry/operations/SpacesTest.java | 2 + .../cloudfoundry/operations/StacksTest.java | 0 .../operations/UserAdminTest.java | 2 + 56 files changed, 297 insertions(+), 41 deletions(-) create mode 100644 integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java create mode 100644 integration-test/src/test/java/org/cloudfoundry/operations/StacksTest.java diff --git a/README.md b/README.md index 715033c14e6..5b4b1fad713 100644 --- a/README.md +++ b/README.md @@ -353,6 +353,7 @@ Name | Description `TEST_PROXY_PORT` | _(Optional)_ The port of a proxy to route all requests through. Defaults to `8080`. `TEST_PROXY_USERNAME` | _(Optional)_ The username for a proxy to route all requests through `TEST_SKIPSSLVALIDATION` | _(Optional)_ Whether to skip SSL validation when connecting to the Cloud Foundry instance. Defaults to `false`. +`SKIP_V2_TESTS` | _(Optional)_ Set to `true` to skip all V2 API integration tests. Useful when the Cloud Foundry V2 API is rate-limited or unavailable. When enabled, tests annotated with `@RequiresV2Api` will be skipped, including V3 tests that depend on V2 API calls (e.g., service broker creation). Defaults to `false`. If you do not have access to a CloudFoundry instance with admin access, you can run one locally using [bosh-deployment](https://github.com/cloudfoundry/bosh-deployment) & [cf-deployment](https://github.com/cloudfoundry/cf-deployment/) and Virtualbox. diff --git a/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java b/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java index d515a86b092..2985a04cde6 100644 --- a/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java +++ b/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java @@ -77,6 +77,7 @@ import org.cloudfoundry.client.v3.Metadata; import org.cloudfoundry.client.v3.Relationship; import org.cloudfoundry.client.v3.applications.Application; +import org.cloudfoundry.client.v3.applications.ApplicationResource; import org.cloudfoundry.client.v3.applications.DeleteApplicationRequest; import org.cloudfoundry.client.v3.applications.ListApplicationsRequest; import org.cloudfoundry.client.v3.serviceinstances.ListSharedSpacesRelationshipRequest; @@ -129,6 +130,12 @@ final class CloudFoundryCleaner implements InitializingBean, DisposableBean { private static final Logger LOGGER = LoggerFactory.getLogger("cloudfoundry-client.test"); + private static final boolean RUN_V2_CLEANUP = isRunV2Tests(); + + private static boolean isRunV2Tests() { + return !"true".equalsIgnoreCase(System.getenv("SKIP_V2_TESTS")); + } + private static final Map STANDARD_FEATURE_FLAGS = FluentMap.builder() .entry("app_bits_upload", true) @@ -186,6 +193,31 @@ public void destroy() { } void clean() { + if (!RUN_V2_CLEANUP) { + LOGGER.info("Skipping V2 API cleanup operations (SKIP_V2_TESTS=true)"); + // Only run V3 and UAA cleanup operations + Flux.empty() + .thenMany( + Mono.when( // No prerequisites - V3/UAA only + cleanClients(this.uaaClient, this.nameFactory), + cleanGroups(this.uaaClient, this.nameFactory), + cleanIdentityProviders(this.uaaClient, this.nameFactory), + cleanIdentityZones(this.uaaClient, this.nameFactory))) + .thenMany( + Mono.when( + cleanApplicationsV3( + this.cloudFoundryClient, + this.nameFactory, + false), // runV2Calls = false (V3-only path) + cleanUsers(this.uaaClient, this.nameFactory))) + .retryWhen(Retry.max(5).filter(SSLException.class::isInstance)) + .doOnSubscribe(s -> LOGGER.debug(">> CLEANUP (V3 only) <<")) + .doOnComplete(() -> LOGGER.debug("<< CLEANUP (V3 only) >>")) + .then() + .block(Duration.ofMinutes(30)); + return; + } + Flux.empty() .thenMany( Mono.when( // Before Routes @@ -218,7 +250,8 @@ void clean() { Mono.when( cleanApplicationsV3( this.cloudFoundryClient, - this.nameFactory), // After Routes, cannot run with + this.nameFactory, + true), // After Routes, cannot run with // other cleanApps cleanUsers(this.uaaClient, this.nameFactory) // After CF Users )) @@ -241,32 +274,43 @@ void clean() { } private static Flux cleanApplicationsV3( - CloudFoundryClient cloudFoundryClient, NameFactory nameFactory) { - return PaginationUtils.requestClientV3Resources( - page -> - cloudFoundryClient - .applicationsV3() - .list(ListApplicationsRequest.builder().page(page).build())) - .filter(application -> nameFactory.isApplicationName(application.getName())) - .delayUntil( - application -> - removeApplicationServiceBindings(cloudFoundryClient, application)) - .flatMap( - application -> - cloudFoundryClient - .applicationsV3() - .delete( - DeleteApplicationRequest.builder() - .applicationId(application.getId()) - .build()) - .then() - .doOnError( - t -> - LOGGER.error( - "Unable to delete V3 application" - + " {}", - application.getName(), - t))); + CloudFoundryClient cloudFoundryClient, NameFactory nameFactory, boolean runV2Calls) { + Flux apps = + PaginationUtils.requestClientV3Resources( + page -> + cloudFoundryClient + .applicationsV3() + .list( + ListApplicationsRequest.builder() + .page(page) + .build())) + .filter( + application -> + nameFactory.isApplicationName(application.getName())); + + if (runV2Calls) { + apps = + apps.delayUntil( + application -> + removeApplicationServiceBindings( + cloudFoundryClient, application)); + } + + return apps.flatMap( + application -> + cloudFoundryClient + .applicationsV3() + .delete( + DeleteApplicationRequest.builder() + .applicationId(application.getId()) + .build()) + .then() + .doOnError( + t -> + LOGGER.error( + "Unable to delete V3 application" + " {}", + application.getName(), + t))); } private static Flux cleanBuildpacks( diff --git a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java index da390ac2040..8a6a1ad4b62 100644 --- a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java +++ b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java @@ -86,6 +86,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; @@ -346,6 +347,7 @@ RandomNameFactory nameFactory() { @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") + @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) Mono metricRegistrarServiceInstance( CloudFoundryClient cloudFoundryClient, Mono spaceId, NameFactory nameFactory) { return spaceId.flatMap( @@ -373,6 +375,7 @@ NetworkingClient networkingClient( @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") + @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) Mono organizationId( CloudFoundryClient cloudFoundryClient, String organizationName, @@ -512,6 +515,7 @@ String serviceName(NameFactory nameFactory) { @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") + @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) Mono spaceId( CloudFoundryClient cloudFoundryClient, Mono organizationId, String spaceName) { return organizationId @@ -538,6 +542,7 @@ String spaceName(NameFactory nameFactory) { @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") + @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) Mono stackId(CloudFoundryClient cloudFoundryClient, Mono stackName) { return stackName .flux() @@ -566,6 +571,7 @@ Mono stackId(CloudFoundryClient cloudFoundryClient, Mono stackNa */ @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") + @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) Mono stackName(CloudFoundryClient cloudFoundryClient) { return PaginationUtils.requestClientV2Resources( page -> @@ -583,6 +589,7 @@ Mono stackName(CloudFoundryClient cloudFoundryClient) { @Lazy @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") + @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) Mono testLogCacheApp( CloudFoundryClient cloudFoundryClient, Mono spaceId, @@ -619,6 +626,7 @@ String testLogCacheAppName(NameFactory nameFactory) { @Lazy @Bean + @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) TestLogCacheEndpoints testLogCacheEndpoints( ConnectionContext connectionContext, TokenProvider tokenProvider, diff --git a/integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java b/integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java new file mode 100644 index 00000000000..acde38fb6bd --- /dev/null +++ b/integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java @@ -0,0 +1,72 @@ +/* + * Copyright 2026 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.cloudfoundry; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; + +/** + * Annotation to mark tests that require the V2 API. Tests annotated with this + * will be skipped if the environment variable {@code SKIP_V2_TESTS} is set to "true". + * + *

Usage: + *

+ * @RequiresV2Api
+ * public class MyV2Test extends AbstractIntegrationTest {
+ *     // ...
+ * }
+ * 
+ * + *

To skip V2 tests, set the environment variable: + *

+ * export SKIP_V2_TESTS=true
+ * 
+ */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@ExtendWith(RequiresV2Api.V2ApiCondition.class) +public @interface RequiresV2Api { + + /** + * JUnit 5 ExecutionCondition that checks if V2 tests should be skipped. + */ + class V2ApiCondition implements ExecutionCondition { + + private static final String SKIP_V2_TESTS_ENV = "SKIP_V2_TESTS"; + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + if ("true".equalsIgnoreCase(System.getenv(SKIP_V2_TESTS_ENV))) { + return ConditionEvaluationResult.disabled( + "V2 API tests are disabled via " + + SKIP_V2_TESTS_ENV + + " environment variable"); + } + return ConditionEvaluationResult.enabled("V2 API tests are enabled"); + } + } +} diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ApplicationsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ApplicationsTest.java index 9774568bd02..df19fe4c8a4 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ApplicationsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ApplicationsTest.java @@ -39,6 +39,7 @@ import org.cloudfoundry.CleanupCloudFoundryAfterClass; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.AbstractApplicationResource; import org.cloudfoundry.client.v2.applications.ApplicationEnvironmentRequest; @@ -98,6 +99,7 @@ import reactor.util.function.Tuple2; @CleanupCloudFoundryAfterClass +@RequiresV2Api public final class ApplicationsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/BlobstoresTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/BlobstoresTest.java index f9368a07307..223f55eb4ed 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/BlobstoresTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/BlobstoresTest.java @@ -19,6 +19,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.ApplicationUtils; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.blobstores.DeleteBlobstoreBuildpackCachesRequest; import org.cloudfoundry.util.JobUtils; @@ -27,6 +28,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class BlobstoresTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/BuildpacksTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/BuildpacksTest.java index 03b7d3f0e95..00afd83bcb9 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/BuildpacksTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/BuildpacksTest.java @@ -20,6 +20,7 @@ import java.nio.file.Path; import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.buildpacks.BuildpackEntity; import org.cloudfoundry.client.v2.buildpacks.BuildpackResource; @@ -40,6 +41,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class BuildpacksTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/DomainsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/DomainsTest.java index 676d130484f..8d4841222d7 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/DomainsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/DomainsTest.java @@ -23,6 +23,7 @@ import java.time.Duration; import java.util.function.Consumer; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; import org.cloudfoundry.client.v2.applications.CreateApplicationResponse; @@ -59,6 +60,7 @@ import reactor.util.function.Tuple2; @SuppressWarnings("deprecation") +@RequiresV2Api public final class DomainsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/EventsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/EventsTest.java index 76dcea594d2..d52358d9dbf 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/EventsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/EventsTest.java @@ -18,6 +18,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.events.EventResource; import org.cloudfoundry.client.v2.events.GetEventRequest; @@ -29,6 +30,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class EventsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/FeatureFlagsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/FeatureFlagsTest.java index d47962b5aa9..217bdd155a0 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/FeatureFlagsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/FeatureFlagsTest.java @@ -26,6 +26,7 @@ import java.util.Set; import java.util.stream.Collectors; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.featureflags.FeatureFlagEntity; import org.cloudfoundry.client.v2.featureflags.GetFeatureFlagRequest; @@ -38,6 +39,7 @@ import reactor.test.StepVerifier; import reactor.util.function.Tuples; +@RequiresV2Api public final class FeatureFlagsTest extends AbstractIntegrationTest { private static final List coreFeatureFlagNameList = diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/InfoTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/InfoTest.java index 471cb284e8a..a4395079a54 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/InfoTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/InfoTest.java @@ -22,12 +22,14 @@ import com.github.zafarkhaja.semver.Version; import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.info.GetInfoRequest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import reactor.test.StepVerifier; +@RequiresV2Api public final class InfoTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/JobsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/JobsTest.java index 0727b062d2e..950ae4e35ad 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/JobsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/JobsTest.java @@ -20,6 +20,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.jobs.GetJobRequest; import org.cloudfoundry.client.v2.organizations.CreateOrganizationRequest; @@ -31,6 +32,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class JobsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationQuotaDefinitionsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationQuotaDefinitionsTest.java index 8a435cfa81b..b99f91e3076 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationQuotaDefinitionsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationQuotaDefinitionsTest.java @@ -20,6 +20,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.organizationquotadefinitions.CreateOrganizationQuotaDefinitionRequest; import org.cloudfoundry.client.v2.organizationquotadefinitions.CreateOrganizationQuotaDefinitionResponse; @@ -37,6 +38,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class OrganizationQuotaDefinitionsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationsTest.java index e1d1762e649..1b31140d922 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationsTest.java @@ -22,6 +22,7 @@ import java.time.Duration; import java.util.function.UnaryOperator; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; import org.cloudfoundry.client.v2.applications.CreateApplicationResponse; @@ -98,13 +99,16 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class OrganizationsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; @Autowired private Mono organizationId; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/PrivateDomainsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/PrivateDomainsTest.java index 587cfa35aea..4dde9496a38 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/PrivateDomainsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/PrivateDomainsTest.java @@ -23,6 +23,7 @@ import java.time.Duration; import java.util.function.Consumer; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.organizations.AssociateOrganizationAuditorRequest; import org.cloudfoundry.client.v2.organizations.AssociateOrganizationAuditorResponse; @@ -57,6 +58,7 @@ import reactor.test.StepVerifier; import reactor.util.function.Tuple2; +@RequiresV2Api public final class PrivateDomainsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/RouteMappingsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/RouteMappingsTest.java index 1056e983040..9b31ddf78a8 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/RouteMappingsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/RouteMappingsTest.java @@ -22,6 +22,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; import org.cloudfoundry.client.v2.applications.CreateApplicationResponse; @@ -43,6 +44,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class RouteMappingsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/RoutesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/RoutesTest.java index 3ee56508931..cb974f35e6b 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/RoutesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/RoutesTest.java @@ -23,6 +23,7 @@ import java.time.Duration; import java.util.function.Consumer; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; import org.cloudfoundry.client.v2.applications.CreateApplicationResponse; @@ -53,6 +54,7 @@ import reactor.test.StepVerifier; import reactor.util.function.Tuple3; +@RequiresV2Api public final class RoutesTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/SecurityGroupsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/SecurityGroupsTest.java index 64ee5df01a8..ba249ceff2c 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/SecurityGroupsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/SecurityGroupsTest.java @@ -21,6 +21,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.securitygroups.AssociateSecurityGroupSpaceRequest; import org.cloudfoundry.client.v2.securitygroups.AssociateSecurityGroupSpaceResponse; @@ -55,6 +56,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class SecurityGroupsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBindingsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBindingsTest.java index 668976376d4..f596238704f 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBindingsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBindingsTest.java @@ -24,6 +24,7 @@ import java.util.Optional; import java.util.function.Consumer; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; import org.cloudfoundry.client.v2.applications.CreateApplicationResponse; @@ -49,6 +50,7 @@ import reactor.util.function.Tuple2; import reactor.util.function.Tuple3; +@RequiresV2Api public final class ServiceBindingsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBrokersTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBrokersTest.java index 214577e4a90..50be1ea1b52 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBrokersTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBrokersTest.java @@ -26,6 +26,7 @@ import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.ApplicationUtils; import org.cloudfoundry.CleanupCloudFoundryAfterClass; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.ServiceBrokerUtils; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.servicebrokers.CreateServiceBrokerRequest; @@ -45,13 +46,16 @@ import reactor.test.StepVerifier; @CleanupCloudFoundryAfterClass +@RequiresV2Api public final class ServiceBrokersTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; @Autowired private Mono organizationId; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceBrokerName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceInstancesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceInstancesTest.java index ed152f87a39..cad61ddbd58 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceInstancesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceInstancesTest.java @@ -24,6 +24,7 @@ import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; import org.cloudfoundry.client.v2.applications.CreateApplicationResponse; @@ -65,6 +66,7 @@ import reactor.test.StepVerifier; import reactor.util.function.Tuples; +@RequiresV2Api public final class ServiceInstancesTest extends AbstractIntegrationTest { private static final String DEFAULT_ROUTER_GROUP = "default-tcp"; @@ -75,7 +77,9 @@ public final class ServiceInstancesTest extends AbstractIntegrationTest { @Autowired private RoutingClient routingClient; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceKeysTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceKeysTest.java index 58067e0d31f..485e9ba5719 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceKeysTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceKeysTest.java @@ -20,6 +20,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.serviceinstances.CreateServiceInstanceRequest; import org.cloudfoundry.client.v2.serviceinstances.CreateServiceInstanceResponse; @@ -42,11 +43,14 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class ServiceKeysTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlanVisibilitiesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlanVisibilitiesTest.java index 910294d42ac..e2a9ecbece2 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlanVisibilitiesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlanVisibilitiesTest.java @@ -22,6 +22,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.ServiceBrokerUtils; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.organizations.CreateOrganizationRequest; @@ -47,6 +48,7 @@ import reactor.test.StepVerifier; import reactor.util.function.Tuples; +@RequiresV2Api public final class ServicePlanVisibilitiesTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlansTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlansTest.java index c8f4db7e148..e9fc66b8e8e 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlansTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlansTest.java @@ -22,6 +22,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.ServiceBrokerUtils; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; @@ -53,6 +54,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class ServicePlansTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; @@ -61,7 +63,9 @@ public final class ServicePlansTest extends AbstractIntegrationTest { @Autowired private String planName; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceUsageEventsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceUsageEventsTest.java index 987de74b28b..32703e319e4 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceUsageEventsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceUsageEventsTest.java @@ -21,6 +21,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.NameFactory; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.serviceinstances.CreateServiceInstanceRequest; import org.cloudfoundry.client.v2.serviceinstances.CreateServiceInstanceResponse; @@ -40,11 +41,14 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class ServiceUsageEventsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicesTest.java index 9af396d3159..1469bfdd361 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicesTest.java @@ -22,6 +22,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.ServiceBrokerUtils; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.serviceinstances.CreateServiceInstanceRequest; @@ -46,6 +47,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class ServicesTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; @@ -54,7 +56,9 @@ public final class ServicesTest extends AbstractIntegrationTest { @Autowired private String planName; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/SharedDomainsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/SharedDomainsTest.java index 063992a6574..bf606542523 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/SharedDomainsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/SharedDomainsTest.java @@ -19,6 +19,7 @@ import java.time.Duration; import java.util.Optional; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.shareddomains.CreateSharedDomainRequest; import org.cloudfoundry.client.v2.shareddomains.CreateSharedDomainResponse; @@ -37,6 +38,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class SharedDomainsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/SpaceQuotaDefinitionsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/SpaceQuotaDefinitionsTest.java index 47c9ae0f5f3..ebe8ca1b618 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/SpaceQuotaDefinitionsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/SpaceQuotaDefinitionsTest.java @@ -20,6 +20,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; import org.cloudfoundry.client.v2.applications.CreateApplicationResponse; @@ -48,6 +49,7 @@ import reactor.test.StepVerifier; import reactor.util.function.Tuples; +@RequiresV2Api public final class SpaceQuotaDefinitionsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/SpacesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/SpacesTest.java index 4193ec53d6e..eae93b616bb 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/SpacesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/SpacesTest.java @@ -27,6 +27,7 @@ import java.util.function.Function; import java.util.function.UnaryOperator; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.ApplicationResource; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; @@ -116,13 +117,16 @@ import reactor.test.StepVerifier; import reactor.util.function.Tuple2; +@RequiresV2Api public final class SpacesTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; @Autowired private Mono organizationId; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/StacksTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/StacksTest.java index cbd3ac2d296..3360a86a3f5 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/StacksTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/StacksTest.java @@ -20,6 +20,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.stacks.CreateStackRequest; import org.cloudfoundry.client.v2.stacks.CreateStackResponse; @@ -38,6 +39,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class StacksTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/UserProvidedServicesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/UserProvidedServicesTest.java index 555741d6340..a850b861418 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/UserProvidedServicesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/UserProvidedServicesTest.java @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.function.Consumer; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; import org.cloudfoundry.client.v2.applications.CreateApplicationResponse; @@ -56,6 +57,7 @@ import reactor.util.function.Tuple3; import reactor.util.function.Tuples; +@RequiresV2Api public final class UserProvidedServicesTest extends AbstractIntegrationTest { private static final String DEFAULT_ROUTER_GROUP = "default-tcp"; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/UsersTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/UsersTest.java index 27f1232c3d0..08efb1965e8 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/UsersTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/UsersTest.java @@ -20,6 +20,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; import org.cloudfoundry.client.v2.applications.CreateApplicationResponse; @@ -80,6 +81,7 @@ import reactor.test.StepVerifier; import reactor.util.function.Tuples; +@RequiresV2Api public final class UsersTest extends AbstractIntegrationTest { private static final String STATUS_FILTER = "active"; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/AdminTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/AdminTest.java index d185f15deac..bdbc6778c87 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/AdminTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/AdminTest.java @@ -21,6 +21,7 @@ import org.cloudfoundry.ApplicationUtils; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.admin.ClearBuildpackCacheRequest; import org.cloudfoundry.util.JobUtils; @@ -29,6 +30,8 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api +// TODO Does it really require V2? public final class AdminTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/DeploymentsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/DeploymentsTest.java index d823ad7b1c1..bcec4978420 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/DeploymentsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/DeploymentsTest.java @@ -25,6 +25,7 @@ import org.cloudfoundry.CleanupCloudFoundryAfterClass; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.applications.GetApplicationCurrentDropletRequest; import org.cloudfoundry.client.v3.applications.GetApplicationCurrentDropletResponse; @@ -52,6 +53,7 @@ import reactor.test.StepVerifier; @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_2_4) +@RequiresV2Api // Due to ApplicationUtils @CleanupCloudFoundryAfterClass public final class DeploymentsTest extends AbstractIntegrationTest { diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/IsolationSegmentsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/IsolationSegmentsTest.java index 0f0a56fc1cd..580fb302146 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/IsolationSegmentsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/IsolationSegmentsTest.java @@ -22,6 +22,7 @@ import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.organizations.CreateOrganizationRequest; import org.cloudfoundry.client.v2.organizations.CreateOrganizationResponse; @@ -53,6 +54,7 @@ import reactor.test.StepVerifier; @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_1_11) +@RequiresV2Api public final class IsolationSegmentsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/OrganizationsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/OrganizationsTest.java index a1fbd52f3df..e3da7d85e66 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/OrganizationsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/OrganizationsTest.java @@ -24,6 +24,7 @@ import org.cloudfoundry.ApplicationUtils; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.domains.CreateDomainRequest; import org.cloudfoundry.client.v3.domains.CreateDomainResponse; @@ -57,6 +58,7 @@ import reactor.test.StepVerifier; @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_1_12) +@RequiresV2Api public final class OrganizationsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ProcessesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ProcessesTest.java index e4a4184e85a..8e3cbba3cba 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ProcessesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ProcessesTest.java @@ -25,6 +25,7 @@ import org.cloudfoundry.CleanupCloudFoundryAfterClass; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.applications.GetApplicationProcessRequest; import org.cloudfoundry.client.v3.applications.GetApplicationProcessResponse; @@ -43,6 +44,7 @@ import reactor.test.StepVerifier; @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_2_0) +@RequiresV2Api // Due to ApplicationUtils @CleanupCloudFoundryAfterClass public final class ProcessesTest extends AbstractIntegrationTest { diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBindingsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBindingsTest.java index 81477aef522..acdb96f1e94 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBindingsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBindingsTest.java @@ -25,6 +25,7 @@ import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.servicebindings.CreateServiceBindingRequest; import org.cloudfoundry.client.v3.servicebindings.DeleteServiceBindingRequest; @@ -54,11 +55,14 @@ import reactor.test.StepVerifier; @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_2_11) +@RequiresV2Api public class ServiceBindingsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBrokersTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBrokersTest.java index 656a0b0efe6..07e0b219cfc 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBrokersTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBrokersTest.java @@ -28,6 +28,7 @@ import org.cloudfoundry.CleanupCloudFoundryAfterClass; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.ServiceBrokerUtils; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.servicebrokers.BasicAuthentication; @@ -50,6 +51,7 @@ import reactor.test.StepVerifier; @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_2_10) +@RequiresV2Api @CleanupCloudFoundryAfterClass public final class ServiceBrokersTest extends AbstractIntegrationTest { @@ -57,7 +59,9 @@ public final class ServiceBrokersTest extends AbstractIntegrationTest { @Autowired private Mono organizationId; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceBrokerName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceInstancesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceInstancesTest.java index 507b288a653..941c0e56169 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceInstancesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceInstancesTest.java @@ -25,6 +25,7 @@ import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.serviceinstances.CreateServiceInstanceRequest; import org.cloudfoundry.client.v3.serviceinstances.CreateServiceInstanceResponse; @@ -57,13 +58,16 @@ import reactor.test.StepVerifier; @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_2_1) +@RequiresV2Api public final class ServiceInstancesTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; @Autowired private Mono organizationId; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceOfferingsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceOfferingsTest.java index f0b67a37b46..20334935909 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceOfferingsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceOfferingsTest.java @@ -24,6 +24,7 @@ import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.ServiceBrokerUtils; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.serviceofferings.DeleteServiceOfferingRequest; @@ -43,13 +44,16 @@ import reactor.test.StepVerifier; @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_2_10) +@RequiresV2Api public final class ServiceOfferingsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; @Autowired private Mono organizationId; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServicePlansTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServicePlansTest.java index 5e37753b66b..7f5f0383945 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServicePlansTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServicePlansTest.java @@ -24,6 +24,7 @@ import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.ServiceBrokerUtils; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.serviceplans.DeleteServicePlanRequest; @@ -45,6 +46,7 @@ import reactor.test.StepVerifier; @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_2_10) +@RequiresV2Api public final class ServicePlansTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; @@ -53,7 +55,9 @@ public final class ServicePlansTest extends AbstractIntegrationTest { @Autowired private String planName; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Test public void delete() { diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/TasksTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/TasksTest.java index 0e3fdada8ce..ec5970a08bb 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/TasksTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/TasksTest.java @@ -25,6 +25,7 @@ import org.cloudfoundry.CleanupCloudFoundryAfterClass; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.applications.ApplicationResource; import org.cloudfoundry.client.v3.applications.GetApplicationCurrentDropletRequest; @@ -52,6 +53,7 @@ @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_1_12) @CleanupCloudFoundryAfterClass +@RequiresV2Api // Due to ApplicationUtils public final class TasksTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/AdvancedTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/AdvancedTest.java index 733e95d6bc9..201b9a49883 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/AdvancedTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/AdvancedTest.java @@ -20,10 +20,12 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import reactor.test.StepVerifier; +@RequiresV2Api public final class AdvancedTest extends AbstractIntegrationTest { @Autowired private CloudFoundryOperations cloudFoundryOperations; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java index 37c701dbbe5..04a2e3c5674 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java @@ -29,6 +29,7 @@ import org.cloudfoundry.CleanupCloudFoundryAfterClass; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.operations.applications.ApplicationDetail; import org.cloudfoundry.operations.applications.ApplicationEnvironments; @@ -88,6 +89,7 @@ import reactor.test.StepVerifier; @CleanupCloudFoundryAfterClass +@RequiresV2Api public final class ApplicationsTest extends AbstractIntegrationTest { private static final String DEFAULT_ROUTER_GROUP = "default-tcp"; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/BuildpacksTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/BuildpacksTest.java index 08b1dfcc243..fb9026d6fda 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/BuildpacksTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/BuildpacksTest.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.operations.buildpacks.Buildpack; import org.cloudfoundry.operations.buildpacks.CreateBuildpackRequest; import org.cloudfoundry.operations.buildpacks.DeleteBuildpackRequest; @@ -31,6 +32,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class BuildpacksTest extends AbstractIntegrationTest { @Autowired private CloudFoundryOperations cloudFoundryOperations; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/DomainsTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/DomainsTest.java index f56d7c777b9..87fd783ebf5 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/DomainsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/DomainsTest.java @@ -22,6 +22,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.ClientV2Exception; import org.cloudfoundry.client.v3.domains.GetDomainRequest; @@ -38,6 +39,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class DomainsTest extends AbstractIntegrationTest { private static final String DEFAULT_ROUTER_GROUP = "default-tcp"; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/NetworkPoliciesTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/NetworkPoliciesTest.java index 1643a3ef4f8..1d32a910a2d 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/NetworkPoliciesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/NetworkPoliciesTest.java @@ -20,6 +20,7 @@ import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.applications.CreateApplicationRequest; import org.cloudfoundry.client.v2.applications.CreateApplicationResponse; @@ -34,6 +35,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class NetworkPoliciesTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/OrganizationAdminTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/OrganizationAdminTest.java index 35186836804..4a4325d1914 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/OrganizationAdminTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/OrganizationAdminTest.java @@ -20,6 +20,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.operations.organizationadmin.CreateQuotaRequest; import org.cloudfoundry.operations.organizationadmin.DeleteQuotaRequest; import org.cloudfoundry.operations.organizationadmin.GetQuotaRequest; @@ -33,6 +34,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class OrganizationAdminTest extends AbstractIntegrationTest { @Autowired private CloudFoundryOperations cloudFoundryOperations; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/OrganizationsTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/OrganizationsTest.java index 3e4e2b57a63..ebe3f90ebe9 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/OrganizationsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/OrganizationsTest.java @@ -18,12 +18,14 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.operations.organizations.CreateOrganizationRequest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class OrganizationsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryOperations cloudFoundryOperations; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/RoutesTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/RoutesTest.java index 19db1a53b1a..47a37e3fb91 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/RoutesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/RoutesTest.java @@ -28,6 +28,7 @@ import java.util.function.Predicate; import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.CleanupCloudFoundryAfterClass; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.operations.applications.ApplicationHealthCheck; import org.cloudfoundry.operations.applications.PushApplicationRequest; import org.cloudfoundry.operations.domains.CreateDomainRequest; @@ -51,6 +52,7 @@ import reactor.test.StepVerifier; @CleanupCloudFoundryAfterClass +@RequiresV2Api public final class RoutesTest extends AbstractIntegrationTest { private static final String DEFAULT_ROUTER_GROUP = "default-tcp"; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/ServiceAdminTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/ServiceAdminTest.java index 7a8f1ec3787..ebd89c92e3f 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/ServiceAdminTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/ServiceAdminTest.java @@ -22,6 +22,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.CleanupCloudFoundryAfterClass; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.ServiceBrokerUtils; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.spaces.CreateSpaceRequest; @@ -40,6 +41,7 @@ import reactor.test.StepVerifier; @CleanupCloudFoundryAfterClass +@RequiresV2Api public final class ServiceAdminTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/ServicesTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/ServicesTest.java index 520027128be..32b8cb4e687 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/ServicesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/ServicesTest.java @@ -24,6 +24,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.CleanupCloudFoundryAfterClass; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.servicebindings.ListServiceBindingsRequest; import org.cloudfoundry.client.v2.servicebindings.ServiceBindingResource; @@ -66,6 +67,7 @@ import reactor.test.StepVerifier; @CleanupCloudFoundryAfterClass +@RequiresV2Api public final class ServicesTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; @@ -76,7 +78,9 @@ public final class ServicesTest extends AbstractIntegrationTest { @Autowired private String planName; - @Autowired private Mono serviceBrokerId; + // Optional: bean requires V2 API; class is guarded by @RequiresV2Api + @Autowired(required = false) + private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/SpacesTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/SpacesTest.java index fbb8dc765b3..7f862e04784 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/SpacesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/SpacesTest.java @@ -20,6 +20,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.operations.spaces.CreateSpaceRequest; import org.cloudfoundry.operations.spaces.GetSpaceRequest; import org.cloudfoundry.operations.spaces.SpaceDetail; @@ -27,6 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired; import reactor.test.StepVerifier; +@RequiresV2Api public final class SpacesTest extends AbstractIntegrationTest { @Autowired private CloudFoundryOperations cloudFoundryOperations; diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/StacksTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/StacksTest.java new file mode 100644 index 00000000000..e69de29bb2d diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/UserAdminTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/UserAdminTest.java index b0c12b8ea3f..af534acda39 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/UserAdminTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/UserAdminTest.java @@ -20,6 +20,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.organizations.ListOrganizationAuditorsRequest; import org.cloudfoundry.client.v2.organizations.ListOrganizationsRequest; @@ -47,6 +48,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresV2Api public final class UserAdminTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; From b56ad0cf00119cf7f8f03265156df5f313d05173 Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Fri, 20 Feb 2026 16:58:02 +0100 Subject: [PATCH 02/14] Add ability to skip tests that require TCP routing --- README.md | 1 + .../org/cloudfoundry/RequiresTcpRouting.java | 77 +++++++++++++++++++ .../operations/ApplicationsTest.java | 5 ++ .../routing/v1/RouterGroupsTest.java | 2 + .../routing/v1/TcpRoutesTest.java | 2 + 5 files changed, 87 insertions(+) create mode 100644 integration-test/src/test/java/org/cloudfoundry/RequiresTcpRouting.java diff --git a/README.md b/README.md index 5b4b1fad713..3b1ebbfd1dc 100644 --- a/README.md +++ b/README.md @@ -353,6 +353,7 @@ Name | Description `TEST_PROXY_PORT` | _(Optional)_ The port of a proxy to route all requests through. Defaults to `8080`. `TEST_PROXY_USERNAME` | _(Optional)_ The username for a proxy to route all requests through `TEST_SKIPSSLVALIDATION` | _(Optional)_ Whether to skip SSL validation when connecting to the Cloud Foundry instance. Defaults to `false`. +`SKIP_TCP_ROUTING_TESTS` | _(Optional)_ Set to `true` to skip TCP routing integration tests (TcpRoutesTest, RouterGroupsTest). Useful when the Cloud Foundry instance does not have TCP routing configured (i.e., no `routing_endpoint` in the info payload). Defaults to `false`. `SKIP_V2_TESTS` | _(Optional)_ Set to `true` to skip all V2 API integration tests. Useful when the Cloud Foundry V2 API is rate-limited or unavailable. When enabled, tests annotated with `@RequiresV2Api` will be skipped, including V3 tests that depend on V2 API calls (e.g., service broker creation). Defaults to `false`. If you do not have access to a CloudFoundry instance with admin access, you can run one locally using [bosh-deployment](https://github.com/cloudfoundry/bosh-deployment) & [cf-deployment](https://github.com/cloudfoundry/cf-deployment/) and Virtualbox. diff --git a/integration-test/src/test/java/org/cloudfoundry/RequiresTcpRouting.java b/integration-test/src/test/java/org/cloudfoundry/RequiresTcpRouting.java new file mode 100644 index 00000000000..0ee45aee62c --- /dev/null +++ b/integration-test/src/test/java/org/cloudfoundry/RequiresTcpRouting.java @@ -0,0 +1,77 @@ +/* + * Copyright 2026 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.cloudfoundry; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; + +/** + * Annotation to mark tests that require TCP routing to be configured. + * + *

Tests annotated with this (or test classes containing this annotation) + * will be skipped if the {@code SKIP_TCP_ROUTING_TESTS} environment variable + * is set to "true". + * + *

Use this when your Cloud Foundry instance does not have TCP routing + * configured (i.e., when the info payload does not contain a 'routing_endpoint' key). + * + *

Example usage: + *

+ * @RequiresTcpRouting
+ * public class TcpRoutesTest extends AbstractIntegrationTest {
+ *     // tests that require TCP routing
+ * }
+ * 
+ */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@ExtendWith(RequiresTcpRouting.SkipTcpRoutingCondition.class) +public @interface RequiresTcpRouting { + + /** + * JUnit 5 ExecutionCondition that checks if tcp routing tests should be skipped. + */ + class SkipTcpRoutingCondition implements ExecutionCondition { + + private static final String ENV_VAR = "SKIP_TCP_ROUTING_TESTS"; + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + String envValue = System.getenv(ENV_VAR); + + if ("true".equalsIgnoreCase(envValue)) { + return ConditionEvaluationResult.disabled( + "TCP routing tests are disabled via " + + ENV_VAR + + " environment variable" + + ". TCP routing may not be configured on the target CF instance."); + } + + return ConditionEvaluationResult.enabled("TCP routing tests are enabled"); + } + } +} diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java index 04a2e3c5674..43f65276114 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java @@ -29,6 +29,7 @@ import org.cloudfoundry.CleanupCloudFoundryAfterClass; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresTcpRouting; import org.cloudfoundry.RequiresV2Api; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.operations.applications.ApplicationDetail; @@ -352,6 +353,7 @@ public void getManifest() throws IOException { } @Test + @RequiresTcpRouting public void getManifestForTcpRoute() throws IOException { String applicationName = this.nameFactory.getApplicationName(); @@ -438,6 +440,7 @@ public void getStopped() throws IOException { } @Test + @RequiresTcpRouting public void getTcp() throws IOException { String applicationName = this.nameFactory.getApplicationName(); String domainName = this.nameFactory.getDomainName(); @@ -1142,6 +1145,7 @@ public void pushRoutePath() throws IOException { } @Test + @RequiresTcpRouting public void pushTcpRoute() throws IOException { String applicationName = this.nameFactory.getApplicationName(); String domainName = this.nameFactory.getDomainName(); @@ -1265,6 +1269,7 @@ public void pushUpdateRoute() throws IOException { } @Test + @RequiresTcpRouting public void pushUpdateTcpRoute() throws IOException { String applicationName = this.nameFactory.getApplicationName(); String domainName = this.nameFactory.getDomainName(); diff --git a/integration-test/src/test/java/org/cloudfoundry/routing/v1/RouterGroupsTest.java b/integration-test/src/test/java/org/cloudfoundry/routing/v1/RouterGroupsTest.java index 8253f29ad5a..7a812c7e262 100644 --- a/integration-test/src/test/java/org/cloudfoundry/routing/v1/RouterGroupsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/routing/v1/RouterGroupsTest.java @@ -18,6 +18,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresTcpRouting; import org.cloudfoundry.routing.RoutingClient; import org.cloudfoundry.routing.v1.routergroups.ListRouterGroupsRequest; import org.cloudfoundry.routing.v1.routergroups.ListRouterGroupsResponse; @@ -29,6 +30,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +@RequiresTcpRouting public final class RouterGroupsTest extends AbstractIntegrationTest { private static final String DEFAULT_ROUTER_GROUP = "default-tcp"; diff --git a/integration-test/src/test/java/org/cloudfoundry/routing/v1/TcpRoutesTest.java b/integration-test/src/test/java/org/cloudfoundry/routing/v1/TcpRoutesTest.java index a562fa42232..6fb7af061b0 100644 --- a/integration-test/src/test/java/org/cloudfoundry/routing/v1/TcpRoutesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/routing/v1/TcpRoutesTest.java @@ -19,6 +19,7 @@ import java.time.Duration; import org.cloudfoundry.AbstractIntegrationTest; import org.cloudfoundry.NameFactory; +import org.cloudfoundry.RequiresTcpRouting; import org.cloudfoundry.routing.RoutingClient; import org.cloudfoundry.routing.v1.routergroups.ListRouterGroupsRequest; import org.cloudfoundry.routing.v1.routergroups.ListRouterGroupsResponse; @@ -39,6 +40,7 @@ import reactor.test.StepVerifier; import reactor.util.retry.Retry; +@RequiresTcpRouting public final class TcpRoutesTest extends AbstractIntegrationTest { private static final String DEFAULT_ROUTER_GROUP = "default-tcp"; From 8cf89171544be9bce92a6e26fe999ea94fd378af Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Mon, 23 Feb 2026 17:27:54 +0100 Subject: [PATCH 03/14] Allow skipping tests tha require browser auth Some UAA do not return a Location header. --- README.md | 1 + .../org/cloudfoundry/RequiresBrowserAuth.java | 74 +++++++++++++++++++ .../cloudfoundry/uaa/AuthorizationsTest.java | 7 ++ 3 files changed, 82 insertions(+) create mode 100644 integration-test/src/test/java/org/cloudfoundry/RequiresBrowserAuth.java diff --git a/README.md b/README.md index 3b1ebbfd1dc..e9bbbe5f1b9 100644 --- a/README.md +++ b/README.md @@ -353,6 +353,7 @@ Name | Description `TEST_PROXY_PORT` | _(Optional)_ The port of a proxy to route all requests through. Defaults to `8080`. `TEST_PROXY_USERNAME` | _(Optional)_ The username for a proxy to route all requests through `TEST_SKIPSSLVALIDATION` | _(Optional)_ Whether to skip SSL validation when connecting to the Cloud Foundry instance. Defaults to `false`. +`SKIP_BROWSER_AUTH_TESTS` | _(Optional)_ Set to `true` to skip integration tests that require browser-based authentication (e.g., SSO tests). Useful when the Cloud Foundry instance does not support browser-based authentication or when running tests in a non-interactive environment. Defaults to `false`. `SKIP_TCP_ROUTING_TESTS` | _(Optional)_ Set to `true` to skip TCP routing integration tests (TcpRoutesTest, RouterGroupsTest). Useful when the Cloud Foundry instance does not have TCP routing configured (i.e., no `routing_endpoint` in the info payload). Defaults to `false`. `SKIP_V2_TESTS` | _(Optional)_ Set to `true` to skip all V2 API integration tests. Useful when the Cloud Foundry V2 API is rate-limited or unavailable. When enabled, tests annotated with `@RequiresV2Api` will be skipped, including V3 tests that depend on V2 API calls (e.g., service broker creation). Defaults to `false`. diff --git a/integration-test/src/test/java/org/cloudfoundry/RequiresBrowserAuth.java b/integration-test/src/test/java/org/cloudfoundry/RequiresBrowserAuth.java new file mode 100644 index 00000000000..d675dd63242 --- /dev/null +++ b/integration-test/src/test/java/org/cloudfoundry/RequiresBrowserAuth.java @@ -0,0 +1,74 @@ +/* + * Copyright 2026 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.cloudfoundry; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; + +/** + * Annotation to mark tests that require browser-based authentication (e.g., OAuth + * authorization code grants, implicit grants). Tests annotated with this will be skipped + * if the environment variable {@code SKIP_BROWSER_AUTH_TESTS} is set to "true". + * + *

Usage: + *

+ * @RequiresBrowserAuth
+ * public class MyAuthTest extends AbstractIntegrationTest {
+ *     // ...
+ * }
+ * 
+ * + *

To skip browser auth tests, set the environment variable: + *

+ * export SKIP_BROWSER_AUTH_TESTS=true
+ * 
+ */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@ExtendWith(RequiresBrowserAuth.BrowserAuthCondition.class) +public @interface RequiresBrowserAuth { + + /** + * JUnit 5 ExecutionCondition that checks if Browser Auth tests should be skipped. + */ + class BrowserAuthCondition implements ExecutionCondition { + + private static final String SKIP_BROWSER_AUTH_ENV = "SKIP_BROWSER_AUTH_TESTS"; + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + if ("true".equalsIgnoreCase(System.getenv(SKIP_BROWSER_AUTH_ENV))) { + return ConditionEvaluationResult.disabled( + "Tests requiring Browser Authentication are disabled via " + + SKIP_BROWSER_AUTH_ENV + + " environment variable"); + } + + return ConditionEvaluationResult.enabled("Browser authentication tests are enabled"); + } + } +} diff --git a/integration-test/src/test/java/org/cloudfoundry/uaa/AuthorizationsTest.java b/integration-test/src/test/java/org/cloudfoundry/uaa/AuthorizationsTest.java index 6480aef0b9c..e0eac2d2149 100644 --- a/integration-test/src/test/java/org/cloudfoundry/uaa/AuthorizationsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/uaa/AuthorizationsTest.java @@ -21,6 +21,7 @@ import java.time.Duration; import java.util.function.Consumer; import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.RequiresBrowserAuth; import org.cloudfoundry.uaa.authorizations.AuthorizeByAuthorizationCodeGrantApiRequest; import org.cloudfoundry.uaa.authorizations.AuthorizeByAuthorizationCodeGrantBrowserRequest; import org.cloudfoundry.uaa.authorizations.AuthorizeByAuthorizationCodeGrantHybridRequest; @@ -55,6 +56,7 @@ public void authorizeByAuthorizationCodeGrantApi() { } @Test + @RequiresBrowserAuth public void authorizeByAuthorizationCodeGrantBrowser() { this.uaaClient .authorizations() @@ -70,6 +72,7 @@ public void authorizeByAuthorizationCodeGrantBrowser() { } @Test + @RequiresBrowserAuth public void authorizeByAuthorizationCodeGrantHybrid() { this.uaaClient .authorizations() @@ -85,6 +88,7 @@ public void authorizeByAuthorizationCodeGrantHybrid() { } @Test + @RequiresBrowserAuth public void authorizeByImplicitGrantBrowser() { this.uaaClient .authorizations() @@ -100,6 +104,7 @@ public void authorizeByImplicitGrantBrowser() { } @Test + @RequiresBrowserAuth public void authorizeByOpenIdWithAuthorizationCodeGrant() { this.uaaClient .authorizations() @@ -116,6 +121,7 @@ public void authorizeByOpenIdWithAuthorizationCodeGrant() { } @Test + @RequiresBrowserAuth public void authorizeByOpenIdWithIdToken() { this.uaaClient .authorizations() @@ -132,6 +138,7 @@ public void authorizeByOpenIdWithIdToken() { } @Test + @RequiresBrowserAuth public void authorizeByOpenIdWithImplicitGrant() { this.uaaClient .authorizations() From c431ba6ae624eaf989b0dc97cfd4f4357815aa91 Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Mon, 23 Feb 2026 17:37:47 +0100 Subject: [PATCH 04/14] Only run very basic LogCacheTest when V2 is missing --- .../org/cloudfoundry/logcache/v1/LogCacheTest.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java b/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java index 414af210bde..56190b818e4 100644 --- a/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java @@ -29,6 +29,7 @@ import org.cloudfoundry.ApplicationUtils; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresV2Api; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -43,13 +44,15 @@ public class LogCacheTest extends AbstractIntegrationTest { private ApplicationUtils.ApplicationMetadata testLogCacheAppMetadata; - @Autowired private TestLogCacheEndpoints testLogCacheEndpoints; + @Autowired(required = false) private TestLogCacheEndpoints testLogCacheEndpoints; private final Random random = new SecureRandom(); @BeforeEach - void setUp(@Autowired Mono testLogCacheApp) { - this.testLogCacheAppMetadata = testLogCacheApp.block(); + void setUp(@Autowired(required = false) Mono testLogCacheApp) { + if (testLogCacheApp != null) { + this.testLogCacheAppMetadata = testLogCacheApp.block(); + } } @Test @@ -68,6 +71,7 @@ public void info() { } @Test + @RequiresV2Api public void meta() { this.logCacheClient .meta(MetaRequest.builder().build()) @@ -83,6 +87,7 @@ public void meta() { } @Test + @RequiresV2Api public void readCounter() { final String name = this.nameFactory.getName("counter-"); final int delta = this.random.nextInt(1000); @@ -102,6 +107,7 @@ public void readCounter() { } @Test + @RequiresV2Api public void readEvent() { final String title = this.nameFactory.getName("event-"); final String body = "This is the body. " + new BigInteger(1024, this.random).toString(32); @@ -117,6 +123,7 @@ public void readEvent() { @Test @Disabled("fails often for no reasons") + @RequiresV2Api public void readGauge() { final String gaugeName = this.nameFactory.getName("gauge-"); final Double value = this.random.nextDouble() % 100; @@ -138,6 +145,7 @@ public void readGauge() { } @Test + @RequiresV2Api public void readLogs() { final String logMessage = this.nameFactory.getName("log-"); From 2957b014fef3f8c01318f8de89269cb3a0e3b347 Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Thu, 26 Feb 2026 09:13:28 +0100 Subject: [PATCH 05/14] Support skipping tests requiring metric registrar --- README.md | 1 + .../cloudfoundry/RequiresMetricRegistrar.java | 74 +++++++++++++++++++ .../logcache/v1/LogCacheTest.java | 18 ++++- 3 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 integration-test/src/test/java/org/cloudfoundry/RequiresMetricRegistrar.java diff --git a/README.md b/README.md index e9bbbe5f1b9..7e516ec5416 100644 --- a/README.md +++ b/README.md @@ -354,6 +354,7 @@ Name | Description `TEST_PROXY_USERNAME` | _(Optional)_ The username for a proxy to route all requests through `TEST_SKIPSSLVALIDATION` | _(Optional)_ Whether to skip SSL validation when connecting to the Cloud Foundry instance. Defaults to `false`. `SKIP_BROWSER_AUTH_TESTS` | _(Optional)_ Set to `true` to skip integration tests that require browser-based authentication (e.g., SSO tests). Useful when the Cloud Foundry instance does not support browser-based authentication or when running tests in a non-interactive environment. Defaults to `false`. +`SKIP_METRIC_REGISTRAR_TESTS` | _(Optional)_ Set to `true` to skip integration tests that require the Metric Registrar service (e.g., MetricRegistrarTest). Useful when the Cloud Foundry instance does not have the Metric Registrar service available. Defaults to `false`. `SKIP_TCP_ROUTING_TESTS` | _(Optional)_ Set to `true` to skip TCP routing integration tests (TcpRoutesTest, RouterGroupsTest). Useful when the Cloud Foundry instance does not have TCP routing configured (i.e., no `routing_endpoint` in the info payload). Defaults to `false`. `SKIP_V2_TESTS` | _(Optional)_ Set to `true` to skip all V2 API integration tests. Useful when the Cloud Foundry V2 API is rate-limited or unavailable. When enabled, tests annotated with `@RequiresV2Api` will be skipped, including V3 tests that depend on V2 API calls (e.g., service broker creation). Defaults to `false`. diff --git a/integration-test/src/test/java/org/cloudfoundry/RequiresMetricRegistrar.java b/integration-test/src/test/java/org/cloudfoundry/RequiresMetricRegistrar.java new file mode 100644 index 00000000000..c70d21dfe25 --- /dev/null +++ b/integration-test/src/test/java/org/cloudfoundry/RequiresMetricRegistrar.java @@ -0,0 +1,74 @@ +/* + * Copyright 2026 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.cloudfoundry; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; + +/** + * Annotation to mark tests that require the Metric Registrar service to be available. + * Tests annotated with this will be skipped if the environment variable + * {@code SKIP_METRIC_REGISTRAR_TESTS} is set to "true". + * + *

Usage: + *

+ * @RequiresMetricRegistrar
+ * public class MetricTest extends AbstractIntegrationTest {
+ *     // ...
+ * }
+ * 
+ * + *

To skip metric registrar tests, set the environment variable: + *

+ * export SKIP_METRIC_REGISTRAR_TESTS=true
+ * 
+ */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@ExtendWith(RequiresMetricRegistrar.RegistrarCondition.class) +public @interface RequiresMetricRegistrar { + + /** + * JUnit 5 ExecutionCondition that checks if Metric Registrar tests should be skipped. + */ + class RegistrarCondition implements ExecutionCondition { + + private static final String SKIP_REGISTRAR_ENV = "SKIP_METRIC_REGISTRAR_TESTS"; + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + if ("true".equalsIgnoreCase(System.getenv(SKIP_REGISTRAR_ENV))) { + return ConditionEvaluationResult.disabled( + "Tests requiring Metric Registrar Service are disabled via " + + SKIP_REGISTRAR_ENV + + " environment variable."); + } + + return ConditionEvaluationResult.enabled("Metric Registrar tests are enabled"); + } + } +} diff --git a/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java b/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java index 56190b818e4..eb53f391235 100644 --- a/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java @@ -29,6 +29,7 @@ import org.cloudfoundry.ApplicationUtils; import org.cloudfoundry.CloudFoundryVersion; import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.RequiresMetricRegistrar; import org.cloudfoundry.RequiresV2Api; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; @@ -44,12 +45,23 @@ public class LogCacheTest extends AbstractIntegrationTest { private ApplicationUtils.ApplicationMetadata testLogCacheAppMetadata; - @Autowired(required = false) private TestLogCacheEndpoints testLogCacheEndpoints; + // Optional: only available when V2 API is enabled (requires deployed test app) + @Autowired(required = false) + private TestLogCacheEndpoints testLogCacheEndpoints; private final Random random = new SecureRandom(); + /** + * Sets up the test log cache app metadata. The testLogCacheApp bean is optional + * ({@code required = false}) because it depends on V2 API calls for app deployment. + * When SKIP_V2_TESTS=true, this bean won't be available and setUp becomes a no-op. + * Tests that need testLogCacheAppMetadata are annotated with {@code @RequiresV2Api} + * and will be skipped in that case. + */ @BeforeEach - void setUp(@Autowired(required = false) Mono testLogCacheApp) { + void setUp( + @Autowired(required = false) + Mono testLogCacheApp) { if (testLogCacheApp != null) { this.testLogCacheAppMetadata = testLogCacheApp.block(); } @@ -88,6 +100,7 @@ public void meta() { @Test @RequiresV2Api + @RequiresMetricRegistrar public void readCounter() { final String name = this.nameFactory.getName("counter-"); final int delta = this.random.nextInt(1000); @@ -108,6 +121,7 @@ public void readCounter() { @Test @RequiresV2Api + @RequiresMetricRegistrar public void readEvent() { final String title = this.nameFactory.getName("event-"); final String body = "This is the body. " + new BigInteger(1024, this.random).toString(32); From 5918572d1346ea5c2e07497dc03fc766833035a7 Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Fri, 17 Apr 2026 16:05:30 +0200 Subject: [PATCH 06/14] Guard serviceBrokerId with @ConditionalOnProperty Prevent the serviceBrokerId bean from being created when SKIP_V2_TESTS=true, rather than relying on @Autowired(required=false) in each test class. This avoids the bean's initMethod="block" eagerly calling the V2 API at context startup even when all V2 tests are disabled. --- .../java/org/cloudfoundry/IntegrationTestConfiguration.java | 1 + .../java/org/cloudfoundry/client/v2/OrganizationsTest.java | 4 +--- .../java/org/cloudfoundry/client/v2/ServiceBrokersTest.java | 4 +--- .../java/org/cloudfoundry/client/v2/ServiceInstancesTest.java | 4 +--- .../test/java/org/cloudfoundry/client/v2/ServiceKeysTest.java | 4 +--- .../java/org/cloudfoundry/client/v2/ServicePlansTest.java | 4 +--- .../org/cloudfoundry/client/v2/ServiceUsageEventsTest.java | 4 +--- .../test/java/org/cloudfoundry/client/v2/ServicesTest.java | 4 +--- .../src/test/java/org/cloudfoundry/client/v2/SpacesTest.java | 4 +--- .../java/org/cloudfoundry/client/v3/ServiceBindingsTest.java | 4 +--- .../java/org/cloudfoundry/client/v3/ServiceBrokersTest.java | 4 +--- .../java/org/cloudfoundry/client/v3/ServiceInstancesTest.java | 4 +--- .../java/org/cloudfoundry/client/v3/ServiceOfferingsTest.java | 4 +--- .../java/org/cloudfoundry/client/v3/ServicePlansTest.java | 4 +--- .../test/java/org/cloudfoundry/operations/ServicesTest.java | 4 +--- 15 files changed, 15 insertions(+), 42 deletions(-) diff --git a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java index 8a6a1ad4b62..aec0afc99cd 100644 --- a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java +++ b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java @@ -473,6 +473,7 @@ Version serverVersion(@Qualifier("admin") CloudFoundryClient cloudFoundryClient) @Lazy @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") + @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) Mono serviceBrokerId( CloudFoundryClient cloudFoundryClient, NameFactory nameFactory, diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationsTest.java index 1b31140d922..3c8740d0fb2 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/OrganizationsTest.java @@ -106,9 +106,7 @@ public final class OrganizationsTest extends AbstractIntegrationTest { @Autowired private Mono organizationId; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBrokersTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBrokersTest.java index 50be1ea1b52..61320ccd50d 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBrokersTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceBrokersTest.java @@ -53,9 +53,7 @@ public final class ServiceBrokersTest extends AbstractIntegrationTest { @Autowired private Mono organizationId; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceBrokerName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceInstancesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceInstancesTest.java index cad61ddbd58..c3620f4957e 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceInstancesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceInstancesTest.java @@ -77,9 +77,7 @@ public final class ServiceInstancesTest extends AbstractIntegrationTest { @Autowired private RoutingClient routingClient; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceKeysTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceKeysTest.java index 485e9ba5719..3ec01e0d95c 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceKeysTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceKeysTest.java @@ -48,9 +48,7 @@ public final class ServiceKeysTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlansTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlansTest.java index e9fc66b8e8e..d0cc34c36b9 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlansTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicePlansTest.java @@ -63,9 +63,7 @@ public final class ServicePlansTest extends AbstractIntegrationTest { @Autowired private String planName; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceUsageEventsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceUsageEventsTest.java index 32703e319e4..56ddd5bbfc0 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceUsageEventsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServiceUsageEventsTest.java @@ -46,9 +46,7 @@ public final class ServiceUsageEventsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicesTest.java index 1469bfdd361..5410c1a951f 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/ServicesTest.java @@ -56,9 +56,7 @@ public final class ServicesTest extends AbstractIntegrationTest { @Autowired private String planName; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v2/SpacesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v2/SpacesTest.java index eae93b616bb..54fc74e861c 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v2/SpacesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v2/SpacesTest.java @@ -124,9 +124,7 @@ public final class SpacesTest extends AbstractIntegrationTest { @Autowired private Mono organizationId; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBindingsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBindingsTest.java index acdb96f1e94..3c0695a2da8 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBindingsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBindingsTest.java @@ -60,9 +60,7 @@ public class ServiceBindingsTest extends AbstractIntegrationTest { @Autowired private CloudFoundryClient cloudFoundryClient; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBrokersTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBrokersTest.java index 07e0b219cfc..4a13ea744cf 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBrokersTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBrokersTest.java @@ -59,9 +59,7 @@ public final class ServiceBrokersTest extends AbstractIntegrationTest { @Autowired private Mono organizationId; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceBrokerName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceInstancesTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceInstancesTest.java index 941c0e56169..1af91bbdf82 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceInstancesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceInstancesTest.java @@ -65,9 +65,7 @@ public final class ServiceInstancesTest extends AbstractIntegrationTest { @Autowired private Mono organizationId; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceOfferingsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceOfferingsTest.java index 20334935909..fec36409fe8 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceOfferingsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceOfferingsTest.java @@ -51,9 +51,7 @@ public final class ServiceOfferingsTest extends AbstractIntegrationTest { @Autowired private Mono organizationId; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceName; diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServicePlansTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServicePlansTest.java index 7f5f0383945..c749b3e23de 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ServicePlansTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServicePlansTest.java @@ -55,9 +55,7 @@ public final class ServicePlansTest extends AbstractIntegrationTest { @Autowired private String planName; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Test public void delete() { diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/ServicesTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/ServicesTest.java index 32b8cb4e687..f81ddb1a674 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/ServicesTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/ServicesTest.java @@ -78,9 +78,7 @@ public final class ServicesTest extends AbstractIntegrationTest { @Autowired private String planName; - // Optional: bean requires V2 API; class is guarded by @RequiresV2Api - @Autowired(required = false) - private Mono serviceBrokerId; + @Autowired private Mono serviceBrokerId; @Autowired private String serviceName; From 2c8da39c95b53c38807f5863b476f5185db96743 Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Fri, 17 Apr 2026 16:22:02 +0200 Subject: [PATCH 07/14] Centralize SKIP_V2_TESTS property name Extract the "SKIP_V2_TESTS" string literal into a public constant RequiresV2Api.SKIP_V2_TESTS_ENV and reference it from IntegrationTestConfiguration and CloudFoundryCleaner. --- .../org/cloudfoundry/CloudFoundryCleaner.java | 2 +- .../IntegrationTestConfiguration.java | 16 ++++++++-------- .../java/org/cloudfoundry/RequiresV2Api.java | 5 +++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java b/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java index 2985a04cde6..ef1dda0f795 100644 --- a/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java +++ b/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java @@ -133,7 +133,7 @@ final class CloudFoundryCleaner implements InitializingBean, DisposableBean { private static final boolean RUN_V2_CLEANUP = isRunV2Tests(); private static boolean isRunV2Tests() { - return !"true".equalsIgnoreCase(System.getenv("SKIP_V2_TESTS")); + return !"true".equalsIgnoreCase(System.getenv(RequiresV2Api.SKIP_V2_TESTS_ENV)); } private static final Map STANDARD_FEATURE_FLAGS = diff --git a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java index aec0afc99cd..94df918ecaa 100644 --- a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java +++ b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java @@ -347,7 +347,7 @@ RandomNameFactory nameFactory() { @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) Mono metricRegistrarServiceInstance( CloudFoundryClient cloudFoundryClient, Mono spaceId, NameFactory nameFactory) { return spaceId.flatMap( @@ -375,7 +375,7 @@ NetworkingClient networkingClient( @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) Mono organizationId( CloudFoundryClient cloudFoundryClient, String organizationName, @@ -473,7 +473,7 @@ Version serverVersion(@Qualifier("admin") CloudFoundryClient cloudFoundryClient) @Lazy @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) Mono serviceBrokerId( CloudFoundryClient cloudFoundryClient, NameFactory nameFactory, @@ -516,7 +516,7 @@ String serviceName(NameFactory nameFactory) { @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) Mono spaceId( CloudFoundryClient cloudFoundryClient, Mono organizationId, String spaceName) { return organizationId @@ -543,7 +543,7 @@ String spaceName(NameFactory nameFactory) { @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) Mono stackId(CloudFoundryClient cloudFoundryClient, Mono stackName) { return stackName .flux() @@ -572,7 +572,7 @@ Mono stackId(CloudFoundryClient cloudFoundryClient, Mono stackNa */ @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) Mono stackName(CloudFoundryClient cloudFoundryClient) { return PaginationUtils.requestClientV2Resources( page -> @@ -590,7 +590,7 @@ Mono stackName(CloudFoundryClient cloudFoundryClient) { @Lazy @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) Mono testLogCacheApp( CloudFoundryClient cloudFoundryClient, Mono spaceId, @@ -627,7 +627,7 @@ String testLogCacheAppName(NameFactory nameFactory) { @Lazy @Bean - @ConditionalOnProperty(name = "SKIP_V2_TESTS", havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) TestLogCacheEndpoints testLogCacheEndpoints( ConnectionContext connectionContext, TokenProvider tokenProvider, diff --git a/integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java b/integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java index acde38fb6bd..82bedb514e1 100644 --- a/integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java +++ b/integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java @@ -51,13 +51,14 @@ @ExtendWith(RequiresV2Api.V2ApiCondition.class) public @interface RequiresV2Api { + /** Environment variable name used to skip V2 API tests. */ + String SKIP_V2_TESTS_ENV = "SKIP_V2_TESTS"; + /** * JUnit 5 ExecutionCondition that checks if V2 tests should be skipped. */ class V2ApiCondition implements ExecutionCondition { - private static final String SKIP_V2_TESTS_ENV = "SKIP_V2_TESTS"; - @Override public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { if ("true".equalsIgnoreCase(System.getenv(SKIP_V2_TESTS_ENV))) { From 3f0db750166f510f0d681c1d5ee9680ed6efcd29 Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Fri, 17 Apr 2026 16:24:32 +0200 Subject: [PATCH 08/14] Annotate LogCacheTest class with @RequiresV2Api The info() test alone doesn't bring enough value to justify keeping the class partially enabled without V2. --- .../logcache/v1/LogCacheTest.java | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java b/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java index eb53f391235..26e5143229c 100644 --- a/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/logcache/v1/LogCacheTest.java @@ -39,32 +39,20 @@ import reactor.test.StepVerifier; @IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_2_9) +@RequiresV2Api public class LogCacheTest extends AbstractIntegrationTest { @Autowired LogCacheClient logCacheClient; private ApplicationUtils.ApplicationMetadata testLogCacheAppMetadata; - // Optional: only available when V2 API is enabled (requires deployed test app) - @Autowired(required = false) - private TestLogCacheEndpoints testLogCacheEndpoints; + @Autowired private TestLogCacheEndpoints testLogCacheEndpoints; private final Random random = new SecureRandom(); - /** - * Sets up the test log cache app metadata. The testLogCacheApp bean is optional - * ({@code required = false}) because it depends on V2 API calls for app deployment. - * When SKIP_V2_TESTS=true, this bean won't be available and setUp becomes a no-op. - * Tests that need testLogCacheAppMetadata are annotated with {@code @RequiresV2Api} - * and will be skipped in that case. - */ @BeforeEach - void setUp( - @Autowired(required = false) - Mono testLogCacheApp) { - if (testLogCacheApp != null) { - this.testLogCacheAppMetadata = testLogCacheApp.block(); - } + void setUp(@Autowired Mono testLogCacheApp) { + this.testLogCacheAppMetadata = testLogCacheApp.block(); } @Test @@ -83,7 +71,6 @@ public void info() { } @Test - @RequiresV2Api public void meta() { this.logCacheClient .meta(MetaRequest.builder().build()) @@ -99,7 +86,6 @@ public void meta() { } @Test - @RequiresV2Api @RequiresMetricRegistrar public void readCounter() { final String name = this.nameFactory.getName("counter-"); @@ -120,7 +106,6 @@ public void readCounter() { } @Test - @RequiresV2Api @RequiresMetricRegistrar public void readEvent() { final String title = this.nameFactory.getName("event-"); @@ -137,7 +122,6 @@ public void readEvent() { @Test @Disabled("fails often for no reasons") - @RequiresV2Api public void readGauge() { final String gaugeName = this.nameFactory.getName("gauge-"); final Double value = this.random.nextDouble() % 100; @@ -159,7 +143,6 @@ public void readGauge() { } @Test - @RequiresV2Api public void readLogs() { final String logMessage = this.nameFactory.getName("log-"); From 7fa9681b4b9132022664f16c1ff2cf1b7c5dd31c Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Fri, 17 Apr 2026 16:39:21 +0200 Subject: [PATCH 09/14] Port cleanApplicationsV3 binding removal from to V3 Replace V2 applicationsV2().listServiceBindings / removeServiceBinding calls with V3 serviceBindingsV3().list / delete in the cleaner's application cleanup path, eliminating the runV2Calls boolean parameter. --- .../org/cloudfoundry/CloudFoundryCleaner.java | 51 +++++++++---------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java b/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java index ef1dda0f795..d491e880907 100644 --- a/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java +++ b/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java @@ -28,7 +28,6 @@ import java.util.function.Supplier; import javax.net.ssl.SSLException; import org.cloudfoundry.client.CloudFoundryClient; -import org.cloudfoundry.client.v2.applications.ListApplicationServiceBindingsRequest; import org.cloudfoundry.client.v2.applications.RemoveApplicationServiceBindingRequest; import org.cloudfoundry.client.v2.buildpacks.DeleteBuildpackRequest; import org.cloudfoundry.client.v2.buildpacks.ListBuildpacksRequest; @@ -80,6 +79,8 @@ import org.cloudfoundry.client.v3.applications.ApplicationResource; import org.cloudfoundry.client.v3.applications.DeleteApplicationRequest; import org.cloudfoundry.client.v3.applications.ListApplicationsRequest; +import org.cloudfoundry.client.v3.servicebindings.DeleteServiceBindingRequest; +import org.cloudfoundry.client.v3.servicebindings.ListServiceBindingsRequest; import org.cloudfoundry.client.v3.serviceinstances.ListSharedSpacesRelationshipRequest; import org.cloudfoundry.client.v3.serviceinstances.ListSharedSpacesRelationshipResponse; import org.cloudfoundry.client.v3.serviceinstances.UnshareServiceInstanceRequest; @@ -207,8 +208,7 @@ void clean() { Mono.when( cleanApplicationsV3( this.cloudFoundryClient, - this.nameFactory, - false), // runV2Calls = false (V3-only path) + this.nameFactory), cleanUsers(this.uaaClient, this.nameFactory))) .retryWhen(Retry.max(5).filter(SSLException.class::isInstance)) .doOnSubscribe(s -> LOGGER.debug(">> CLEANUP (V3 only) <<")) @@ -250,9 +250,7 @@ void clean() { Mono.when( cleanApplicationsV3( this.cloudFoundryClient, - this.nameFactory, - true), // After Routes, cannot run with - // other cleanApps + this.nameFactory), cleanUsers(this.uaaClient, this.nameFactory) // After CF Users )) .thenMany( @@ -274,9 +272,8 @@ void clean() { } private static Flux cleanApplicationsV3( - CloudFoundryClient cloudFoundryClient, NameFactory nameFactory, boolean runV2Calls) { - Flux apps = - PaginationUtils.requestClientV3Resources( + CloudFoundryClient cloudFoundryClient, NameFactory nameFactory) { + return PaginationUtils.requestClientV3Resources( page -> cloudFoundryClient .applicationsV3() @@ -286,17 +283,12 @@ private static Flux cleanApplicationsV3( .build())) .filter( application -> - nameFactory.isApplicationName(application.getName())); - - if (runV2Calls) { - apps = - apps.delayUntil( - application -> - removeApplicationServiceBindings( - cloudFoundryClient, application)); - } - - return apps.flatMap( + nameFactory.isApplicationName(application.getName())) + .delayUntil( + application -> + removeApplicationServiceBindings( + cloudFoundryClient, application)) + .flatMap( application -> cloudFoundryClient .applicationsV3() @@ -1204,21 +1196,24 @@ private static boolean isCleanable(NameFactory nameFactory, UserResource resourc private static Flux removeApplicationServiceBindings( CloudFoundryClient cloudFoundryClient, Application application) { - return PaginationUtils.requestClientV2Resources( + return PaginationUtils.requestClientV3Resources( page -> cloudFoundryClient - .applicationsV2() - .listServiceBindings( - ListApplicationServiceBindingsRequest.builder() + .serviceBindingsV3() + .list( + ListServiceBindingsRequest.builder() .page(page) .applicationId(application.getId()) .build())) .flatMap( serviceBinding -> - requestRemoveServiceBinding( - cloudFoundryClient, - application.getId(), - ResourceUtils.getId(serviceBinding)) + cloudFoundryClient + .serviceBindingsV3() + .delete( + DeleteServiceBindingRequest.builder() + .serviceBindingId(serviceBinding.getId()) + .build()) + .then() .doOnError( t -> LOGGER.error( From e98ece3471ccaa605b5a6d33bff14a00e481f977 Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Fri, 17 Apr 2026 16:45:46 +0200 Subject: [PATCH 10/14] Clarify SKIP_BROWSER_AUTH_TESTS description in README Reword to explain the env var is for when UAA doesn't have browser-based auth configured, rather than referencing "non-interactive environments". --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7e516ec5416..06464884264 100644 --- a/README.md +++ b/README.md @@ -353,7 +353,7 @@ Name | Description `TEST_PROXY_PORT` | _(Optional)_ The port of a proxy to route all requests through. Defaults to `8080`. `TEST_PROXY_USERNAME` | _(Optional)_ The username for a proxy to route all requests through `TEST_SKIPSSLVALIDATION` | _(Optional)_ Whether to skip SSL validation when connecting to the Cloud Foundry instance. Defaults to `false`. -`SKIP_BROWSER_AUTH_TESTS` | _(Optional)_ Set to `true` to skip integration tests that require browser-based authentication (e.g., SSO tests). Useful when the Cloud Foundry instance does not support browser-based authentication or when running tests in a non-interactive environment. Defaults to `false`. +`SKIP_BROWSER_AUTH_TESTS` | _(Optional)_ Set to `true` to skip integration tests that require browser-based authentication (e.g., SSO tests). Useful when the Cloud Foundry instance's UAA does not have browser-based authentication configured. Defaults to `false`. `SKIP_METRIC_REGISTRAR_TESTS` | _(Optional)_ Set to `true` to skip integration tests that require the Metric Registrar service (e.g., MetricRegistrarTest). Useful when the Cloud Foundry instance does not have the Metric Registrar service available. Defaults to `false`. `SKIP_TCP_ROUTING_TESTS` | _(Optional)_ Set to `true` to skip TCP routing integration tests (TcpRoutesTest, RouterGroupsTest). Useful when the Cloud Foundry instance does not have TCP routing configured (i.e., no `routing_endpoint` in the info payload). Defaults to `false`. `SKIP_V2_TESTS` | _(Optional)_ Set to `true` to skip all V2 API integration tests. Useful when the Cloud Foundry V2 API is rate-limited or unavailable. When enabled, tests annotated with `@RequiresV2Api` will be skipped, including V3 tests that depend on V2 API calls (e.g., service broker creation). Defaults to `false`. From 25cb827d848bc79d8d01d6e07d78609f51bb59be Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Fri, 17 Apr 2026 16:48:11 +0200 Subject: [PATCH 11/14] Share V2 skip condition via RequiresV2Api Move the SKIP_V2_TESTS check into a reusable static method in V2ApiCondition. --- .../test/java/org/cloudfoundry/CloudFoundryCleaner.java | 6 +----- .../src/test/java/org/cloudfoundry/RequiresV2Api.java | 7 ++++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java b/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java index d491e880907..feaed95df6a 100644 --- a/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java +++ b/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java @@ -131,11 +131,7 @@ final class CloudFoundryCleaner implements InitializingBean, DisposableBean { private static final Logger LOGGER = LoggerFactory.getLogger("cloudfoundry-client.test"); - private static final boolean RUN_V2_CLEANUP = isRunV2Tests(); - - private static boolean isRunV2Tests() { - return !"true".equalsIgnoreCase(System.getenv(RequiresV2Api.SKIP_V2_TESTS_ENV)); - } + private static final boolean RUN_V2_CLEANUP = RequiresV2Api.V2ApiCondition.isEnabled(); private static final Map STANDARD_FEATURE_FLAGS = FluentMap.builder() diff --git a/integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java b/integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java index 82bedb514e1..b11fe8ca06b 100644 --- a/integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java +++ b/integration-test/src/test/java/org/cloudfoundry/RequiresV2Api.java @@ -59,9 +59,14 @@ */ class V2ApiCondition implements ExecutionCondition { + /** Returns {@code true} if V2 API tests should run (i.e., not skipped). */ + public static boolean isEnabled() { + return !"true".equalsIgnoreCase(System.getenv(SKIP_V2_TESTS_ENV)); + } + @Override public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { - if ("true".equalsIgnoreCase(System.getenv(SKIP_V2_TESTS_ENV))) { + if (!isEnabled()) { return ConditionEvaluationResult.disabled( "V2 API tests are disabled via " + SKIP_V2_TESTS_ENV From 43b3c90fe48bec25af0ace90faca1164559da53e Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Fri, 24 Apr 2026 16:30:53 +0200 Subject: [PATCH 12/14] Migrate organizationId and spaceId from V2 to V3 When SKIP_V2_TESTS=true, the organizationId and spaceId beans were not created (guarded by @ConditionalOnProperty), but V3 test classes like ApplicationsTest autowire them without @RequiresV2Api, causing failures. Replace V2 API calls with V3 equivalents so these beans are always available: - organizationId: use organizationsV3().create() and rolesV3().create() instead of V2 quota definitions, org creation, and manager association - spaceId: use spacesV3().create() with SpaceRelationships instead of V2 space creation Remove the now-unused organizationQuotaName bean. --- .../IntegrationTestConfiguration.java | 109 ++++++++++-------- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java index 94df918ecaa..39ba921c11c 100644 --- a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java +++ b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java @@ -39,14 +39,20 @@ import java.util.List; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.info.GetInfoRequest; -import org.cloudfoundry.client.v2.organizationquotadefinitions.CreateOrganizationQuotaDefinitionRequest; -import org.cloudfoundry.client.v2.organizations.AssociateOrganizationManagerRequest; -import org.cloudfoundry.client.v2.organizations.CreateOrganizationRequest; -import org.cloudfoundry.client.v2.spaces.CreateSpaceRequest; +import org.cloudfoundry.client.v2.userprovidedserviceinstances.CreateUserProvidedServiceInstanceRequest; import org.cloudfoundry.client.v2.stacks.ListStacksRequest; import org.cloudfoundry.client.v2.stacks.StackEntity; import org.cloudfoundry.client.v2.stacks.StackResource; -import org.cloudfoundry.client.v2.userprovidedserviceinstances.CreateUserProvidedServiceInstanceRequest; +import org.cloudfoundry.client.v3.Relationship; +import org.cloudfoundry.client.v3.ToOneRelationship; +import org.cloudfoundry.client.v3.organizations.CreateOrganizationRequest; +import org.cloudfoundry.client.v3.organizations.CreateOrganizationResponse; +import org.cloudfoundry.client.v3.roles.CreateRoleRequest; +import org.cloudfoundry.client.v3.roles.RoleRelationships; +import org.cloudfoundry.client.v3.roles.RoleType; +import org.cloudfoundry.client.v3.spaces.CreateSpaceRequest; +import org.cloudfoundry.client.v3.spaces.CreateSpaceResponse; +import org.cloudfoundry.client.v3.spaces.SpaceRelationships; import org.cloudfoundry.doppler.DopplerClient; import org.cloudfoundry.logcache.v1.LogCacheClient; import org.cloudfoundry.logcache.v1.TestLogCacheEndpoints; @@ -375,54 +381,49 @@ NetworkingClient networkingClient( @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) Mono organizationId( - CloudFoundryClient cloudFoundryClient, - String organizationName, - String organizationQuotaName, - Mono userId) { + CloudFoundryClient cloudFoundryClient, String organizationName, Mono userId) { return userId.flatMap( userId1 -> cloudFoundryClient - .organizationQuotaDefinitions() + .organizationsV3() .create( - CreateOrganizationQuotaDefinitionRequest.builder() - .applicationInstanceLimit(-1) - .applicationTaskLimit(-1) - .instanceMemoryLimit(-1) - .memoryLimit(16384) - .name(organizationQuotaName) - .nonBasicServicesAllowed(true) - .totalPrivateDomains(-1) - .totalReservedRoutePorts(-1) - .totalRoutes(-1) - .totalServiceKeys(-1) - .totalServices(-1) + CreateOrganizationRequest.builder() + .name(organizationName) .build()) - .map(ResourceUtils::getId) + .map(CreateOrganizationResponse::getId) .zipWith(Mono.just(userId1))) - .flatMap( - function( - (quotaId, userId1) -> - cloudFoundryClient - .organizations() - .create( - CreateOrganizationRequest.builder() - .name(organizationName) - .quotaDefinitionId(quotaId) - .build()) - .map(ResourceUtils::getId) - .zipWith(Mono.just(userId1)))) .flatMap( function( (organizationId, userId1) -> cloudFoundryClient - .organizations() - .associateManager( - AssociateOrganizationManagerRequest - .builder() - .organizationId(organizationId) - .managerId(userId1) + .rolesV3() + .create( + CreateRoleRequest.builder() + .type(RoleType.ORGANIZATION_MANAGER) + .relationships( + RoleRelationships.builder() + .user( + ToOneRelationship + .builder() + .data( + Relationship + .builder() + .id( + userId1) + .build()) + .build()) + .organization( + ToOneRelationship + .builder() + .data( + Relationship + .builder() + .id( + organizationId) + .build()) + .build()) + .build()) .build()) .thenReturn(organizationId))) .doOnSubscribe(s -> this.logger.debug(">> ORGANIZATION ({}) <<", organizationName)) @@ -436,11 +437,6 @@ String organizationName(NameFactory nameFactory) { return nameFactory.getOrganizationName(); } - @Bean - String organizationQuotaName(NameFactory nameFactory) { - return nameFactory.getQuotaDefinitionName(); - } - @Bean String password(NameFactory nameFactory) { return nameFactory.getPassword(); @@ -516,20 +512,31 @@ String serviceName(NameFactory nameFactory) { @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) Mono spaceId( CloudFoundryClient cloudFoundryClient, Mono organizationId, String spaceName) { return organizationId .flatMap( orgId -> cloudFoundryClient - .spaces() + .spacesV3() .create( CreateSpaceRequest.builder() .name(spaceName) - .organizationId(orgId) + .relationships( + SpaceRelationships.builder() + .organization( + ToOneRelationship + .builder() + .data( + Relationship + .builder() + .id( + orgId) + .build()) + .build()) + .build()) .build())) - .map(ResourceUtils::getId) + .map(CreateSpaceResponse::getId) .doOnSubscribe(s -> this.logger.debug(">> SPACE ({}) <<", spaceName)) .doOnError(Throwable::printStackTrace) .doOnSuccess(id -> this.logger.debug("<< SPACE ({}) >>", id)) From 817554c26e7f08cc4ba70f967851b378d8335b03 Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Fri, 24 Apr 2026 16:43:19 +0200 Subject: [PATCH 13/14] Migrate stackId and stackName from V2 to V3 Add missing state and stateReason fields to the V3 Stack model to match the current CF API response, then migrate the stackId and stackName beans to use stacksV3() instead of the V2 stacks API. This allows StacksTest to run when SKIP_V2_TESTS=true. --- .../cloudfoundry/client/v3/stacks/Stack.java | 14 +++++++++ .../IntegrationTestConfiguration.java | 30 +++++++++---------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/stacks/Stack.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/stacks/Stack.java index 0e90cc053de..6e6cca0410f 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/stacks/Stack.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/stacks/Stack.java @@ -66,4 +66,18 @@ public abstract class Stack extends Resource { @JsonProperty("default") @Nullable abstract Boolean geDefault(); + + /** + * The state of the stack (e.g. ready) + */ + @JsonProperty("state") + @Nullable + abstract String getState(); + + /** + * The reason for the stack's current state + */ + @JsonProperty("state_reason") + @Nullable + abstract String getStateReason(); } diff --git a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java index 39ba921c11c..da9a622908e 100644 --- a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java +++ b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java @@ -40,9 +40,6 @@ import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v2.info.GetInfoRequest; import org.cloudfoundry.client.v2.userprovidedserviceinstances.CreateUserProvidedServiceInstanceRequest; -import org.cloudfoundry.client.v2.stacks.ListStacksRequest; -import org.cloudfoundry.client.v2.stacks.StackEntity; -import org.cloudfoundry.client.v2.stacks.StackResource; import org.cloudfoundry.client.v3.Relationship; import org.cloudfoundry.client.v3.ToOneRelationship; import org.cloudfoundry.client.v3.organizations.CreateOrganizationRequest; @@ -550,23 +547,22 @@ String spaceName(NameFactory nameFactory) { @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) Mono stackId(CloudFoundryClient cloudFoundryClient, Mono stackName) { return stackName - .flux() - .flatMap( + .flatMapMany( name -> - PaginationUtils.requestClientV2Resources( + PaginationUtils.requestClientV3Resources( page -> cloudFoundryClient - .stacks() + .stacksV3() .list( - ListStacksRequest.builder() + org.cloudfoundry.client.v3.stacks + .ListStacksRequest.builder() .name(name) .page(page) .build()))) .single() - .map(ResourceUtils::getId) + .map(org.cloudfoundry.client.v3.stacks.StackResource::getId) .doOnSubscribe(s -> this.logger.debug(">> STACK ({}) <<", stackName)) .doOnError(Throwable::printStackTrace) .doOnSuccess(id -> this.logger.debug("<< STACK ({})>>", id)) @@ -579,15 +575,17 @@ Mono stackId(CloudFoundryClient cloudFoundryClient, Mono stackNa */ @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) Mono stackName(CloudFoundryClient cloudFoundryClient) { - return PaginationUtils.requestClientV2Resources( + return PaginationUtils.requestClientV3Resources( page -> cloudFoundryClient - .stacks() - .list(ListStacksRequest.builder().page(page).build())) - .map(StackResource::getEntity) - .map(StackEntity::getName) + .stacksV3() + .list( + org.cloudfoundry.client.v3.stacks + .ListStacksRequest.builder() + .page(page) + .build())) + .map(org.cloudfoundry.client.v3.stacks.StackResource::getName) .filter(s -> s.matches("^cflinuxfs\\d$")) .sort(Comparator.reverseOrder()) .next() From 6781bae0c5f8c1db12c245941a4916b803078b5f Mon Sep 17 00:00:00 2001 From: Joris Baum Date: Fri, 24 Apr 2026 16:45:31 +0200 Subject: [PATCH 14/14] Apply spotless --- .../applications/DefaultApplicationsTest.java | 6 +- .../org/cloudfoundry/CloudFoundryCleaner.java | 56 ++++++++----------- .../IntegrationTestConfiguration.java | 24 ++++++-- .../cloudfoundry/operations/StacksTest.java | 1 + 4 files changed, 47 insertions(+), 40 deletions(-) diff --git a/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/DefaultApplicationsTest.java b/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/DefaultApplicationsTest.java index 93f83236aa6..f137ac2d84b 100644 --- a/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/DefaultApplicationsTest.java +++ b/cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/DefaultApplicationsTest.java @@ -1378,7 +1378,11 @@ void logsLogCache() { requestLogsRecentLogCache(this.logCacheClient, "test-metadata-id"); this.applications - .logs(ApplicationLogsRequest.builder().name("test-application-name").recent(true).build()) + .logs( + ApplicationLogsRequest.builder() + .name("test-application-name") + .recent(true) + .build()) .as(StepVerifier::create) .expectNextMatches( log -> diff --git a/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java b/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java index feaed95df6a..de94246f6b1 100644 --- a/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java +++ b/integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java @@ -76,7 +76,6 @@ import org.cloudfoundry.client.v3.Metadata; import org.cloudfoundry.client.v3.Relationship; import org.cloudfoundry.client.v3.applications.Application; -import org.cloudfoundry.client.v3.applications.ApplicationResource; import org.cloudfoundry.client.v3.applications.DeleteApplicationRequest; import org.cloudfoundry.client.v3.applications.ListApplicationsRequest; import org.cloudfoundry.client.v3.servicebindings.DeleteServiceBindingRequest; @@ -202,9 +201,7 @@ void clean() { cleanIdentityZones(this.uaaClient, this.nameFactory))) .thenMany( Mono.when( - cleanApplicationsV3( - this.cloudFoundryClient, - this.nameFactory), + cleanApplicationsV3(this.cloudFoundryClient, this.nameFactory), cleanUsers(this.uaaClient, this.nameFactory))) .retryWhen(Retry.max(5).filter(SSLException.class::isInstance)) .doOnSubscribe(s -> LOGGER.debug(">> CLEANUP (V3 only) <<")) @@ -244,9 +241,7 @@ void clean() { cleanUsers(this.cloudFoundryClient, this.nameFactory))) .thenMany( Mono.when( - cleanApplicationsV3( - this.cloudFoundryClient, - this.nameFactory), + cleanApplicationsV3(this.cloudFoundryClient, this.nameFactory), cleanUsers(this.uaaClient, this.nameFactory) // After CF Users )) .thenMany( @@ -270,35 +265,30 @@ void clean() { private static Flux cleanApplicationsV3( CloudFoundryClient cloudFoundryClient, NameFactory nameFactory) { return PaginationUtils.requestClientV3Resources( - page -> - cloudFoundryClient - .applicationsV3() - .list( - ListApplicationsRequest.builder() - .page(page) - .build())) - .filter( - application -> - nameFactory.isApplicationName(application.getName())) + page -> + cloudFoundryClient + .applicationsV3() + .list(ListApplicationsRequest.builder().page(page).build())) + .filter(application -> nameFactory.isApplicationName(application.getName())) .delayUntil( application -> - removeApplicationServiceBindings( - cloudFoundryClient, application)) + removeApplicationServiceBindings(cloudFoundryClient, application)) .flatMap( - application -> - cloudFoundryClient - .applicationsV3() - .delete( - DeleteApplicationRequest.builder() - .applicationId(application.getId()) - .build()) - .then() - .doOnError( - t -> - LOGGER.error( - "Unable to delete V3 application" + " {}", - application.getName(), - t))); + application -> + cloudFoundryClient + .applicationsV3() + .delete( + DeleteApplicationRequest.builder() + .applicationId(application.getId()) + .build()) + .then() + .doOnError( + t -> + LOGGER.error( + "Unable to delete V3 application" + + " {}", + application.getName(), + t))); } private static Flux cleanBuildpacks( diff --git a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java index da9a622908e..46692283d55 100644 --- a/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java +++ b/integration-test/src/test/java/org/cloudfoundry/IntegrationTestConfiguration.java @@ -350,7 +350,10 @@ RandomNameFactory nameFactory() { @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty( + name = RequiresV2Api.SKIP_V2_TESTS_ENV, + havingValue = "false", + matchIfMissing = true) Mono metricRegistrarServiceInstance( CloudFoundryClient cloudFoundryClient, Mono spaceId, NameFactory nameFactory) { return spaceId.flatMap( @@ -466,7 +469,10 @@ Version serverVersion(@Qualifier("admin") CloudFoundryClient cloudFoundryClient) @Lazy @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty( + name = RequiresV2Api.SKIP_V2_TESTS_ENV, + havingValue = "false", + matchIfMissing = true) Mono serviceBrokerId( CloudFoundryClient cloudFoundryClient, NameFactory nameFactory, @@ -581,8 +587,8 @@ Mono stackName(CloudFoundryClient cloudFoundryClient) { cloudFoundryClient .stacksV3() .list( - org.cloudfoundry.client.v3.stacks - .ListStacksRequest.builder() + org.cloudfoundry.client.v3.stacks.ListStacksRequest + .builder() .page(page) .build())) .map(org.cloudfoundry.client.v3.stacks.StackResource::getName) @@ -595,7 +601,10 @@ Mono stackName(CloudFoundryClient cloudFoundryClient) { @Lazy @Bean(initMethod = "block") @DependsOn("cloudFoundryCleaner") - @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty( + name = RequiresV2Api.SKIP_V2_TESTS_ENV, + havingValue = "false", + matchIfMissing = true) Mono testLogCacheApp( CloudFoundryClient cloudFoundryClient, Mono spaceId, @@ -632,7 +641,10 @@ String testLogCacheAppName(NameFactory nameFactory) { @Lazy @Bean - @ConditionalOnProperty(name = RequiresV2Api.SKIP_V2_TESTS_ENV, havingValue = "false", matchIfMissing = true) + @ConditionalOnProperty( + name = RequiresV2Api.SKIP_V2_TESTS_ENV, + havingValue = "false", + matchIfMissing = true) TestLogCacheEndpoints testLogCacheEndpoints( ConnectionContext connectionContext, TokenProvider tokenProvider, diff --git a/integration-test/src/test/java/org/cloudfoundry/operations/StacksTest.java b/integration-test/src/test/java/org/cloudfoundry/operations/StacksTest.java index e69de29bb2d..8b137891791 100644 --- a/integration-test/src/test/java/org/cloudfoundry/operations/StacksTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/operations/StacksTest.java @@ -0,0 +1 @@ +