From 60e6090232c12dd9b388054c38a3f8e1b1cd5930 Mon Sep 17 00:00:00 2001 From: Rangel Ivanov Date: Tue, 28 Jun 2022 14:48:39 +0300 Subject: [PATCH] Re-implement V3 Service Bindings --- .../client/v3/AbstractClientV3Operations.java | 6 +- .../ReactorServiceBindingsV3.java | 40 +- .../ReactorServiceBindingsV3Test.java | 109 ++--- .../v3/servicebindings/GET_response.json | 38 +- .../v3/servicebindings/GET_{id}_response.json | 16 +- .../v3/servicebindings/POST_request.json | 13 +- .../v3/servicebindings/POST_response.json | 23 -- .../v3/servicebindings/ServiceBinding.java | 29 +- .../servicebindings/ServiceBindingType.java | 9 +- .../v3/servicebindings/ServiceBindingsV3.java | 34 +- .../_CreateServiceBindingRequest.java | 32 +- .../_CreateServiceBindingResponse.java | 10 +- ... => _GetServiceBindingDetailsRequest.java} | 20 +- ...=> _GetServiceBindingDetailsResponse.java} | 18 +- .../_GetServiceBindingParametersRequest.java | 34 ++ .../_GetServiceBindingParametersResponse.java | 60 +++ .../_GetServiceBindingRequest.java | 1 - .../_ListServiceBindingsRequest.java | 61 ++- .../_ServiceBindingRelationships.java | 10 +- .../_UpdateServiceBindingRequest.java | 45 ++ .../_UpdateServiceBindingResponse.java} | 18 +- .../CreateServiceBindingRequestTest.java | 26 +- .../v3/servicebindings/RelationshipsTest.java | 27 +- .../client/v3/ApplicationsTest.java | 2 +- .../client/v3/ServiceBindingsTest.java | 384 ++++++++++++++++++ 25 files changed, 883 insertions(+), 182 deletions(-) delete mode 100644 cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/POST_response.json rename cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/{_CreateServiceBindingData.java => _GetServiceBindingDetailsRequest.java} (61%) rename cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/{_ServiceBindingData.java => _GetServiceBindingDetailsResponse.java} (79%) create mode 100644 cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingParametersRequest.java create mode 100644 cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingParametersResponse.java create mode 100644 cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_UpdateServiceBindingRequest.java rename cloudfoundry-client/src/{test/java/org/cloudfoundry/client/v3/servicebindings/CreateServiceBindingDataTest.java => main/java/org/cloudfoundry/client/v3/servicebindings/_UpdateServiceBindingResponse.java} (65%) create mode 100644 integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBindingsTest.java diff --git a/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/v3/AbstractClientV3Operations.java b/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/v3/AbstractClientV3Operations.java index 25bc8d35cdc..665c6a9fa88 100644 --- a/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/v3/AbstractClientV3Operations.java +++ b/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/v3/AbstractClientV3Operations.java @@ -62,7 +62,7 @@ protected final Mono delete(Object requestPayload, Function Mono.justOrEmpty(extractJobId(response))); } protected final Mono> deleteWithResponse(Object requestPayload, Class responseType, @@ -141,7 +141,7 @@ protected Mono post(Object requestPayload, Class responseType, Functio } protected final Mono> postWithResponse(Object requestPayload, Class responseType, - Function uriTransformer) { + Function uriTransformer) { return createOperator() .flatMap(operator -> operator.post() .uri(queryTransformer(requestPayload).andThen(uriTransformer)) @@ -157,7 +157,7 @@ protected final Mono post(Object requestPayload, Function Mono.justOrEmpty(extractJobId(response))); } protected final Mono put(Object requestPayload, Class responseType, Function uriTransformer) { diff --git a/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/v3/servicebindings/ReactorServiceBindingsV3.java b/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/v3/servicebindings/ReactorServiceBindingsV3.java index 7e2086d2f24..0992563e4ed 100644 --- a/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/v3/servicebindings/ReactorServiceBindingsV3.java +++ b/cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/v3/servicebindings/ReactorServiceBindingsV3.java @@ -19,17 +19,25 @@ import org.cloudfoundry.client.v3.servicebindings.CreateServiceBindingRequest; import org.cloudfoundry.client.v3.servicebindings.CreateServiceBindingResponse; import org.cloudfoundry.client.v3.servicebindings.DeleteServiceBindingRequest; +import org.cloudfoundry.client.v3.servicebindings.GetServiceBindingDetailsRequest; +import org.cloudfoundry.client.v3.servicebindings.GetServiceBindingDetailsResponse; +import org.cloudfoundry.client.v3.servicebindings.GetServiceBindingParametersRequest; +import org.cloudfoundry.client.v3.servicebindings.GetServiceBindingParametersResponse; import org.cloudfoundry.client.v3.servicebindings.GetServiceBindingRequest; import org.cloudfoundry.client.v3.servicebindings.GetServiceBindingResponse; import org.cloudfoundry.client.v3.servicebindings.ListServiceBindingsRequest; import org.cloudfoundry.client.v3.servicebindings.ListServiceBindingsResponse; +import org.cloudfoundry.client.v3.servicebindings.ServiceBindingResource; import org.cloudfoundry.client.v3.servicebindings.ServiceBindingsV3; +import org.cloudfoundry.client.v3.servicebindings.UpdateServiceBindingRequest; +import org.cloudfoundry.client.v3.servicebindings.UpdateServiceBindingResponse; import org.cloudfoundry.reactor.ConnectionContext; import org.cloudfoundry.reactor.TokenProvider; import org.cloudfoundry.reactor.client.v3.AbstractClientV3Operations; import reactor.core.publisher.Mono; import java.util.Map; +import java.util.Optional; /** * The Reactor-based implementation of {@link ServiceBindingsV3} @@ -50,25 +58,47 @@ public ReactorServiceBindingsV3(ConnectionContext connectionContext, Mono create(CreateServiceBindingRequest request) { - return post(request, CreateServiceBindingResponse.class, builder -> builder.pathSegment("service_bindings")) + return postWithResponse(request, ServiceBindingResource.class, builder -> builder.pathSegment("service_credential_bindings")) + .map(responseTuple -> CreateServiceBindingResponse.builder() + .serviceBinding(responseTuple.getBody()) + .jobId(Optional.ofNullable(extractJobId(responseTuple.getResponse()))) + .build()) .checkpoint(); } @Override - public Mono delete(DeleteServiceBindingRequest request) { - return delete(request, Void.class, builder -> builder.pathSegment("service_bindings", request.getServiceBindingId())) + public Mono delete(DeleteServiceBindingRequest request) { + return delete(request, builder -> builder.pathSegment("service_credential_bindings", request.getServiceBindingId())) .checkpoint(); } @Override public Mono get(GetServiceBindingRequest request) { - return get(request, GetServiceBindingResponse.class, builder -> builder.pathSegment("service_bindings", request.getServiceBindingId())) + return get(request, GetServiceBindingResponse.class, builder -> builder.pathSegment("service_credential_bindings", request.getServiceBindingId())) + .checkpoint(); + } + + @Override + public Mono getDetails(GetServiceBindingDetailsRequest request) { + return get(request, GetServiceBindingDetailsResponse.class, builder -> builder.pathSegment("service_credential_bindings", request.getServiceBindingId(), "details")) + .checkpoint(); + } + + @Override + public Mono getParameters(GetServiceBindingParametersRequest request) { + return get(request, GetServiceBindingParametersResponse.class, builder -> builder.pathSegment("service_credential_bindings", request.getServiceBindingId(), "parameters")) .checkpoint(); } @Override public Mono list(ListServiceBindingsRequest request) { - return get(request, ListServiceBindingsResponse.class, builder -> builder.pathSegment("service_bindings")) + return get(request, ListServiceBindingsResponse.class, builder -> builder.pathSegment("service_credential_bindings")) + .checkpoint(); + } + + @Override + public Mono update(UpdateServiceBindingRequest request) { + return patch(request, UpdateServiceBindingResponse.class, builder -> builder.pathSegment("service_credential_bindings", request.getServiceBindingId())) .checkpoint(); } diff --git a/cloudfoundry-client-reactor/src/test/java/org/cloudfoundry/reactor/client/v3/servicebindings/ReactorServiceBindingsV3Test.java b/cloudfoundry-client-reactor/src/test/java/org/cloudfoundry/reactor/client/v3/servicebindings/ReactorServiceBindingsV3Test.java index 3a22f82633a..70f5b32ecc2 100644 --- a/cloudfoundry-client-reactor/src/test/java/org/cloudfoundry/reactor/client/v3/servicebindings/ReactorServiceBindingsV3Test.java +++ b/cloudfoundry-client-reactor/src/test/java/org/cloudfoundry/reactor/client/v3/servicebindings/ReactorServiceBindingsV3Test.java @@ -19,7 +19,7 @@ import org.cloudfoundry.client.v3.Link; import org.cloudfoundry.client.v3.Pagination; import org.cloudfoundry.client.v3.Relationship; -import org.cloudfoundry.client.v3.servicebindings.CreateServiceBindingData; +import org.cloudfoundry.client.v3.ToOneRelationship; import org.cloudfoundry.client.v3.servicebindings.CreateServiceBindingRequest; import org.cloudfoundry.client.v3.servicebindings.CreateServiceBindingResponse; import org.cloudfoundry.client.v3.servicebindings.DeleteServiceBindingRequest; @@ -27,7 +27,6 @@ import org.cloudfoundry.client.v3.servicebindings.GetServiceBindingResponse; import org.cloudfoundry.client.v3.servicebindings.ListServiceBindingsRequest; import org.cloudfoundry.client.v3.servicebindings.ListServiceBindingsResponse; -import org.cloudfoundry.client.v3.servicebindings.ServiceBindingData; import org.cloudfoundry.client.v3.servicebindings.ServiceBindingRelationships; import org.cloudfoundry.client.v3.servicebindings.ServiceBindingResource; import org.cloudfoundry.client.v3.servicebindings.ServiceBindingType; @@ -44,7 +43,7 @@ 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.POST; -import static io.netty.handler.codec.http.HttpResponseStatus.CREATED; +import static io.netty.handler.codec.http.HttpResponseStatus.ACCEPTED; import static io.netty.handler.codec.http.HttpResponseStatus.NO_CONTENT; import static io.netty.handler.codec.http.HttpResponseStatus.OK; @@ -56,48 +55,34 @@ public final class ReactorServiceBindingsV3Test extends AbstractClientApiTest { public void create() { mockRequest(InteractionContext.builder() .request(TestRequest.builder() - .method(POST).path("/service_bindings") + .method(POST).path("/service_credential_bindings") .payload("fixtures/client/v3/servicebindings/POST_request.json") .build()) .response(TestResponse.builder() - .status(CREATED) - .payload("fixtures/client/v3/servicebindings/POST_response.json") + .status(ACCEPTED) + .header("Location", "https://api.example.org/v3/jobs/af5c57f6-8769-41fa-a499-2c84ed896788") .build()) .build()); this.serviceBindings .create(CreateServiceBindingRequest.builder() - .data(CreateServiceBindingData.builder() - .parameter("some_object_id", "for_the_service_broker") - .build()) .relationships(ServiceBindingRelationships.builder() - .application(Relationship.builder() - .id("74f7c078-0934-470f-9883-4fddss5b8f13") + .application(ToOneRelationship.builder() + .data(Relationship.builder() + .id("74f7c078-0934-470f-9883-4fddss5b8f13") + .build()) .build()) - .serviceInstance(Relationship.builder() - .id("8bfe4c1b-9e18-45b1-83be-124163f31f9e") + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id("8bfe4c1b-9e18-45b1-83be-124163f31f9e") + .build()) .build()) .build()) .type(ServiceBindingType.APPLICATION) .build()) .as(StepVerifier::create) .expectNext(CreateServiceBindingResponse.builder() - .id("dde5ad2a-d8f4-44dc-a56f-0452d744f1c3") - .type("app") - .data(ServiceBindingData.builder() - .credential("super-secret", "password") - .syslogDrainUrl("syslog://drain.url.com") - .build()) - .createdAt("2015-11-13T17:02:56Z") - .link("self", Link.builder() - .href("/v3/service_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3") - .build()) - .link("service_instance", Link.builder() - .href("/v3/service_instances/8bfe4c1b-9e18-45b1-83be-124163f31f9e") - .build()) - .link("app", Link.builder() - .href("/v3/apps/74f7c078-0934-470f-9883-4fddss5b8f13") - .build()) + .jobId("af5c57f6-8769-41fa-a499-2c84ed896788") .build()) .expectComplete() .verify(Duration.ofSeconds(5)); @@ -107,7 +92,7 @@ public void create() { public void delete() { mockRequest(InteractionContext.builder() .request(TestRequest.builder() - .method(DELETE).path("/service_bindings/test-service-binding-id") + .method(DELETE).path("/service_credential_bindings/test-service-binding-id") .build()) .response(TestResponse.builder() .status(NO_CONTENT) @@ -127,7 +112,7 @@ public void delete() { public void get() { mockRequest(InteractionContext.builder() .request(TestRequest.builder() - .method(GET).path("/service_bindings/test-service-binding-id") + .method(GET).path("/service_credential_bindings/test-service-binding-id") .build()) .response(TestResponse.builder() .status(OK) @@ -142,14 +127,22 @@ public void get() { .as(StepVerifier::create) .expectNext(GetServiceBindingResponse.builder() .id("dde5ad2a-d8f4-44dc-a56f-0452d744f1c3") - .type("app") - .data(ServiceBindingData.builder() - .credential("super-secret", "password") - .syslogDrainUrl("syslog://drain.url.com") + .type(ServiceBindingType.APPLICATION) + .relationships(ServiceBindingRelationships.builder() + .application(ToOneRelationship.builder() + .data(Relationship.builder() + .id("74f7c078-0934-470f-9883-4fddss5b8f13") + .build()) + .build()) + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id("8bfe4c1b-9e18-45b1-83be-124163f31f9e") + .build()) + .build()) .build()) .createdAt("2015-11-13T17:02:56Z") .link("self", Link.builder() - .href("/v3/service_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3") + .href("/v3/service_credential_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3") .build()) .link("service_instance", Link.builder() .href("/v3/service_instances/8bfe4c1b-9e18-45b1-83be-124163f31f9e") @@ -166,7 +159,7 @@ public void get() { public void list() { mockRequest(InteractionContext.builder() .request(TestRequest.builder() - .method(GET).path("/service_bindings?app_guids=test-application-id&order_by=%2Bcreated_at&page=1") + .method(GET).path("/service_credential_bindings?app_guids=test-application-id&order_by=%2Bcreated_at&page=1") .build()) .response(TestResponse.builder() .status(OK) @@ -185,25 +178,33 @@ public void list() { .pagination(Pagination.builder() .totalResults(3) .first(Link.builder() - .href("/v3/service_bindings?page=1&per_page=2") + .href("/v3/service_credential_bindings?page=1&per_page=2") .build()) .last(Link.builder() - .href("/v3/service_bindings?page=2&per_page=2") + .href("/v3/service_credential_bindings?page=2&per_page=2") .build()) .next(Link.builder() - .href("/v3/service_bindings?page=2&per_page=2") + .href("/v3/service_credential_bindings?page=2&per_page=2") .build()) .build()) .resource(ServiceBindingResource.builder() .id("dde5ad2a-d8f4-44dc-a56f-0452d744f1c3") - .type("app") - .data(ServiceBindingData.builder() - .credential("super-secret", "password") - .syslogDrainUrl("syslog://drain.url.com") + .type(ServiceBindingType.APPLICATION) + .relationships(ServiceBindingRelationships.builder() + .application(ToOneRelationship.builder() + .data(Relationship.builder() + .id("74f7c078-0934-470f-9883-4fddss5b8f13") + .build()) + .build()) + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id("8bfe4c1b-9e18-45b1-83be-124163f31f9e") + .build()) + .build()) .build()) .createdAt("2015-11-13T17:02:56Z") .link("self", Link.builder() - .href("/v3/service_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3") + .href("/v3/service_credential_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3") .build()) .link("service_instance", Link.builder() .href("/v3/service_instances/8bfe4c1b-9e18-45b1-83be-124163f31f9e") @@ -214,14 +215,22 @@ public void list() { .build()) .resource(ServiceBindingResource.builder() .id("7aa37bad-6ccb-4ef9-ba48-9ce3a91b2b62") - .type("app") - .data(ServiceBindingData.builder() - .credential("super-secret", "password") - .syslogDrainUrl("syslog://drain.url.com") + .type(ServiceBindingType.APPLICATION) + .relationships(ServiceBindingRelationships.builder() + .application(ToOneRelationship.builder() + .data(Relationship.builder() + .id("74f7c078-0934-470f-9883-4fddss5b8f13") + .build()) + .build()) + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id("8bf356j3-9e18-45b1-3333-124163f31f9e") + .build()) + .build()) .build()) .createdAt("2015-11-13T17:02:56Z") .link("self", Link.builder() - .href("/v3/service_bindings/7aa37bad-6ccb-4ef9-ba48-9ce3a91b2b62") + .href("/v3/service_credential_bindings/7aa37bad-6ccb-4ef9-ba48-9ce3a91b2b62") .build()) .link("service_instance", Link.builder() .href("/v3/service_instances/8bf356j3-9e18-45b1-3333-124163f31f9e") diff --git a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/GET_response.json b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/GET_response.json index 9e0714d62e0..f3c7b24e152 100644 --- a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/GET_response.json +++ b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/GET_response.json @@ -2,13 +2,13 @@ "pagination": { "total_results": 3, "first": { - "href": "/v3/service_bindings?page=1&per_page=2" + "href": "/v3/service_credential_bindings?page=1&per_page=2" }, "last": { - "href": "/v3/service_bindings?page=2&per_page=2" + "href": "/v3/service_credential_bindings?page=2&per_page=2" }, "next": { - "href": "/v3/service_bindings?page=2&per_page=2" + "href": "/v3/service_credential_bindings?page=2&per_page=2" }, "previous": null }, @@ -16,17 +16,23 @@ { "guid": "dde5ad2a-d8f4-44dc-a56f-0452d744f1c3", "type": "app", - "data": { - "credentials": { - "super-secret": "password" + "relationships": { + "app": { + "data": { + "guid": "74f7c078-0934-470f-9883-4fddss5b8f13" + } }, - "syslog_drain_url": "syslog://drain.url.com" + "service_instance": { + "data": { + "guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e" + } + } }, "created_at": "2015-11-13T17:02:56Z", "updated_at": null, "links": { "self": { - "href": "/v3/service_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3" + "href": "/v3/service_credential_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3" }, "service_instance": { "href": "/v3/service_instances/8bfe4c1b-9e18-45b1-83be-124163f31f9e" @@ -39,17 +45,23 @@ { "guid": "7aa37bad-6ccb-4ef9-ba48-9ce3a91b2b62", "type": "app", - "data": { - "credentials": { - "super-secret": "password" + "relationships": { + "app": { + "data": { + "guid": "74f7c078-0934-470f-9883-4fddss5b8f13" + } }, - "syslog_drain_url": "syslog://drain.url.com" + "service_instance": { + "data": { + "guid": "8bf356j3-9e18-45b1-3333-124163f31f9e" + } + } }, "created_at": "2015-11-13T17:02:56Z", "updated_at": null, "links": { "self": { - "href": "/v3/service_bindings/7aa37bad-6ccb-4ef9-ba48-9ce3a91b2b62" + "href": "/v3/service_credential_bindings/7aa37bad-6ccb-4ef9-ba48-9ce3a91b2b62" }, "service_instance": { "href": "/v3/service_instances/8bf356j3-9e18-45b1-3333-124163f31f9e" diff --git a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/GET_{id}_response.json b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/GET_{id}_response.json index 9087c366948..790344cbaf6 100644 --- a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/GET_{id}_response.json +++ b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/GET_{id}_response.json @@ -1,17 +1,23 @@ { "guid": "dde5ad2a-d8f4-44dc-a56f-0452d744f1c3", "type": "app", - "data": { - "credentials": { - "super-secret": "password" + "relationships": { + "app": { + "data": { + "guid": "74f7c078-0934-470f-9883-4fddss5b8f13" + } }, - "syslog_drain_url": "syslog://drain.url.com" + "service_instance": { + "data": { + "guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e" + } + } }, "created_at": "2015-11-13T17:02:56Z", "updated_at": null, "links": { "self": { - "href": "/v3/service_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3" + "href": "/v3/service_credential_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3" }, "service_instance": { "href": "/v3/service_instances/8bfe4c1b-9e18-45b1-83be-124163f31f9e" diff --git a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/POST_request.json b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/POST_request.json index c235529edf2..ebb8b0febd3 100644 --- a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/POST_request.json +++ b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/POST_request.json @@ -2,15 +2,14 @@ "type": "app", "relationships": { "app": { - "guid": "74f7c078-0934-470f-9883-4fddss5b8f13" + "data": { + "guid": "74f7c078-0934-470f-9883-4fddss5b8f13" + } }, "service_instance": { - "guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e" - } - }, - "data": { - "parameters": { - "some_object_id": "for_the_service_broker" + "data": { + "guid": "8bfe4c1b-9e18-45b1-83be-124163f31f9e" + } } } } \ No newline at end of file diff --git a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/POST_response.json b/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/POST_response.json deleted file mode 100644 index 9087c366948..00000000000 --- a/cloudfoundry-client-reactor/src/test/resources/fixtures/client/v3/servicebindings/POST_response.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "guid": "dde5ad2a-d8f4-44dc-a56f-0452d744f1c3", - "type": "app", - "data": { - "credentials": { - "super-secret": "password" - }, - "syslog_drain_url": "syslog://drain.url.com" - }, - "created_at": "2015-11-13T17:02:56Z", - "updated_at": null, - "links": { - "self": { - "href": "/v3/service_bindings/dde5ad2a-d8f4-44dc-a56f-0452d744f1c3" - }, - "service_instance": { - "href": "/v3/service_instances/8bfe4c1b-9e18-45b1-83be-124163f31f9e" - }, - "app": { - "href": "/v3/apps/74f7c078-0934-470f-9883-4fddss5b8f13" - } - } -} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBinding.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBinding.java index 2d1ff195194..a022055a720 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBinding.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBinding.java @@ -18,6 +18,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.cloudfoundry.Nullable; +import org.cloudfoundry.client.v3.LastOperation; +import org.cloudfoundry.client.v3.Metadata; import org.cloudfoundry.client.v3.Resource; /** @@ -26,17 +28,36 @@ public abstract class ServiceBinding extends Resource { /** - * The datas + * The name */ - @JsonProperty("data") + @JsonProperty("name") @Nullable - public abstract ServiceBindingData getData(); + public abstract String getName(); /** * The type */ @JsonProperty("type") + public abstract ServiceBindingType getType(); + + /** + * The last operation + */ + @JsonProperty("last_operation") + @Nullable + abstract LastOperation getLastOperation(); + + /** + * The relationships + */ + @JsonProperty("relationships") + public abstract ServiceBindingRelationships getRelationships(); + + /** + * The metadata + */ + @JsonProperty("metadata") @Nullable - public abstract String getType(); + public abstract Metadata getMetadata(); } diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBindingType.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBindingType.java index d94f2e72d01..af7854ef378 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBindingType.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBindingType.java @@ -19,14 +19,19 @@ import com.fasterxml.jackson.annotation.JsonValue; /** - * The service binding type of the {@link CreateServiceBindingRequest} + * The service credential binding type */ public enum ServiceBindingType { /** * Indicates that the service binding is to an application */ - APPLICATION("app"); + APPLICATION("app"), + + /** + * Indicates that the service binding is a key + */ + KEY("key"); private final String value; diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBindingsV3.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBindingsV3.java index cff11891701..611e5ccdc19 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBindingsV3.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/ServiceBindingsV3.java @@ -24,7 +24,7 @@ public interface ServiceBindingsV3 { /** - * Makes the Create a service binding request + * Makes the Create a service credential binding request * * @param request the Create Service Binding request * @return the response from the Create Service Binding request @@ -32,15 +32,15 @@ public interface ServiceBindingsV3 { Mono create(CreateServiceBindingRequest request); /** - * Makes the Delete a service binding request + * Makes the Delete a service credential binding request * * @param request the Delete Service Binding request * @return the response from the Delete Service Binding request */ - Mono delete(DeleteServiceBindingRequest request); + Mono delete(DeleteServiceBindingRequest request); /** - * Makes the Get a Service Binding request + * Makes the Get a service credential binding request * * @param request the Get Service Binding request * @return the response from the Get Service Binding request @@ -48,11 +48,35 @@ public interface ServiceBindingsV3 { Mono get(GetServiceBindingRequest request); /** - * Makes the List service bindings request + * Makes the Get a service credential binding details request + * + * @param request the Get Service Binding Details request + * @return the response from the Get Service Binding Details request + */ + Mono getDetails(GetServiceBindingDetailsRequest request); + + /** + * Makes the Get parameters a service credential binding request + * + * @param request the Get Service Binding Parameters request + * @return the response from the Get Service Binding Parameters request + */ + Mono getParameters(GetServiceBindingParametersRequest request); + + /** + * Makes the List service credential bindings request * * @param request the List Service Bindings request * @return the response from the List Service Bindings request */ Mono list(ListServiceBindingsRequest request); + /** + * Makes the Update a service credential bindings request + * + * @param request the Update Service Bindings request + * @return the response from the Update Service Bindings request + */ + Mono update(UpdateServiceBindingRequest request); + } diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_CreateServiceBindingRequest.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_CreateServiceBindingRequest.java index 6f8486b03d3..5a5ecee9b05 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_CreateServiceBindingRequest.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_CreateServiceBindingRequest.java @@ -16,12 +16,15 @@ package org.cloudfoundry.client.v3.servicebindings; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.cloudfoundry.AllowNulls; import org.cloudfoundry.Nullable; +import org.cloudfoundry.client.v3.Metadata; import org.immutables.value.Value; +import java.util.Map; + /** * The request payload for the Create Service Binding operation. */ @@ -30,11 +33,11 @@ abstract class _CreateServiceBindingRequest { /** - * The data + * The name */ - @JsonProperty("data") + @JsonProperty("name") @Nullable - abstract CreateServiceBindingData getData(); + abstract String getName(); /** * The relationships @@ -48,4 +51,25 @@ abstract class _CreateServiceBindingRequest { @JsonProperty("type") abstract ServiceBindingType getType(); + /** + * The parameters + */ + @JsonProperty("parameters") + @Nullable + @AllowNulls + abstract Map getParameters(); + + /** + * The metadata + */ + @JsonProperty("metadata") + @Nullable + abstract Metadata getMetadata(); + + @Value.Check + void validateParameters() { + if (ServiceBindingType.KEY.equals(getType()) && getName() == null) { + throw new IllegalStateException("A name is required for a service binding of type 'key'"); + } + } } diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_CreateServiceBindingResponse.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_CreateServiceBindingResponse.java index aa60a2f9ca8..787050e680d 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_CreateServiceBindingResponse.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_CreateServiceBindingResponse.java @@ -16,14 +16,18 @@ package org.cloudfoundry.client.v3.servicebindings; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import org.immutables.value.Value; +import java.util.Optional; + /** * The response payload for Create Service Binding */ -@JsonDeserialize @Value.Immutable -abstract class _CreateServiceBindingResponse extends ServiceBinding { +abstract class _CreateServiceBindingResponse { + + public abstract Optional getJobId(); + + public abstract Optional getServiceBinding(); } diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_CreateServiceBindingData.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingDetailsRequest.java similarity index 61% rename from cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_CreateServiceBindingData.java rename to cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingDetailsRequest.java index 7cc8611fd35..585021dee0d 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_CreateServiceBindingData.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingDetailsRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2021 the original author or authors. + * Copyright 2013-2022 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. @@ -16,25 +16,19 @@ package org.cloudfoundry.client.v3.servicebindings; -import com.fasterxml.jackson.annotation.JsonProperty; -import org.cloudfoundry.AllowNulls; -import org.cloudfoundry.Nullable; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.immutables.value.Value; -import java.util.Map; - /** - * The data to use when created a {@link ServiceBinding} + * The request payload for the Get Service Binding Details operation. */ @Value.Immutable -abstract class _CreateServiceBindingData { +abstract class _GetServiceBindingDetailsRequest { /** - * The parameters + * The service binding id */ - @AllowNulls - @JsonProperty("parameters") - @Nullable - abstract Map getParameters(); + @JsonIgnore + abstract String getServiceBindingId(); } diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_ServiceBindingData.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingDetailsResponse.java similarity index 79% rename from cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_ServiceBindingData.java rename to cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingDetailsResponse.java index bb07dd119c4..37000505ac3 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_ServiceBindingData.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingDetailsResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2021 the original author or authors. + * Copyright 2013-2022 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. @@ -26,32 +26,30 @@ import java.util.Map; /** - * The data for a {@link ServiceBinding} + * The response payload for the Get Service Binding Details operation */ @JsonDeserialize @Value.Immutable -abstract class _ServiceBindingData { +abstract class _GetServiceBindingDetailsResponse { /** - * The service binding credentials + * The credentials */ - @AllowNulls @JsonProperty("credentials") - @Nullable + @AllowNulls abstract Map getCredentials(); /** - * The syslog drain URL + * The syslog drain url */ - @JsonProperty("syslog_drain_url") + @JsonProperty("syslog_drain_log") @Nullable abstract String getSyslogDrainUrl(); /** - * The (experimental) volume mounts + * The volume mounts */ @JsonProperty("volume_mounts") - @Nullable abstract List getVolumeMounts(); } diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingParametersRequest.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingParametersRequest.java new file mode 100644 index 00000000000..2fd53a1f671 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingParametersRequest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2022 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.servicebindings; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.immutables.value.Value; + +/** + * The request payload for the Get Service Binding Parameters operation. + */ +@Value.Immutable +abstract class _GetServiceBindingParametersRequest { + + /** + * The service binding id + */ + @JsonIgnore + abstract String getServiceBindingId(); + +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingParametersResponse.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingParametersResponse.java new file mode 100644 index 00000000000..441b9f03cb8 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingParametersResponse.java @@ -0,0 +1,60 @@ +/* + * Copyright 2013-2022 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.servicebindings; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.cloudfoundry.AllowNulls; +import org.immutables.value.Value; + +import java.io.IOException; +import java.util.Map; + +/** + * The response payload for the Get Service Binding Parameters operation + */ +@JsonDeserialize(using = _GetServiceBindingParametersResponse.ServiceBindingParametersResponseDeserializer.class) +@Value.Immutable +abstract class _GetServiceBindingParametersResponse { + + /** + * The parameters + */ + @AllowNulls + abstract Map getParameters(); + + static final class ServiceBindingParametersResponseDeserializer extends StdDeserializer { + + private static final long serialVersionUID = 1L; + + ServiceBindingParametersResponseDeserializer() { + super(GetServiceBindingParametersResponse.class); + } + + @Override + public GetServiceBindingParametersResponse deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + return GetServiceBindingParametersResponse.builder() + .parameters(p.readValueAs(new TypeReference>() { + + })) + .build(); + } + } +} diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingRequest.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingRequest.java index 36a65c0ff31..a8aa498f01b 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingRequest.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_GetServiceBindingRequest.java @@ -16,7 +16,6 @@ package org.cloudfoundry.client.v3.servicebindings; - import com.fasterxml.jackson.annotation.JsonIgnore; import org.immutables.value.Value; diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_ListServiceBindingsRequest.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_ListServiceBindingsRequest.java index b0f57d0cd42..253cedbcf9a 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_ListServiceBindingsRequest.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_ListServiceBindingsRequest.java @@ -17,6 +17,7 @@ package org.cloudfoundry.client.v3.servicebindings; +import org.cloudfoundry.Nullable; import org.cloudfoundry.client.v3.FilterParameter; import org.cloudfoundry.client.v3.PaginatedRequest; import org.immutables.value.Value; @@ -30,10 +31,10 @@ abstract class _ListServiceBindingsRequest extends PaginatedRequest { /** - * The application ids + * The names */ - @FilterParameter("app_guids") - abstract List getApplicationIds(); + @FilterParameter("names") + abstract List getNames(); /** * The service instance ids @@ -41,4 +42,58 @@ abstract class _ListServiceBindingsRequest extends PaginatedRequest { @FilterParameter("service_instance_guids") abstract List getServiceInstanceIds(); + /** + * The service instance names + */ + @FilterParameter("service_instance_names") + abstract List getServiceInstanceNames(); + + /** + * The application ids + */ + @FilterParameter("app_guids") + abstract List getApplicationIds(); + + /** + * The application names + */ + @FilterParameter("app_names") + abstract List getAppNames(); + + /** + * The service plan ids + */ + @FilterParameter("service_plan_guids") + abstract List getServicePlanIds(); + + /** + * The service plan names + */ + @FilterParameter("service_plan_names") + abstract List getServicePlanNames(); + + /** + * The service offering ids + */ + @FilterParameter("service_offering_guids") + abstract List getServiceOfferingIds(); + + /** + * The service offering names + */ + @FilterParameter("service_offering_names") + abstract List getServiceOfferingNames(); + + /** + * The type + */ + @FilterParameter("type") + @Nullable + abstract ServiceBindingType getType(); + + /** + * The ids + */ + @FilterParameter("guids") + abstract List getIds(); } diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_ServiceBindingRelationships.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_ServiceBindingRelationships.java index a0718829e39..0a90f88d5bb 100644 --- a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_ServiceBindingRelationships.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_ServiceBindingRelationships.java @@ -17,25 +17,29 @@ package org.cloudfoundry.client.v3.servicebindings; import com.fasterxml.jackson.annotation.JsonProperty; -import org.cloudfoundry.client.v3.Relationship; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.cloudfoundry.Nullable; +import org.cloudfoundry.client.v3.ToOneRelationship; import org.immutables.value.Value; /** * The relationships for the Create Service Binding request */ @Value.Immutable +@JsonDeserialize abstract class _ServiceBindingRelationships { /** * The application relationship */ @JsonProperty("app") - abstract Relationship getApplication(); + @Nullable + abstract ToOneRelationship getApplication(); /** * The service instance relationship */ @JsonProperty("service_instance") - abstract Relationship getServiceInstance(); + abstract ToOneRelationship getServiceInstance(); } diff --git a/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_UpdateServiceBindingRequest.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_UpdateServiceBindingRequest.java new file mode 100644 index 00000000000..a3b0ddc89e3 --- /dev/null +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_UpdateServiceBindingRequest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2022 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.servicebindings; + +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.cloudfoundry.client.v3.Metadata; +import org.immutables.value.Value; + +/** + * The request payload for the Update Service Binding operation + */ +@JsonSerialize +@Value.Immutable +abstract class _UpdateServiceBindingRequest { + + /** + * The service binding id + */ + @JsonIgnore + abstract String getServiceBindingId(); + + /** + * The metadata + */ + @JsonProperty("metadata") + @Nullable + abstract Metadata getMetadata(); +} diff --git a/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/servicebindings/CreateServiceBindingDataTest.java b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_UpdateServiceBindingResponse.java similarity index 65% rename from cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/servicebindings/CreateServiceBindingDataTest.java rename to cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_UpdateServiceBindingResponse.java index 49decd8b145..59e4c157a55 100644 --- a/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/servicebindings/CreateServiceBindingDataTest.java +++ b/cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/servicebindings/_UpdateServiceBindingResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2021 the original author or authors. + * Copyright 2013-2022 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. @@ -16,14 +16,14 @@ package org.cloudfoundry.client.v3.servicebindings; -import org.junit.Test; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.immutables.value.Value; -public final class CreateServiceBindingDataTest { - - @Test - public void valid() { - CreateServiceBindingData.builder() - .build(); - } +/** + * The response payload for the Update Service Binding operation + */ +@JsonDeserialize +@Value.Immutable +abstract class _UpdateServiceBindingResponse extends ServiceBinding { } diff --git a/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/servicebindings/CreateServiceBindingRequestTest.java b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/servicebindings/CreateServiceBindingRequestTest.java index 9132756104c..3e3631ef0c7 100644 --- a/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/servicebindings/CreateServiceBindingRequestTest.java +++ b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/servicebindings/CreateServiceBindingRequestTest.java @@ -16,8 +16,8 @@ package org.cloudfoundry.client.v3.servicebindings; - import org.cloudfoundry.client.v3.Relationship; +import org.cloudfoundry.client.v3.ToOneRelationship; import org.junit.Test; public final class CreateServiceBindingRequestTest { @@ -33,11 +33,15 @@ public void noRelationships() { public void noType() { CreateServiceBindingRequest.builder() .relationships(ServiceBindingRelationships.builder() - .application(Relationship.builder() - .id("test-id") + .application(ToOneRelationship.builder() + .data(Relationship.builder() + .id("test-id") + .build()) .build()) - .serviceInstance(Relationship.builder() - .id("test-id") + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id("test-id") + .build()) .build()) .build()) .build(); @@ -47,11 +51,15 @@ public void noType() { public void valid() { CreateServiceBindingRequest.builder() .relationships(ServiceBindingRelationships.builder() - .application(Relationship.builder() - .id("test-id") + .application(ToOneRelationship.builder() + .data(Relationship.builder() + .id("test-id") + .build()) .build()) - .serviceInstance(Relationship.builder() - .id("test-id") + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id("test-id") + .build()) .build()) .build()) .type(ServiceBindingType.APPLICATION) diff --git a/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/servicebindings/RelationshipsTest.java b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/servicebindings/RelationshipsTest.java index 347c10aee3a..f138b614d2a 100644 --- a/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/servicebindings/RelationshipsTest.java +++ b/cloudfoundry-client/src/test/java/org/cloudfoundry/client/v3/servicebindings/RelationshipsTest.java @@ -17,15 +17,18 @@ package org.cloudfoundry.client.v3.servicebindings; import org.cloudfoundry.client.v3.Relationship; +import org.cloudfoundry.client.v3.ToOneRelationship; import org.junit.Test; public final class RelationshipsTest { - @Test(expected = IllegalStateException.class) + @Test public void noApplication() { ServiceBindingRelationships.builder() - .application(Relationship.builder() - .id("test-id") + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id("test-id") + .build()) .build()) .build(); } @@ -33,8 +36,10 @@ public void noApplication() { @Test(expected = IllegalStateException.class) public void noServiceInstance() { ServiceBindingRelationships.builder() - .serviceInstance(Relationship.builder() - .id("test-id") + .application(ToOneRelationship.builder() + .data(Relationship.builder() + .id("test-id") + .build()) .build()) .build(); } @@ -42,11 +47,15 @@ public void noServiceInstance() { @Test public void valid() { ServiceBindingRelationships.builder() - .application(Relationship.builder() - .id("test-id") + .application(ToOneRelationship.builder() + .data(Relationship.builder() + .id("test-id") + .build()) .build()) - .serviceInstance(Relationship.builder() - .id("test-id") + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id("test-id") + .build()) .build()) .build(); } diff --git a/integration-test/src/test/java/org/cloudfoundry/client/v3/ApplicationsTest.java b/integration-test/src/test/java/org/cloudfoundry/client/v3/ApplicationsTest.java index d2b6cd6cca3..e2b4b3ee2a4 100644 --- a/integration-test/src/test/java/org/cloudfoundry/client/v3/ApplicationsTest.java +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ApplicationsTest.java @@ -744,7 +744,7 @@ public void updateFeature() { .verify(Duration.ofMinutes(5)); } - private static Mono createApplicationId(CloudFoundryClient cloudFoundryClient, String applicationName, String spaceId) { + static Mono createApplicationId(CloudFoundryClient cloudFoundryClient, String applicationName, String spaceId) { return requestCreateApplication(cloudFoundryClient, applicationName, spaceId) .map(CreateApplicationResponse::getId); } 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 new file mode 100644 index 00000000000..da467c48897 --- /dev/null +++ b/integration-test/src/test/java/org/cloudfoundry/client/v3/ServiceBindingsTest.java @@ -0,0 +1,384 @@ +/* + * Copyright 2013-2022 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 org.cloudfoundry.AbstractIntegrationTest; +import org.cloudfoundry.CloudFoundryVersion; +import org.cloudfoundry.IfCloudFoundryVersion; +import org.cloudfoundry.client.CloudFoundryClient; +import org.cloudfoundry.client.v3.servicebindings.DeleteServiceBindingRequest; +import org.cloudfoundry.client.v3.servicebindings.GetServiceBindingDetailsRequest; +import org.cloudfoundry.client.v3.servicebindings.GetServiceBindingDetailsResponse; +import org.cloudfoundry.client.v3.servicebindings.GetServiceBindingRequest; +import org.cloudfoundry.client.v3.servicebindings.ListServiceBindingsResponse; +import org.cloudfoundry.client.v3.serviceinstances.CreateServiceInstanceRequest; +import org.cloudfoundry.client.v3.serviceinstances.CreateServiceInstanceResponse; +import org.cloudfoundry.client.v3.serviceplans.ListServicePlansRequest; +import org.cloudfoundry.client.v3.servicebindings.CreateServiceBindingRequest; +import org.cloudfoundry.client.v3.servicebindings.ListServiceBindingsRequest; +import org.cloudfoundry.client.v3.servicebindings.ServiceBinding; +import org.cloudfoundry.client.v3.servicebindings.ServiceBindingRelationships; +import org.cloudfoundry.client.v3.servicebindings.ServiceBindingResource; +import org.cloudfoundry.client.v3.servicebindings.ServiceBindingType; +import org.cloudfoundry.client.v3.serviceinstances.ListServiceInstancesRequest; +import org.cloudfoundry.client.v3.serviceinstances.ServiceInstance; +import org.cloudfoundry.client.v3.serviceinstances.ServiceInstanceRelationships; +import org.cloudfoundry.client.v3.serviceinstances.ServiceInstanceType; +import org.cloudfoundry.client.v3.serviceplans.ServicePlan; +import org.cloudfoundry.util.JobUtils; +import org.cloudfoundry.util.PaginationUtils; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.time.Duration; +import java.util.Collections; +import java.util.Map; + +import static org.cloudfoundry.client.v3.ApplicationsTest.createApplicationId; +import static org.cloudfoundry.util.tuple.TupleUtils.function; + +@IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_2_11) +public class ServiceBindingsTest extends AbstractIntegrationTest { + + @Autowired + private CloudFoundryClient cloudFoundryClient; + + @Autowired + private Mono serviceBrokerId; + + @Autowired + private String serviceName; + + @Autowired + private Mono spaceId; + + @Test + public void createServiceKeyFromManagedServiceInstance() { + String serviceInstanceName = this.nameFactory.getServiceInstanceName(); + String serviceKeyName = this.nameFactory.getServiceKeyName(); + + this.spaceId + .flatMap(spaceId -> createManagedServiceInstanceId(this.cloudFoundryClient, this.serviceBrokerId, serviceInstanceName, this.serviceName, spaceId)) + .flatMap(serviceInstanceId -> this.cloudFoundryClient.serviceBindingsV3() + .create(CreateServiceBindingRequest.builder() + .type(ServiceBindingType.KEY) + .name(serviceKeyName) + .relationships(ServiceBindingRelationships.builder() + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id(serviceInstanceId) + .build()) + .build()) + .build()) + .build()) + .map(response -> response.getJobId() + .get()) + .flatMap(jobId -> JobUtils.waitForCompletion(this.cloudFoundryClient, Duration.ofMinutes(5), jobId))) + .thenMany(requestListServiceBindings(this.cloudFoundryClient, serviceInstanceName)) + .map(ServiceBinding::getName) + .as(StepVerifier::create) + .expectNext(serviceKeyName) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + @Test + public void createAppBindingFromUserProvidedServiceInstance() { + String serviceInstanceName = this.nameFactory.getServiceInstanceName(); + String applicationName = this.nameFactory.getApplicationName(); + + this.spaceId + .flatMap(spaceId -> Mono.zip( + createUserProvidedServiceInstanceId(this.cloudFoundryClient, serviceInstanceName, Collections.emptyMap(), spaceId), + createApplicationId(this.cloudFoundryClient, applicationName, spaceId) + )) + .flatMap(function((serviceInstanceId, appId) -> this.cloudFoundryClient.serviceBindingsV3() + .create(CreateServiceBindingRequest.builder() + .type(ServiceBindingType.APPLICATION) + .metadata(Metadata.builder() + .label("test-label", "test-label-value") + .build()) + .relationships(ServiceBindingRelationships.builder() + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id(serviceInstanceId) + .build()) + .build()) + .application(ToOneRelationship.builder() + .data(Relationship.builder() + .id(appId) + .build()) + .build()) + .build()) + .build()) + .map(response -> response.getServiceBinding() + .get()))) + .map(ServiceBindingResource::getMetadata) + .map(Metadata::getLabels) + .as(StepVerifier::create) + .expectNext(Collections.singletonMap("test-label", "test-label-value")) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + @Test + public void deleteForManagedService() { + String serviceInstanceName = this.nameFactory.getServiceInstanceName(); + String serviceKeyName = this.nameFactory.getServiceKeyName(); + + this.spaceId + .flatMap(spaceId -> createManagedServiceInstanceId(this.cloudFoundryClient, this.serviceBrokerId, serviceInstanceName, this.serviceName, spaceId)) + .flatMap(serviceInstanceId -> createServiceKey(this.cloudFoundryClient, serviceKeyName, serviceInstanceName, serviceInstanceId)) + .map(ServiceBinding::getId) + .flatMap(bindingId -> this.cloudFoundryClient.serviceBindingsV3() + .delete(DeleteServiceBindingRequest.builder() + .serviceBindingId(bindingId) + .build())) + .hasElement() + .as(StepVerifier::create) + .expectNext(true) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + @Test + public void deleteForUserProvidedService() { + String serviceInstanceName = this.nameFactory.getServiceInstanceName(); + String applicationName = this.nameFactory.getApplicationName(); + + this.spaceId + .flatMap(spaceId -> Mono.zip( + createUserProvidedServiceInstanceId(this.cloudFoundryClient, serviceInstanceName, Collections.emptyMap(), spaceId), + createApplicationId(this.cloudFoundryClient, applicationName, spaceId) + )) + .flatMap(function((serviceInstanceId, appId) -> createServiceBindingForUserProvidedService(this.cloudFoundryClient, appId, serviceInstanceId))) + .map(ServiceBinding::getId) + .flatMap(bindingId -> this.cloudFoundryClient.serviceBindingsV3() + .delete(DeleteServiceBindingRequest.builder() + .serviceBindingId(bindingId) + .build())) + .hasElement() + .as(StepVerifier::create) + .expectNext(false) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + @Test + public void listForApplication() { + String serviceInstanceName = this.nameFactory.getServiceInstanceName(); + String applicationName = this.nameFactory.getApplicationName(); + + this.spaceId + .flatMap(spaceId -> Mono.zip( + createUserProvidedServiceInstanceId(this.cloudFoundryClient, serviceInstanceName, Collections.emptyMap(), spaceId), + createApplicationId(this.cloudFoundryClient, applicationName, spaceId) + )) + .flatMap(function((serviceInstanceId, appId) -> createServiceBindingForUserProvidedService(this.cloudFoundryClient, appId, serviceInstanceId))) + .thenMany(this.cloudFoundryClient.serviceBindingsV3() + .list(ListServiceBindingsRequest.builder() + .appName(applicationName) + .build())) + .map(ListServiceBindingsResponse::getResources) + .as(StepVerifier::create) + .expectNextCount(1) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + @Test + public void get() { + String serviceInstanceName = this.nameFactory.getServiceInstanceName(); + String applicationName = this.nameFactory.getApplicationName(); + + this.spaceId + .flatMap(spaceId -> Mono.zip( + createUserProvidedServiceInstanceId(this.cloudFoundryClient, serviceInstanceName, Collections.emptyMap(), spaceId), + createApplicationId(this.cloudFoundryClient, applicationName, spaceId) + )) + .flatMap(function((serviceInstanceId, appId) -> createServiceBindingForUserProvidedService(this.cloudFoundryClient, appId, serviceInstanceId))) + .map(ServiceBinding::getId) + .flatMap(bindingId -> this.cloudFoundryClient.serviceBindingsV3() + .get(GetServiceBindingRequest.builder() + .serviceBindingId(bindingId) + .build())) + .map(ServiceBinding::getMetadata) + .map(Metadata::getLabels) + .as(StepVerifier::create) + .expectNext(Collections.singletonMap("test-label", "test-label-value")) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + @Test + public void getDetails() { + String serviceInstanceName = this.nameFactory.getServiceInstanceName(); + String applicationName = this.nameFactory.getApplicationName(); + + this.spaceId + .flatMap(spaceId -> Mono.zip( + createUserProvidedServiceInstanceId(this.cloudFoundryClient, serviceInstanceName, Collections.singletonMap("foo", "bar"), spaceId), + createApplicationId(this.cloudFoundryClient, applicationName, spaceId) + )) + .flatMap(function((serviceInstanceId, appId) -> createServiceBindingForUserProvidedService(this.cloudFoundryClient, appId, serviceInstanceId))) + .map(ServiceBinding::getId) + .flatMap(bindingId -> this.cloudFoundryClient.serviceBindingsV3() + .getDetails(GetServiceBindingDetailsRequest.builder() + .serviceBindingId(bindingId) + .build())) + .map(GetServiceBindingDetailsResponse::getCredentials) + .as(StepVerifier::create) + .expectNext(Collections.singletonMap("foo", "bar")) + .expectComplete() + .verify(Duration.ofMinutes(5)); + } + + private static Mono createManagedServiceInstanceId(CloudFoundryClient cloudFoundryClient, Mono serviceBrokerId, String serviceInstanceName, String serviceName, String spaceId) { + return serviceBrokerId + .flatMap(brokerId -> getPlanId(cloudFoundryClient, brokerId, serviceName)) + .flatMap(planId -> requestCreateManagedServiceInstance(cloudFoundryClient, planId, serviceInstanceName, spaceId)) + .map(response -> response.getJobId() + .get()) + .flatMap(jobId -> JobUtils.waitForCompletion(cloudFoundryClient, Duration.ofMinutes(5), jobId)) + .thenMany(requestListServiceInstances(cloudFoundryClient, serviceInstanceName)) + .single() + .map(ServiceInstance::getId); + } + + private static Mono getPlanId(CloudFoundryClient cloudFoundryClient, String serviceBrokerId, String serviceName) { + return requestListServicePlans(cloudFoundryClient, serviceName, serviceBrokerId) + .single() + .map(ServicePlan::getId); + } + + private static Flux requestListServicePlans(CloudFoundryClient cloudFoundryClient, String serviceName, String serviceBrokerId) { + return PaginationUtils.requestClientV3Resources(page -> cloudFoundryClient.servicePlansV3() + .list(ListServicePlansRequest.builder() + .page(page) + .serviceOfferingName(serviceName) + .serviceBrokerId(serviceBrokerId) + .build())); + } + + private static Mono requestCreateManagedServiceInstance(CloudFoundryClient cloudFoundryClient, String planId, String serviceInstanceName, String spaceId) { + return cloudFoundryClient.serviceInstancesV3() + .create(CreateServiceInstanceRequest.builder() + .name(serviceInstanceName) + .type(ServiceInstanceType.MANAGED) + .relationships(ServiceInstanceRelationships.builder() + .space(ToOneRelationship.builder() + .data(Relationship.builder() + .id(spaceId) + .build()) + .build()) + .servicePlan(ToOneRelationship.builder() + .data(Relationship.builder() + .id(planId) + .build()) + .build()) + .build()) + .build()); + } + + private static Mono createUserProvidedServiceInstanceId(CloudFoundryClient cloudFoundryClient, String serviceInstanceName, Map credentials, String spaceId) { + return requestCreateUserProvidedServiceInstance(cloudFoundryClient, serviceInstanceName, credentials, spaceId) + .map(response -> response.getServiceInstance() + .get()) + .map(ServiceInstance::getId); + } + + private static Mono requestCreateUserProvidedServiceInstance(CloudFoundryClient cloudFoundryClient, String serviceInstanceName, Map credentials, + String spaceId) { + return cloudFoundryClient.serviceInstancesV3() + .create(CreateServiceInstanceRequest.builder() + .type(ServiceInstanceType.USER_PROVIDED) + .name(serviceInstanceName) + .credentials(credentials) + .relationships(ServiceInstanceRelationships.builder() + .space(ToOneRelationship.builder() + .data(Relationship.builder() + .id(spaceId) + .build()) + .build()) + .build()) + .build()); + } + + private static Flux requestListServiceInstances(CloudFoundryClient cloudFoundryClient, String serviceInstanceName) { + return PaginationUtils.requestClientV3Resources(page -> cloudFoundryClient.serviceInstancesV3() + .list(ListServiceInstancesRequest.builder() + .page(page) + .serviceInstanceName(serviceInstanceName) + .build())); + } + + private static Flux requestListServiceBindings(CloudFoundryClient cloudFoundryClient, String serviceInstanceName) { + return PaginationUtils.requestClientV3Resources(page -> cloudFoundryClient.serviceBindingsV3() + .list(ListServiceBindingsRequest.builder() + .page(page) + .serviceInstanceName(serviceInstanceName) + .build())); + } + + private static Mono createServiceKey(CloudFoundryClient cloudFoundryClient, String serviceKeyName, String serviceInstanceName, String serviceInstanceId) { + return cloudFoundryClient.serviceBindingsV3() + .create(CreateServiceBindingRequest.builder() + .type(ServiceBindingType.KEY) + .name(serviceKeyName) + .relationships(ServiceBindingRelationships.builder() + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id(serviceInstanceId) + .build()) + .build()) + .build()) + .build()) + .map(response -> response.getJobId() + .get()) + .flatMap(jobId -> JobUtils.waitForCompletion(cloudFoundryClient, Duration.ofMinutes(5), jobId)) + .thenMany(requestListServiceBindings(cloudFoundryClient, serviceInstanceName)) + .single(); + } + + private static Mono createServiceBindingForUserProvidedService(CloudFoundryClient cloudFoundryClient, String appId, String serviceInstanceId) { + return cloudFoundryClient.serviceBindingsV3() + .create(CreateServiceBindingRequest.builder() + .type(ServiceBindingType.APPLICATION) + .metadata(Metadata.builder() + .label("test-label", "test-label-value") + .build()) + .relationships(ServiceBindingRelationships.builder() + .serviceInstance(ToOneRelationship.builder() + .data(Relationship.builder() + .id(serviceInstanceId) + .build()) + .build()) + .application(ToOneRelationship.builder() + .data(Relationship.builder() + .id(appId) + .build()) + .build()) + .build()) + .build()) + .map(response -> response.getServiceBinding() + .get()); + } + +}