diff --git a/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/_ReactorCloudFoundryClient.java b/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/_ReactorCloudFoundryClient.java index 319a1bcfd6..7e43bd5820 100644 --- a/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/_ReactorCloudFoundryClient.java +++ b/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/_ReactorCloudFoundryClient.java @@ -34,6 +34,7 @@ import org.cloudfoundry.client.v2.routemappings.RouteMappings; import org.cloudfoundry.client.v2.routes.Routes; import org.cloudfoundry.client.v2.securitygroups.SecurityGroups; +import org.cloudfoundry.client.v3.organizationquotadefinitions.OrganizationQuotaDefinitionsV3; import org.cloudfoundry.client.v3.securitygroups.SecurityGroupsV3; import org.cloudfoundry.client.v2.servicebindings.ServiceBindingsV2; import org.cloudfoundry.client.v2.servicebrokers.ServiceBrokers; @@ -92,6 +93,7 @@ import org.cloudfoundry.reactor.client.v2.routemappings.ReactorRouteMappings; import org.cloudfoundry.reactor.client.v2.routes.ReactorRoutes; import org.cloudfoundry.reactor.client.v2.securitygroups.ReactorSecurityGroups; +import org.cloudfoundry.reactor.client.v3.organizationquotadefinitions.ReactorOrganizationQuotaDefinitionsV3; import org.cloudfoundry.reactor.client.v3.securitygroups.ReactorSecurityGroupsV3; import org.cloudfoundry.reactor.client.v2.servicebindings.ReactorServiceBindingsV2; import org.cloudfoundry.reactor.client.v2.servicebrokers.ReactorServiceBrokers; @@ -278,6 +280,13 @@ public OrganizationQuotaDefinitions organizationQuotaDefinitions() { getRequestTags()); } + @Override + @Value.Derived + public OrganizationQuotaDefinitionsV3 organizationQuotaDefinitionsV3() { + return new ReactorOrganizationQuotaDefinitionsV3(getConnectionContext(), getRootV3(), getTokenProvider(), + getRequestTags()); + } + @Override @Value.Derived public Organizations organizations() { diff --git a/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/v3/organizationquotadefinitions/ReactorOrganizationQuotaDefinitionsV3.java b/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/v3/organizationquotadefinitions/ReactorOrganizationQuotaDefinitionsV3.java new file mode 100644 index 0000000000..4d4fb69a49 --- /dev/null +++ b/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/v3/organizationquotadefinitions/ReactorOrganizationQuotaDefinitionsV3.java @@ -0,0 +1,113 @@ +/* + * Copyright 2013-2025 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.reactor.client.v3.organizationquotadefinitions; + +import java.util.Map; +import org.cloudfoundry.client.v3.organizationquotadefinitions.CreateOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.CreateOrganizationQuotaDefinitionResponse; +import org.cloudfoundry.client.v3.organizationquotadefinitions.DeleteOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.GetOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.GetOrganizationQuotaDefinitionResponse; +import org.cloudfoundry.client.v3.organizationquotadefinitions.ListOrganizationQuotaDefinitionsRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.ListOrganizationQuotaDefinitionsResponse; +import org.cloudfoundry.client.v3.organizationquotadefinitions.OrganizationQuotaDefinitionsV3; +import org.cloudfoundry.client.v3.organizationquotadefinitions.UpdateOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.UpdateOrganizationQuotaDefinitionResponse; +import org.cloudfoundry.reactor.ConnectionContext; +import org.cloudfoundry.reactor.TokenProvider; +import org.cloudfoundry.reactor.client.v3.AbstractClientV3Operations; +import reactor.core.publisher.Mono; + +/** + * The Reactor-based implementation of {@link ReactorOrganizationQuotaDefinitionsV3} + */ +public class ReactorOrganizationQuotaDefinitionsV3 extends AbstractClientV3Operations + implements OrganizationQuotaDefinitionsV3 { + + /** + * Creates an instance + * + * @param connectionContext the {@link ConnectionContext} to use when communicating with the server + * @param root the root URI of the server. Typically, something like {@code https://api.run.pivotal.io}. + * @param tokenProvider the {@link TokenProvider} to use when communicating with the server + * @param requestTags map with custom http headers which will be added to web request + */ + public ReactorOrganizationQuotaDefinitionsV3( + ConnectionContext connectionContext, + Mono root, + TokenProvider tokenProvider, + Map requestTags) { + super(connectionContext, root, tokenProvider, requestTags); + } + + @Override + public Mono create( + CreateOrganizationQuotaDefinitionRequest request) { + return post( + request, + CreateOrganizationQuotaDefinitionResponse.class, + builder -> builder.pathSegment("organization_quotas")) + .checkpoint(); + } + + @Override + public Mono get( + GetOrganizationQuotaDefinitionRequest request) { + return get( + request, + GetOrganizationQuotaDefinitionResponse.class, + builder -> + builder.pathSegment( + "organization_quotas", + request.getOrganizationQuotaDefinitionId())) + .checkpoint(); + } + + @Override + public Mono list( + ListOrganizationQuotaDefinitionsRequest request) { + return get( + request, + ListOrganizationQuotaDefinitionsResponse.class, + builder -> builder.pathSegment("organization_quotas")) + .checkpoint(); + } + + @Override + public Mono update( + UpdateOrganizationQuotaDefinitionRequest request) { + return patch( + request, + UpdateOrganizationQuotaDefinitionResponse.class, + builder -> + builder.pathSegment( + "organization_quotas", + request.getOrganizationQuotaDefinitionId())) + .checkpoint(); + } + + @Override + public Mono delete(DeleteOrganizationQuotaDefinitionRequest request) { + return delete( + request, + builder -> + builder.pathSegment( + "organization_quotas", + request.getOrganizationQuotaDefinitionId())) + .checkpoint(); + } +} diff --git a/cloudfoundry-client-reactor/src/test/java/org/cloudfoundry/reactor/client/v3/organizationquotadefinitions/ReactorOrganizationQuotaDefinitionsV3Test.java b/cloudfoundry-client-reactor/src/test/java/org/cloudfoundry/reactor/client/v3/organizationquotadefinitions/ReactorOrganizationQuotaDefinitionsV3Test.java new file mode 100644 index 0000000000..60cd7eebdb --- /dev/null +++ b/cloudfoundry-client-reactor/src/test/java/org/cloudfoundry/reactor/client/v3/organizationquotadefinitions/ReactorOrganizationQuotaDefinitionsV3Test.java @@ -0,0 +1,305 @@ +/* + * Copyright 2013-2025 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.reactor.client.v3.organizationquotadefinitions; + +import static io.netty.handler.codec.http.HttpMethod.DELETE; +import static io.netty.handler.codec.http.HttpMethod.GET; +import static io.netty.handler.codec.http.HttpMethod.PATCH; +import static io.netty.handler.codec.http.HttpMethod.POST; +import static io.netty.handler.codec.http.HttpResponseStatus.ACCEPTED; +import static io.netty.handler.codec.http.HttpResponseStatus.OK; + +import java.time.Duration; +import java.util.Collections; +import org.cloudfoundry.client.v3.Link; +import org.cloudfoundry.client.v3.Pagination; +import org.cloudfoundry.client.v3.Relationship; +import org.cloudfoundry.client.v3.ToManyRelationship; +import org.cloudfoundry.client.v3.organizationquotadefinitions.Apps; +import org.cloudfoundry.client.v3.organizationquotadefinitions.CreateOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.CreateOrganizationQuotaDefinitionResponse; +import org.cloudfoundry.client.v3.organizationquotadefinitions.DeleteOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.Domains; +import org.cloudfoundry.client.v3.organizationquotadefinitions.GetOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.GetOrganizationQuotaDefinitionResponse; +import org.cloudfoundry.client.v3.organizationquotadefinitions.ListOrganizationQuotaDefinitionsRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.ListOrganizationQuotaDefinitionsResponse; +import org.cloudfoundry.client.v3.organizationquotadefinitions.OrganizationQuotaDefinitionRelationships; +import org.cloudfoundry.client.v3.organizationquotadefinitions.OrganizationQuotaDefinitionResource; +import org.cloudfoundry.client.v3.organizationquotadefinitions.Routes; +import org.cloudfoundry.client.v3.organizationquotadefinitions.Services; +import org.cloudfoundry.client.v3.organizationquotadefinitions.UpdateOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.UpdateOrganizationQuotaDefinitionResponse; +import org.cloudfoundry.reactor.InteractionContext; +import org.cloudfoundry.reactor.TestRequest; +import org.cloudfoundry.reactor.TestResponse; +import org.cloudfoundry.reactor.client.AbstractClientApiTest; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import reactor.test.StepVerifier; + +class ReactorOrganizationQuotaDefinitionsV3Test extends AbstractClientApiTest { + + private final ReactorOrganizationQuotaDefinitionsV3 organizationQuotaDefinitionsV3 = + new ReactorOrganizationQuotaDefinitionsV3( + CONNECTION_CONTEXT, this.root, TOKEN_PROVIDER, Collections.emptyMap()); + + @Test + void create() { + mockRequest( + InteractionContext.builder() + .request( + TestRequest.builder() + .method(POST) + .path("/organization_quotas") + .payload( + "fixtures/client/v3/organization_quotas/POST_request.json") + .build()) + .response( + TestResponse.builder() + .status(OK) + .payload( + "fixtures/client/v3/organization_quotas/POST_response.json") + .build()) + .build()); + + this.organizationQuotaDefinitionsV3 + .create(CreateOrganizationQuotaDefinitionRequest.builder().name("my-quota").build()) + .as(StepVerifier::create) + .expectNext( + CreateOrganizationQuotaDefinitionResponse.builder() + .from(expectedOrganizationQuotaDefinitionResource1()) + .build()) + .expectComplete() + .verify(Duration.ofSeconds(5)); + } + + @Test + void delete() { + mockRequest( + InteractionContext.builder() + .request( + TestRequest.builder() + .method(DELETE) + .path("/organization_quotas/test-organization-quota-id") + .build()) + .response( + TestResponse.builder() + .status(ACCEPTED) + .header( + "Location", + "https://api.example.org/v3/jobs/test-job-id") + .build()) + .build()); + + this.organizationQuotaDefinitionsV3 + .delete( + DeleteOrganizationQuotaDefinitionRequest.builder() + .organizationQuotaDefinitionId("test-organization-quota-id") + .build()) + .as(StepVerifier::create) + .expectNext("test-job-id") + .expectComplete() + .verify(Duration.ofSeconds(5)); + } + + @Test + void get() { + mockRequest( + InteractionContext.builder() + .request( + TestRequest.builder() + .method(GET) + .path( + "/organization_quotas/24637893-3b77-489d-bb79-8466f0d88b52") + .build()) + .response( + TestResponse.builder() + .status(OK) + .payload( + "fixtures/client/v3/organization_quotas/GET_{id}_response.json") + .build()) + .build()); + + this.organizationQuotaDefinitionsV3 + .get( + GetOrganizationQuotaDefinitionRequest.builder() + .organizationQuotaDefinitionId( + "24637893-3b77-489d-bb79-8466f0d88b52") + .build()) + .as(StepVerifier::create) + .expectNext( + GetOrganizationQuotaDefinitionResponse.builder() + .from(expectedOrganizationQuotaDefinitionResource1()) + .build()) + .expectComplete() + .verify(Duration.ofSeconds(5)); + } + + @Test + void list() { + mockRequest( + InteractionContext.builder() + .request( + TestRequest.builder() + .method(GET) + .path("/organization_quotas") + .build()) + .response( + TestResponse.builder() + .status(OK) + .payload( + "fixtures/client/v3/organization_quotas/GET_response.json") + .build()) + .build()); + + this.organizationQuotaDefinitionsV3 + .list(ListOrganizationQuotaDefinitionsRequest.builder().build()) + .as(StepVerifier::create) + .expectNext( + ListOrganizationQuotaDefinitionsResponse.builder() + .pagination( + Pagination.builder() + .totalResults(2) + .totalPages(1) + .first( + Link.builder() + .href( + "https://api.example.org/v3/organization_quotas?page=1&per_page=50") + .build()) + .last( + Link.builder() + .href( + "https://api.example.org/v3/organization_quotas?page=1&per_page=50") + .build()) + .build()) + .resource( + OrganizationQuotaDefinitionResource.builder() + .from( + expectedOrganizationQuotaDefinitionResource1()) + .build()) + .resource( + OrganizationQuotaDefinitionResource.builder() + .from( + expectedOrganizationQuotaDefinitionResource2()) + .build()) + .build()) + .expectComplete() + .verify(Duration.ofSeconds(5)); + } + + @Test + void update() { + mockRequest( + InteractionContext.builder() + .request( + TestRequest.builder() + .method(PATCH) + .path( + "/organization_quotas/24637893-3b77-489d-bb79-8466f0d88b52") + .payload( + "fixtures/client/v3/organization_quotas/PATCH_{id}_request.json") + .build()) + .response( + TestResponse.builder() + .status(OK) + .payload( + "fixtures/client/v3/organization_quotas/PATCH_{id}_response.json") + .build()) + .build()); + + this.organizationQuotaDefinitionsV3 + .update( + UpdateOrganizationQuotaDefinitionRequest.builder() + .organizationQuotaDefinitionId( + "24637893-3b77-489d-bb79-8466f0d88b52") + .build()) + .as(StepVerifier::create) + .expectNext( + UpdateOrganizationQuotaDefinitionResponse.builder() + .from(expectedOrganizationQuotaDefinitionResource1()) + .build()) + .expectComplete() + .verify(Duration.ofSeconds(5)); + } + + @NotNull + private static OrganizationQuotaDefinitionResource + expectedOrganizationQuotaDefinitionResource1() { + return buildOrganizationQuotaDefinitionResource( + "24637893-3b77-489d-bb79-8466f0d88b52", + "my-quota", + "9b370018-c38e-44c9-86d6-155c76801104"); + } + + private static OrganizationQuotaDefinitionResource + expectedOrganizationQuotaDefinitionResource2() { + return buildOrganizationQuotaDefinitionResource( + "bb49bf20-ad98-4729-93ae-38fbc564b630", + "my-quota-2", + "144251f2-a202-4ffe-ab47-9046c4077e99"); + } + + @NotNull + private static OrganizationQuotaDefinitionResource buildOrganizationQuotaDefinitionResource( + String id, String name, String relatedOrganizationId) { + + Apps apps = + Apps.builder() + .totalMemoryInMb(5120) + .perProcessMemoryInMb(1024) + .logRateLimitInBytesPerSecond(1024) + .totalInstances(10) + .perAppTasks(5) + .build(); + Services services = + Services.builder() + .isPaidServicesAllowed(true) + .totalServiceInstances(10) + .totalServiceKeys(20) + .build(); + Routes routes = Routes.builder().totalRoutes(8).totalReservedPorts(4).build(); + Domains domains = Domains.builder().totalDomains(7).build(); + ToManyRelationship organizationRelationships = + ToManyRelationship.builder() + .data( + Collections.singletonList( + Relationship.builder().id(relatedOrganizationId).build())) + .build(); + OrganizationQuotaDefinitionRelationships relationships = + OrganizationQuotaDefinitionRelationships.builder() + .organizations(organizationRelationships) + .build(); + + return OrganizationQuotaDefinitionResource.builder() + .createdAt("2016-05-04T17:00:41Z") + .id(id) + .link( + "self", + Link.builder() + .href("https://api.example.org/v3/organization_quotas/" + id) + .build()) + .name(name) + .updatedAt("2016-05-04T17:00:41Z") + .apps(apps) + .services(services) + .routes(routes) + .domains(domains) + .relationships(relationships) + .build(); + } +} diff --git a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/GET_response.json b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/GET_response.json new file mode 100644 index 0000000000..7c33318b28 --- /dev/null +++ b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/GET_response.json @@ -0,0 +1,86 @@ +{ + "pagination": { + "total_results": 2, + "total_pages": 1, + "first": { + "href": "https://api.example.org/v3/organization_quotas?page=1&per_page=50" + }, + "last": { + "href": "https://api.example.org/v3/organization_quotas?page=1&per_page=50" + }, + "next": null, + "previous": null + }, + "resources": [ + { + "guid": "24637893-3b77-489d-bb79-8466f0d88b52", + "created_at": "2016-05-04T17:00:41Z", + "updated_at": "2016-05-04T17:00:41Z", + "name": "my-quota", + "apps": { + "total_memory_in_mb": 5120, + "per_process_memory_in_mb": 1024, + "log_rate_limit_in_bytes_per_second": 1024, + "total_instances": 10, + "per_app_tasks": 5 + }, + "services": { + "paid_services_allowed": true, + "total_service_instances": 10, + "total_service_keys": 20 + }, + "routes": { + "total_routes": 8, + "total_reserved_ports": 4 + }, + "domains": { + "total_domains": 7 + }, + "relationships": { + "organizations": { + "data": [ + { "guid": "9b370018-c38e-44c9-86d6-155c76801104" } + ] + } + }, + "links": { + "self": { "href": "https://api.example.org/v3/organization_quotas/24637893-3b77-489d-bb79-8466f0d88b52" } + } + }, + { + "guid": "bb49bf20-ad98-4729-93ae-38fbc564b630", + "created_at": "2016-05-04T17:00:41Z", + "updated_at": "2016-05-04T17:00:41Z", + "name": "my-quota-2", + "apps": { + "total_memory_in_mb": 5120, + "per_process_memory_in_mb": 1024, + "log_rate_limit_in_bytes_per_second": 1024, + "total_instances": 10, + "per_app_tasks": 5 + }, + "services": { + "paid_services_allowed": true, + "total_service_instances": 10, + "total_service_keys": 20 + }, + "routes": { + "total_routes": 8, + "total_reserved_ports": 4 + }, + "domains": { + "total_domains": 7 + }, + "relationships": { + "organizations": { + "data": [ + { "guid": "144251f2-a202-4ffe-ab47-9046c4077e99" } + ] + } + }, + "links": { + "self": { "href": "https://api.example.org/v3/organization_quotas/bb49bf20-ad98-4729-93ae-38fbc564b630" } + } + } + ] +} \ No newline at end of file diff --git a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/GET_{id}_response.json b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/GET_{id}_response.json new file mode 100644 index 0000000000..af547d449f --- /dev/null +++ b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/GET_{id}_response.json @@ -0,0 +1,35 @@ +{ + "guid": "24637893-3b77-489d-bb79-8466f0d88b52", + "created_at": "2016-05-04T17:00:41Z", + "updated_at": "2016-05-04T17:00:41Z", + "name": "my-quota", + "apps": { + "total_memory_in_mb": 5120, + "per_process_memory_in_mb": 1024, + "log_rate_limit_in_bytes_per_second": 1024, + "total_instances": 10, + "per_app_tasks": 5 + }, + "services": { + "paid_services_allowed": true, + "total_service_instances": 10, + "total_service_keys": 20 + }, + "routes": { + "total_routes": 8, + "total_reserved_ports": 4 + }, + "domains": { + "total_domains": 7 + }, + "relationships": { + "organizations": { + "data": [ + { "guid": "9b370018-c38e-44c9-86d6-155c76801104" } + ] + } + }, + "links": { + "self": { "href": "https://api.example.org/v3/organization_quotas/24637893-3b77-489d-bb79-8466f0d88b52" } + } +} \ No newline at end of file diff --git a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/PATCH_{id}_request.json b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/PATCH_{id}_request.json new file mode 100644 index 0000000000..7a73a41bfd --- /dev/null +++ b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/PATCH_{id}_request.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/PATCH_{id}_response.json b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/PATCH_{id}_response.json new file mode 100644 index 0000000000..af547d449f --- /dev/null +++ b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/PATCH_{id}_response.json @@ -0,0 +1,35 @@ +{ + "guid": "24637893-3b77-489d-bb79-8466f0d88b52", + "created_at": "2016-05-04T17:00:41Z", + "updated_at": "2016-05-04T17:00:41Z", + "name": "my-quota", + "apps": { + "total_memory_in_mb": 5120, + "per_process_memory_in_mb": 1024, + "log_rate_limit_in_bytes_per_second": 1024, + "total_instances": 10, + "per_app_tasks": 5 + }, + "services": { + "paid_services_allowed": true, + "total_service_instances": 10, + "total_service_keys": 20 + }, + "routes": { + "total_routes": 8, + "total_reserved_ports": 4 + }, + "domains": { + "total_domains": 7 + }, + "relationships": { + "organizations": { + "data": [ + { "guid": "9b370018-c38e-44c9-86d6-155c76801104" } + ] + } + }, + "links": { + "self": { "href": "https://api.example.org/v3/organization_quotas/24637893-3b77-489d-bb79-8466f0d88b52" } + } +} \ No newline at end of file diff --git a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/POST_request.json b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/POST_request.json new file mode 100644 index 0000000000..fe1dcc937e --- /dev/null +++ b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/POST_request.json @@ -0,0 +1,3 @@ +{ + "name": "my-quota" +} \ No newline at end of file diff --git a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/POST_response.json b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/POST_response.json new file mode 100644 index 0000000000..af547d449f --- /dev/null +++ b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/organization_quotas/POST_response.json @@ -0,0 +1,35 @@ +{ + "guid": "24637893-3b77-489d-bb79-8466f0d88b52", + "created_at": "2016-05-04T17:00:41Z", + "updated_at": "2016-05-04T17:00:41Z", + "name": "my-quota", + "apps": { + "total_memory_in_mb": 5120, + "per_process_memory_in_mb": 1024, + "log_rate_limit_in_bytes_per_second": 1024, + "total_instances": 10, + "per_app_tasks": 5 + }, + "services": { + "paid_services_allowed": true, + "total_service_instances": 10, + "total_service_keys": 20 + }, + "routes": { + "total_routes": 8, + "total_reserved_ports": 4 + }, + "domains": { + "total_domains": 7 + }, + "relationships": { + "organizations": { + "data": [ + { "guid": "9b370018-c38e-44c9-86d6-155c76801104" } + ] + } + }, + "links": { + "self": { "href": "https://api.example.org/v3/organization_quotas/24637893-3b77-489d-bb79-8466f0d88b52" } + } +} \ No newline at end of file diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/CloudFoundryClient.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/CloudFoundryClient.java index d3c0ec8164..c229b37230 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/CloudFoundryClient.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/CloudFoundryClient.java @@ -57,6 +57,7 @@ import org.cloudfoundry.client.v3.droplets.Droplets; import org.cloudfoundry.client.v3.isolationsegments.IsolationSegments; import org.cloudfoundry.client.v3.jobs.JobsV3; +import org.cloudfoundry.client.v3.organizationquotadefinitions.OrganizationQuotaDefinitionsV3; import org.cloudfoundry.client.v3.organizations.OrganizationsV3; import org.cloudfoundry.client.v3.packages.Packages; import org.cloudfoundry.client.v3.processes.Processes; @@ -188,6 +189,11 @@ public interface CloudFoundryClient { */ OrganizationQuotaDefinitions organizationQuotaDefinitions(); + /** + * Main entry point to the Cloud Foundry Quota Definitions V3 Client API + */ + OrganizationQuotaDefinitionsV3 organizationQuotaDefinitionsV3(); + /** * Main entry point to the Cloud Foundry Organizations V2 Client API */ diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/OrganizationQuotaDefinition.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/OrganizationQuotaDefinition.java new file mode 100644 index 0000000000..ca295d7e9f --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/OrganizationQuotaDefinition.java @@ -0,0 +1,68 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.cloudfoundry.Nullable; +import org.cloudfoundry.client.v3.Resource; + +/** + * Base class for responses that are organization quota definitions + */ +public abstract class OrganizationQuotaDefinition extends Resource { + + /** + * Name of the quota + */ + @JsonProperty("name") + abstract String getName(); + + /** + * Quotas that affect applications and application sub-resources + */ + @JsonProperty("apps") + @Nullable + abstract Apps getApps(); + + /** + * Quotas that affect services + */ + @JsonProperty("services") + @Nullable + abstract Services getServices(); + + /** + * Quotas that affect routes + */ + @JsonProperty("routes") + @Nullable + abstract Routes getRoutes(); + + /** + * Quotas that affect domains + */ + @JsonProperty("domains") + @Nullable + abstract Domains getDomains(); + + /** + * A relationship to the organizations where the quota is applied + */ + @JsonProperty("relationships") + @Nullable + abstract OrganizationQuotaDefinitionRelationships getRelationships(); +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/OrganizationQuotaDefinitionsV3.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/OrganizationQuotaDefinitionsV3.java new file mode 100644 index 0000000000..6a8b3eef51 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/OrganizationQuotaDefinitionsV3.java @@ -0,0 +1,72 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import reactor.core.publisher.Mono; + +/** + * Main entry point to the Cloud Foundry Organization Quota Definitions Client API + */ +public interface OrganizationQuotaDefinitionsV3 { + + /** + * Makes the Create Organization Quota Definition + * request + * + * @param request the Create Organization Quota Definition request + * @return the response from the Create Organization Quota Definition request + */ + Mono create( + CreateOrganizationQuotaDefinitionRequest request); + + /** + * Makes the Get Organization Quota Definition + * request + * + * @param request the Get Organization Quota Definition request + * @return the response from the Get Organization Quota Definition request + */ + Mono get(GetOrganizationQuotaDefinitionRequest request); + + /** + * Makes the List all Organization Quota Definitions + * request + * + * @param request the List all Organization Quota Definitions request + * @return the response from the List all Organization Quota Definitions request + */ + Mono list( + ListOrganizationQuotaDefinitionsRequest request); + + /** Makes the Update Organization Quota Definition + * request + * + * @param request the Update Organization Quota Definition request + * @return the response from the Update Organization Quota Definition request + */ + Mono update( + UpdateOrganizationQuotaDefinitionRequest request); + + /** + * Makes the Delete Organization Quota Definition + * request + * + * @param request the Delete Organization Quota Definition request + * @return the response from the Delete Organization Quota Definition request + */ + Mono delete(DeleteOrganizationQuotaDefinitionRequest request); +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Apps.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Apps.java new file mode 100644 index 0000000000..e9ca31725e --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Apps.java @@ -0,0 +1,66 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.cloudfoundry.Nullable; +import org.immutables.value.Value; + +/** + * Quotas that affect applications and application sub-resources + */ +@JsonDeserialize +@Value.Immutable +abstract class _Apps { + + /** + * Maximum memory for a single process or task + */ + @JsonProperty("per_process_memory_in_mb") + @Nullable + abstract Integer getPerProcessMemoryInMb(); + + /** + * Total memory allowed for all the started processes and running tasks in an organization + */ + @JsonProperty("total_memory_in_mb") + @Nullable + abstract Integer getTotalMemoryInMb(); + + /** + * Total instances of all the started processes allowed in an organization + */ + @JsonProperty("total_instances") + @Nullable + abstract Integer getTotalInstances(); + + /** + * Total log rate limit allowed for all the started processes and running tasks in an organization + */ + @JsonProperty("log_rate_limit_in_bytes_per_second") + @Nullable + abstract Integer getLogRateLimitInBytesPerSecond(); + + /** + * Maximum number of running tasks in an organization + */ + @JsonProperty("per_app_tasks") + @Nullable + abstract Integer getPerAppTasks(); + +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_CreateOrganizationQuotaDefinitionRequest.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_CreateOrganizationQuotaDefinitionRequest.java new file mode 100644 index 0000000000..401a3e3cb2 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_CreateOrganizationQuotaDefinitionRequest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.cloudfoundry.Nullable; +import org.immutables.value.Value; + +/** + * The request payload to creates a new organization quota + */ +@JsonSerialize +@Value.Immutable +abstract class _CreateOrganizationQuotaDefinitionRequest { + + /** + * Name of the quota + */ + @JsonProperty("name") + abstract String getName(); + + /** + * Quotas that affect applications and application sub-resources + */ + @JsonProperty("apps") + @Nullable + abstract Apps getApps(); + + /** + * Quotas that affect services + */ + @JsonProperty("services") + @Nullable + abstract Services getServices(); + + /** + * Quotas that affect routes + */ + @JsonProperty("routes") + @Nullable + abstract Routes getRoutes(); + + /** + * Quotas that affect domains + */ + @JsonProperty("domains") + @Nullable + abstract Domains getDomains(); + + /** + * A relationship to the organizations where the quota is applied + */ + @JsonProperty("relationships") + @Nullable + abstract OrganizationQuotaDefinitionRelationships getRelationships(); + +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_CreateOrganizationQuotaDefinitionResponse.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_CreateOrganizationQuotaDefinitionResponse.java new file mode 100644 index 0000000000..65eb015f87 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_CreateOrganizationQuotaDefinitionResponse.java @@ -0,0 +1,29 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.immutables.value.Value; + +/** + * The response payload for the Create an Organization Quota Definition operation + */ +@JsonDeserialize +@Value.Immutable +abstract class _CreateOrganizationQuotaDefinitionResponse extends OrganizationQuotaDefinition { + +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_DeleteOrganizationQuotaDefinitionRequest.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_DeleteOrganizationQuotaDefinitionRequest.java new file mode 100644 index 0000000000..d1ce45f83e --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_DeleteOrganizationQuotaDefinitionRequest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.immutables.value.Value; + +/** + * The request payload for the Delete an Organization Quota Definition operation + */ +@Value.Immutable +abstract class _DeleteOrganizationQuotaDefinitionRequest { + + /** + * The quota definition id + */ + @JsonIgnore + abstract String getOrganizationQuotaDefinitionId(); + +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Domains.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Domains.java new file mode 100644 index 0000000000..10e2f217bc --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Domains.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.cloudfoundry.Nullable; +import org.immutables.value.Value; + +/** + * Quotas that affect domains + */ +@JsonDeserialize +@Value.Immutable +abstract class _Domains { + + /** + * Total number of domains that can be scoped to an organization + * + * @return the total number of domains that can be scoped to an organization + */ + @JsonProperty("total_domains") + @Nullable + abstract Integer getTotalDomains(); +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_GetOrganizationQuotaDefinitionRequest.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_GetOrganizationQuotaDefinitionRequest.java new file mode 100644 index 0000000000..92bd4dee5b --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_GetOrganizationQuotaDefinitionRequest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.immutables.value.Value; + +/** + * The request payload for the Retrieve a Particular Organization Quota Definition operation + */ +@Value.Immutable +abstract class _GetOrganizationQuotaDefinitionRequest { + + /** + * The quota definition id + */ + @JsonIgnore + abstract String getOrganizationQuotaDefinitionId(); + +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_GetOrganizationQuotaDefinitionResponse.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_GetOrganizationQuotaDefinitionResponse.java new file mode 100644 index 0000000000..c98b39ecb2 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_GetOrganizationQuotaDefinitionResponse.java @@ -0,0 +1,29 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.immutables.value.Value; + +/** + * The response payload for the Retrieve a Particular Organization Quota Definition operation + */ +@JsonDeserialize +@Value.Immutable +abstract class _GetOrganizationQuotaDefinitionResponse extends OrganizationQuotaDefinition { + +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_ListOrganizationQuotaDefinitionsRequest.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_ListOrganizationQuotaDefinitionsRequest.java new file mode 100644 index 0000000000..d5102ed43a --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_ListOrganizationQuotaDefinitionsRequest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import org.cloudfoundry.Nullable; +import org.cloudfoundry.client.v3.FilterParameter; +import org.cloudfoundry.client.v3.PaginatedRequest; +import org.immutables.value.Value; + +import java.util.List; + +/** + * The request payload for the List all Organization Quota Definitions operation + */ +@Value.Immutable +abstract class _ListOrganizationQuotaDefinitionsRequest extends PaginatedRequest { + + /** + * list of organization quota guids to filter by + */ + @FilterParameter("guids") + @Nullable + abstract List getGuids(); + + /** + * list of organization quota names to filter by + */ + @FilterParameter("names") + @Nullable + abstract List getNames(); + + /** + * list of organization guids to filter by + */ + @FilterParameter("organization_guids") + @Nullable + abstract List getOrganizationGuids(); + +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_ListOrganizationQuotaDefinitionsResponse.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_ListOrganizationQuotaDefinitionsResponse.java new file mode 100644 index 0000000000..504b93fff8 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_ListOrganizationQuotaDefinitionsResponse.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.cloudfoundry.client.v3.PaginatedResponse; +import org.immutables.value.Value; + +/** + * The response payload for the List all Organization Quota Definitions operation + */ +@JsonDeserialize +@Value.Immutable +abstract class _ListOrganizationQuotaDefinitionsResponse extends PaginatedResponse { + +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_OrganizationQuotaDefinitionRelationships.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_OrganizationQuotaDefinitionRelationships.java new file mode 100644 index 0000000000..4e677758c1 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_OrganizationQuotaDefinitionRelationships.java @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.cloudfoundry.Nullable; +import org.cloudfoundry.client.v3.ToManyRelationship; +import org.immutables.value.Value; + +/** + * The relationships for the OrganizationQuotaDefinition entity + */ + +@Value.Immutable +@JsonDeserialize +abstract class _OrganizationQuotaDefinitionRelationships { + + /** + * The quota relationship + */ + @JsonProperty("organizations") + @Nullable + abstract ToManyRelationship getOrganizations(); + +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_OrganizationQuotaDefinitionResource.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_OrganizationQuotaDefinitionResource.java new file mode 100644 index 0000000000..edebd290e8 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_OrganizationQuotaDefinitionResource.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.immutables.value.Value; + +/** + * Base class for resources that contain Organization Quota Definitions + */ +@JsonDeserialize +@Value.Immutable +abstract class _OrganizationQuotaDefinitionResource extends OrganizationQuotaDefinition { + +} + diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Routes.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Routes.java new file mode 100644 index 0000000000..9ca4398379 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Routes.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.cloudfoundry.Nullable; +import org.immutables.value.Value; + +/** + * Quotas that affect routes + */ +@JsonDeserialize +@Value.Immutable +abstract class _Routes { + + /** + * Total number of routes allowed in an organization + * + * @return the total number of routes allowed in an organization + */ + @JsonProperty("total_routes") + @Nullable + abstract Integer getTotalRoutes(); + + /** + * Total number of ports that are reservable by routes in an organization + * + * @return the total number of reserved ports allowed in an organization + */ + @JsonProperty("total_reserved_ports") + @Nullable + abstract Integer getTotalReservedPorts(); + +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Services.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Services.java new file mode 100644 index 0000000000..2e7e96cb13 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_Services.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.cloudfoundry.Nullable; +import org.immutables.value.Value; + +/** + * Quotas that affect services + */ +@JsonDeserialize +@Value.Immutable +abstract class _Services { + + /** + * Specifies whether instances of paid service plans can be created + * @return true if instances of paid service plans can be created, false otherwise + */ + @JsonProperty("paid_services_allowed") + abstract boolean isPaidServicesAllowed(); + + /** + * Total number of service instances allowed in an organization + * @return the total number of service instances allowed in an organization + */ + @JsonProperty("total_service_instances") + @Nullable + abstract Integer getTotalServiceInstances(); + + /** + * Total number of service keys allowed in an organization + * @return the total number of service keys allowed in an organization + */ + @JsonProperty("total_service_keys") + @Nullable + abstract Integer getTotalServiceKeys(); +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_UpdateOrganizationQuotaDefinitionRequest.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_UpdateOrganizationQuotaDefinitionRequest.java new file mode 100644 index 0000000000..ed9f950cb0 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_UpdateOrganizationQuotaDefinitionRequest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.cloudfoundry.Nullable; +import org.immutables.value.Value; + +/** + * The request payload to update an organization quota + */ +@JsonSerialize +@Value.Immutable +abstract class _UpdateOrganizationQuotaDefinitionRequest { + + /** + * The quota definition id + */ + @JsonIgnore + abstract String getOrganizationQuotaDefinitionId(); + + /** + * Name of the quota + */ + @JsonProperty("name") + @Nullable + abstract String getName(); + + /** + * Quotas that affect applications and application sub-resources + */ + @JsonProperty("apps") + @Nullable + abstract Apps getApps(); + + /** + * Quotas that affect services + */ + @JsonProperty("services") + @Nullable + abstract Services getServices(); + + /** + * Quotas that affect routes + */ + @JsonProperty("routes") + @Nullable + abstract Routes getRoutes(); + + /** + * Quotas that affect domains + */ + @JsonProperty("domains") + @Nullable + abstract Domains getDomains(); +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_UpdateOrganizationQuotaDefinitionResponse.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_UpdateOrganizationQuotaDefinitionResponse.java new file mode 100644 index 0000000000..0bb4f02ed7 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/organizationquotadefinitions/_UpdateOrganizationQuotaDefinitionResponse.java @@ -0,0 +1,29 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.immutables.value.Value; + +/** + * The response payload for the Update an Organization Quota Definition operation + */ +@JsonDeserialize +@Value.Immutable +abstract class _UpdateOrganizationQuotaDefinitionResponse extends OrganizationQuotaDefinition { + +} diff --git a/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/CreateOrganizationQuotaDefinitionRequestTest.java b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/CreateOrganizationQuotaDefinitionRequestTest.java new file mode 100644 index 0000000000..ea2c622021 --- /dev/null +++ b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/CreateOrganizationQuotaDefinitionRequestTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +final class CreateOrganizationQuotaDefinitionRequestTest { + + @Test + void noName() { + assertThrows( + IllegalStateException.class, + () -> CreateOrganizationQuotaDefinitionRequest.builder().build()); + } + + @Test + void valid() { + CreateOrganizationQuotaDefinitionRequest.builder().name("test-quota").build(); + } +} diff --git a/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/DeleteOrganizationQuotaDefinitionRequestTest.java b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/DeleteOrganizationQuotaDefinitionRequestTest.java new file mode 100644 index 0000000000..b1743c58f2 --- /dev/null +++ b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/DeleteOrganizationQuotaDefinitionRequestTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +final class DeleteOrganizationQuotaDefinitionRequestTest { + + @Test + void noOrganizationId() { + assertThrows( + IllegalStateException.class, + () -> DeleteOrganizationQuotaDefinitionRequest.builder().build()); + } + + @Test + void valid() { + DeleteOrganizationQuotaDefinitionRequest.builder() + .organizationQuotaDefinitionId("test-id") + .build(); + } +} diff --git a/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/GetOrganizationQuotaDefinitionRequestTest.java b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/GetOrganizationQuotaDefinitionRequestTest.java new file mode 100644 index 0000000000..dd52243e8a --- /dev/null +++ b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/GetOrganizationQuotaDefinitionRequestTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +final class GetOrganizationQuotaDefinitionRequestTest { + + @Test + void noOrganizationQuotaDefinitionId() { + assertThrows( + IllegalStateException.class, + () -> GetOrganizationQuotaDefinitionRequest.builder().build()); + } + + @Test + void valid() { + GetOrganizationQuotaDefinitionRequest.builder() + .organizationQuotaDefinitionId("test-id") + .build(); + } +} diff --git a/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/ListOrganizationQuotaDefinitionsRequestTest.java b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/ListOrganizationQuotaDefinitionsRequestTest.java new file mode 100644 index 0000000000..03054a4060 --- /dev/null +++ b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/ListOrganizationQuotaDefinitionsRequestTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import org.junit.jupiter.api.Test; + +public class ListOrganizationQuotaDefinitionsRequestTest { + + @Test + void valid() { + ListOrganizationQuotaDefinitionsRequest.builder().build(); + } +} diff --git a/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/UpdateOrganizationQuotaDefinitionRequestTest.java b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/UpdateOrganizationQuotaDefinitionRequestTest.java new file mode 100644 index 0000000000..21c82d6005 --- /dev/null +++ b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/organizationquotadefinitions/UpdateOrganizationQuotaDefinitionRequestTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2025 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.client.v3.organizationquotadefinitions; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +final class UpdateOrganizationQuotaDefinitionRequestTest { + + @Test + void noOrganizationQuotaDefinitionId() { + assertThrows( + IllegalStateException.class, + () -> UpdateOrganizationQuotaDefinitionRequest.builder().build()); + } + + @Test + void valid() { + UpdateOrganizationQuotaDefinitionRequest.builder() + .organizationQuotaDefinitionId("test-id") + .build(); + } +} diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/OrganizationQuotaDefinitionsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/OrganizationQuotaDefinitionsTest.java new file mode 100644 index 0000000000..38e1808747 --- /dev/null +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/OrganizationQuotaDefinitionsTest.java @@ -0,0 +1,247 @@ +/* + * Copyright 2013-2021 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.client.v3; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Duration; +import org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.CloudFoundryVersion; +import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.client.CloudFoundryClient; +import org.cloudfoundry.client.v3.organizationquotadefinitions.Apps; +import org.cloudfoundry.client.v3.organizationquotadefinitions.CreateOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.CreateOrganizationQuotaDefinitionResponse; +import org.cloudfoundry.client.v3.organizationquotadefinitions.DeleteOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.GetOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.GetOrganizationQuotaDefinitionResponse; +import org.cloudfoundry.client.v3.organizationquotadefinitions.ListOrganizationQuotaDefinitionsRequest; +import org.cloudfoundry.client.v3.organizationquotadefinitions.OrganizationQuotaDefinitionResource; +import org.cloudfoundry.client.v3.organizationquotadefinitions.Routes; +import org.cloudfoundry.client.v3.organizationquotadefinitions.Services; +import org.cloudfoundry.client.v3.organizationquotadefinitions.UpdateOrganizationQuotaDefinitionRequest; +import org.cloudfoundry.util.JobUtils; +import org.cloudfoundry.util.PaginationUtils; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +@IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_2_8) +public final class OrganizationQuotaDefinitionsTest extends AbstractIntegrationTest { + + @Autowired private CloudFoundryClient cloudFoundryClient; + + @Test + public void create() { + String organizationQuotaName = this.nameFactory.getQuotaDefinitionName(); + Apps organizationQuotaAppLimits = + Apps.builder() + .perProcessMemoryInMb(1024) + .totalMemoryInMb(2048) + .logRateLimitInBytesPerSecond(0) + .build(); + Services organizationQuotaServiceLimits = + Services.builder().isPaidServicesAllowed(false).totalServiceInstances(10).build(); + Routes organizationQuotaRouteLimits = Routes.builder().totalRoutes(10).build(); + this.cloudFoundryClient + .organizationQuotaDefinitionsV3() + .create( + CreateOrganizationQuotaDefinitionRequest.builder() + .name(organizationQuotaName) + .apps(organizationQuotaAppLimits) + .services(organizationQuotaServiceLimits) + .routes(organizationQuotaRouteLimits) + .build()) + .thenMany( + requestListOrganizationQuotas( + this.cloudFoundryClient, organizationQuotaName)) + .single() + .as(StepVerifier::create) + .assertNext( + organizationQuotaDefinitionResource -> { + assertThat(organizationQuotaDefinitionResource).isNotNull(); + assertThat(organizationQuotaDefinitionResource.getId()).isNotNull(); + assertThat(organizationQuotaDefinitionResource.getName()) + .isEqualTo(organizationQuotaName); + assertThat(organizationQuotaDefinitionResource.getApps()) + .isEqualTo(organizationQuotaAppLimits); + assertThat(organizationQuotaDefinitionResource.getServices()) + .isEqualTo(organizationQuotaServiceLimits); + assertThat(organizationQuotaDefinitionResource.getRoutes()) + .isEqualTo(organizationQuotaRouteLimits); + }) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + @Test + public void delete() { + String organizationQuotaName = this.nameFactory.getQuotaDefinitionName(); + + createOrganizationQuotaId(this.cloudFoundryClient, organizationQuotaName) + .flatMap( + organizationQuotaId -> + this.cloudFoundryClient + .organizationQuotaDefinitionsV3() + .delete( + DeleteOrganizationQuotaDefinitionRequest.builder() + .organizationQuotaDefinitionId( + organizationQuotaId) + .build()) + .flatMap( + job -> + JobUtils.waitForCompletion( + this.cloudFoundryClient, + Duration.ofMinutes(5), + job))) + .thenMany( + requestListOrganizationQuotas( + this.cloudFoundryClient, organizationQuotaName)) + .as(StepVerifier::create) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + @Test + public void get() { + String organizationQuotaName = this.nameFactory.getQuotaDefinitionName(); + + createOrganizationQuotaId(this.cloudFoundryClient, organizationQuotaName) + .flatMap( + organizationQuotaId -> + this.cloudFoundryClient + .organizationQuotaDefinitionsV3() + .get( + GetOrganizationQuotaDefinitionRequest.builder() + .organizationQuotaDefinitionId( + organizationQuotaId) + .build())) + .map(GetOrganizationQuotaDefinitionResponse::getName) + .as(StepVerifier::create) + .expectNext(organizationQuotaName) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + @Test + public void list() { + String organizationQuotaName = this.nameFactory.getQuotaDefinitionName(); + + createOrganizationQuota(this.cloudFoundryClient, organizationQuotaName) + .thenMany( + PaginationUtils.requestClientV3Resources( + page -> + this.cloudFoundryClient + .organizationQuotaDefinitionsV3() + .list( + ListOrganizationQuotaDefinitionsRequest + .builder() + .page(page) + .build()))) + .filter(resource -> organizationQuotaName.equals(resource.getName())) + .as(StepVerifier::create) + .expectNextCount(1) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + @Test + public void update() { + String organizationQuotaName = this.nameFactory.getQuotaDefinitionName(); + int totalMemoryLimit = 64 * 1024; // 64 GB + + createOrganizationQuotaId(this.cloudFoundryClient, organizationQuotaName) + .flatMap( + organizationQuotaId -> + this.cloudFoundryClient + .organizationQuotaDefinitionsV3() + .update( + UpdateOrganizationQuotaDefinitionRequest.builder() + .organizationQuotaDefinitionId( + organizationQuotaId) + .apps( + Apps.builder() + .totalMemoryInMb( + totalMemoryLimit) + .build()) + .routes( + Routes.builder() + .totalRoutes(100) + .build()) + .services( + Services.builder() + .isPaidServicesAllowed(true) + .totalServiceInstances(100) + .build()) + .build())) + .thenMany( + requestListOrganizationQuotas( + this.cloudFoundryClient, organizationQuotaName)) + .as(StepVerifier::create) + .consumeNextWith( + organizationQuotaDefinitionResource -> { + assertThat( + organizationQuotaDefinitionResource + .getApps() + .getTotalMemoryInMb()) + .isEqualTo(totalMemoryLimit); + assertThat( + organizationQuotaDefinitionResource + .getRoutes() + .getTotalRoutes()) + .isEqualTo(100); + assertThat( + organizationQuotaDefinitionResource + .getServices() + .getTotalServiceInstances()) + .isEqualTo(100); + }) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + private static Mono createOrganizationQuotaId( + CloudFoundryClient cloudFoundryClient, String organizationQuotaName) { + return createOrganizationQuota(cloudFoundryClient, organizationQuotaName) + .map(CreateOrganizationQuotaDefinitionResponse::getId); + } + + private static Mono createOrganizationQuota( + CloudFoundryClient cloudFoundryClient, String organizationQuotaName) { + return cloudFoundryClient + .organizationQuotaDefinitionsV3() + .create( + CreateOrganizationQuotaDefinitionRequest.builder() + .name(organizationQuotaName) + .build()); + } + + private static Flux requestListOrganizationQuotas( + CloudFoundryClient cloudFoundryClient, String organizationName) { + return PaginationUtils.requestClientV3Resources( + page -> + cloudFoundryClient + .organizationQuotaDefinitionsV3() + .list( + ListOrganizationQuotaDefinitionsRequest.builder() + .name(organizationName) + .page(page) + .build())); + } +}