Skip to content

Commit 9de4a51

Browse files
committed
Merge branch '931-v3-deployments' into 2.x
2 parents eef597c + f5d3b11 commit 9de4a51

33 files changed

+1611
-2
lines changed

cloudfoundry-client-reactor/src/main/java/org/cloudfoundry/reactor/client/_ReactorCloudFoundryClient.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.cloudfoundry.client.v2.users.Users;
5151
import org.cloudfoundry.client.v3.applications.ApplicationsV3;
5252
import org.cloudfoundry.client.v3.builds.Builds;
53+
import org.cloudfoundry.client.v3.deployments.DeploymentsV3;
5354
import org.cloudfoundry.client.v3.droplets.Droplets;
5455
import org.cloudfoundry.client.v3.isolationsegments.IsolationSegments;
5556
import org.cloudfoundry.client.v3.jobs.JobsV3;
@@ -95,6 +96,7 @@
9596
import org.cloudfoundry.reactor.client.v2.users.ReactorUsers;
9697
import org.cloudfoundry.reactor.client.v3.applications.ReactorApplicationsV3;
9798
import org.cloudfoundry.reactor.client.v3.builds.ReactorBuilds;
99+
import org.cloudfoundry.reactor.client.v3.deployments.ReactorDeploymentsV3;
98100
import org.cloudfoundry.reactor.client.v3.droplets.ReactorDroplets;
99101
import org.cloudfoundry.reactor.client.v3.isolationsegments.ReactorIsolationSegments;
100102
import org.cloudfoundry.reactor.client.v3.jobs.ReactorJobsV3;
@@ -157,6 +159,12 @@ public void checkCompatibility() {
157159
new CloudFoundryClientCompatibilityChecker(info()).check();
158160
}
159161

162+
@Override
163+
@Value.Derived
164+
public DeploymentsV3 deploymentsV3() {
165+
return new ReactorDeploymentsV3(getConnectionContext(), getRootV3(), getTokenProvider());
166+
}
167+
160168
@Override
161169
@Value.Derived
162170
public Domains domains() {
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2013-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.cloudfoundry.reactor.client.v3.deployments;
18+
19+
import org.cloudfoundry.client.v3.deployments.CancelDeploymentRequest;
20+
import org.cloudfoundry.client.v3.deployments.CancelDeploymentResponse;
21+
import org.cloudfoundry.client.v3.deployments.CreateDeploymentRequest;
22+
import org.cloudfoundry.client.v3.deployments.CreateDeploymentResponse;
23+
import org.cloudfoundry.client.v3.deployments.DeploymentsV3;
24+
import org.cloudfoundry.client.v3.deployments.GetDeploymentRequest;
25+
import org.cloudfoundry.client.v3.deployments.GetDeploymentResponse;
26+
import org.cloudfoundry.client.v3.deployments.ListDeploymentsRequest;
27+
import org.cloudfoundry.client.v3.deployments.ListDeploymentsResponse;
28+
import org.cloudfoundry.reactor.ConnectionContext;
29+
import org.cloudfoundry.reactor.TokenProvider;
30+
import org.cloudfoundry.reactor.client.v3.AbstractClientV3Operations;
31+
import reactor.core.publisher.Mono;
32+
33+
/**
34+
* The Reactor-based implementation of {@link DeploymentsV3}
35+
*/
36+
public final class ReactorDeploymentsV3 extends AbstractClientV3Operations implements DeploymentsV3 {
37+
38+
/**
39+
* Creates an instance
40+
*
41+
* @param connectionContext the {@link ConnectionContext} to use when communicating with the server
42+
* @param root the root URI of the server. Typically something like {@code https://api.run.pivotal.io}.
43+
* @param tokenProvider the {@link TokenProvider} to use when communicating with the server
44+
*/
45+
public ReactorDeploymentsV3(ConnectionContext connectionContext, Mono<String> root, TokenProvider tokenProvider) {
46+
super(connectionContext, root, tokenProvider);
47+
}
48+
49+
@Override
50+
public Mono<CancelDeploymentResponse> cancel(CancelDeploymentRequest request) {
51+
return post(request, CancelDeploymentResponse.class, builder -> builder.pathSegment("deployments", request.getDeploymentId(), "actions", "cancel"))
52+
.checkpoint();
53+
}
54+
55+
@Override
56+
public Mono<CreateDeploymentResponse> create(CreateDeploymentRequest request) {
57+
return post(request, CreateDeploymentResponse.class, builder -> builder.pathSegment("deployments"))
58+
.checkpoint();
59+
}
60+
61+
@Override
62+
public Mono<GetDeploymentResponse> get(GetDeploymentRequest request) {
63+
return get(request, GetDeploymentResponse.class, builder -> builder.pathSegment("deployments", request.getDeploymentId()))
64+
.checkpoint();
65+
}
66+
67+
@Override
68+
public Mono<ListDeploymentsResponse> list(ListDeploymentsRequest request) {
69+
return get(request, ListDeploymentsResponse.class, builder -> builder.pathSegment("deployments"))
70+
.checkpoint();
71+
}
72+
73+
}

cloudfoundry-client-reactor/src/test/java/org/cloudfoundry/reactor/client/v3/builds/ReactorBuildsTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.cloudfoundry.client.v3.builds.CreateBuildRequest;
2828
import org.cloudfoundry.client.v3.builds.CreateBuildResponse;
2929
import org.cloudfoundry.client.v3.builds.CreatedBy;
30+
import org.cloudfoundry.client.v3.builds.Droplet;
3031
import org.cloudfoundry.client.v3.builds.GetBuildRequest;
3132
import org.cloudfoundry.client.v3.builds.GetBuildResponse;
3233
import org.cloudfoundry.client.v3.builds.ListBuildsRequest;
@@ -140,7 +141,7 @@ public void get() {
140141
.inputPackage(Relationship.builder()
141142
.id("8e4da443-f255-499c-8b47-b3729b5b7432")
142143
.build())
143-
.droplet(Relationship.builder()
144+
.droplet(Droplet.builder()
144145
.id("1e1186e7-d803-4c46-b9d6-5c81e50fe55a")
145146
.build())
146147
.link("self", Link.builder()
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/*
2+
* Copyright 2013-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.cloudfoundry.reactor.client.v3.deployments;
18+
19+
import org.cloudfoundry.client.v3.Link;
20+
import org.cloudfoundry.client.v3.Pagination;
21+
import org.cloudfoundry.client.v3.Relationship;
22+
import org.cloudfoundry.client.v3.ToOneRelationship;
23+
import org.cloudfoundry.client.v3.deployments.CancelDeploymentRequest;
24+
import org.cloudfoundry.client.v3.deployments.CreateDeploymentRequest;
25+
import org.cloudfoundry.client.v3.deployments.CreateDeploymentResponse;
26+
import org.cloudfoundry.client.v3.deployments.DeploymentRelationships;
27+
import org.cloudfoundry.client.v3.deployments.DeploymentResource;
28+
import org.cloudfoundry.client.v3.deployments.DeploymentState;
29+
import org.cloudfoundry.client.v3.deployments.GetDeploymentRequest;
30+
import org.cloudfoundry.client.v3.deployments.GetDeploymentResponse;
31+
import org.cloudfoundry.client.v3.deployments.ListDeploymentsRequest;
32+
import org.cloudfoundry.client.v3.deployments.ListDeploymentsResponse;
33+
import org.cloudfoundry.client.v3.deployments.Process;
34+
import org.cloudfoundry.client.v3.deployments.Revision;
35+
import org.cloudfoundry.reactor.InteractionContext;
36+
import org.cloudfoundry.reactor.TestRequest;
37+
import org.cloudfoundry.reactor.TestResponse;
38+
import org.cloudfoundry.reactor.client.AbstractClientApiTest;
39+
import org.junit.Test;
40+
import reactor.test.StepVerifier;
41+
42+
import java.time.Duration;
43+
44+
import static io.netty.handler.codec.http.HttpMethod.GET;
45+
import static io.netty.handler.codec.http.HttpMethod.POST;
46+
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
47+
import static java.util.Collections.singletonList;
48+
49+
public class ReactorDeploymentsV3Test extends AbstractClientApiTest {
50+
51+
private final ReactorDeploymentsV3 deployments = new ReactorDeploymentsV3(CONNECTION_CONTEXT, this.root, TOKEN_PROVIDER);
52+
53+
@Test
54+
public void cancel() {
55+
mockRequest(InteractionContext.builder()
56+
.request(TestRequest.builder()
57+
.method(POST).path("/deployments/test-deployment-id/actions/cancel")
58+
.payload("fixtures/client/v3/deployments/POST_{id}_cancel_request.json")
59+
.build())
60+
.response(TestResponse.builder()
61+
.status(OK)
62+
.build())
63+
.build());
64+
65+
this.deployments
66+
.cancel(CancelDeploymentRequest.builder()
67+
.deploymentId("test-deployment-id")
68+
.build())
69+
.as(StepVerifier::create)
70+
.expectComplete()
71+
.verify(Duration.ofSeconds(5));
72+
}
73+
74+
@Test
75+
public void create() {
76+
mockRequest(InteractionContext.builder()
77+
.request(TestRequest.builder()
78+
.method(POST).path("/deployments")
79+
.payload("fixtures/client/v3/deployments/POST_request.json")
80+
.build())
81+
.response(TestResponse.builder()
82+
.status(OK)
83+
.payload("fixtures/client/v3/deployments/POST_response.json")
84+
.build())
85+
.build());
86+
87+
this.deployments
88+
.create(CreateDeploymentRequest.builder()
89+
.droplet(Relationship.builder().id("44ccfa61-dbcf-4a0d-82fe-f668e9d2a962").build())
90+
.relationships(DeploymentRelationships.builder()
91+
.app(ToOneRelationship.builder()
92+
.data(Relationship.builder()
93+
.id("305cea31-5a44-45ca-b51b-e89c7a8ef8b2")
94+
.build())
95+
.build())
96+
.build())
97+
.build())
98+
.as(StepVerifier::create)
99+
100+
.expectNext(CreateDeploymentResponse.builder()
101+
.id("59c3d133-2b83-46f3-960e-7765a129aea4")
102+
.state(DeploymentState.DEPLOYING)
103+
.droplet(Relationship.builder()
104+
.id("44ccfa61-dbcf-4a0d-82fe-f668e9d2a962")
105+
.build())
106+
.previousDroplet(Relationship.builder()
107+
.id("cc6bc315-bd06-49ce-92c2-bc3ad45268c2")
108+
.build())
109+
.newProcesses(singletonList(Process.builder()
110+
.id("fd5d3e60-f88c-4c37-b1ae-667cfc65a856")
111+
.type("web-deployment-59c3d133-2b83-46f3-960e-7765a129aea4")
112+
.build()))
113+
.revision(Revision.builder()
114+
.id("56126cba-656a-4eba-a81e-7e9951b2df57")
115+
.version(1)
116+
.build())
117+
.createdAt("2018-04-25T22:42:10Z")
118+
.updatedAt("2018-04-25T22:42:10Z")
119+
.relationships(DeploymentRelationships.builder()
120+
.app(ToOneRelationship.builder()
121+
.data(Relationship.builder()
122+
.id("305cea31-5a44-45ca-b51b-e89c7a8ef8b2")
123+
.build())
124+
.build())
125+
.build())
126+
.link("self", Link.builder()
127+
.href("https://api.example.org/v3/deployments/59c3d133-2b83-46f3-960e-7765a129aea4")
128+
.build())
129+
.link("app", Link.builder()
130+
.href("https://api.example.org/v3/apps/305cea31-5a44-45ca-b51b-e89c7a8ef8b2")
131+
.build())
132+
.build())
133+
.expectComplete()
134+
.verify(Duration.ofSeconds(5));
135+
}
136+
137+
@Test
138+
public void get() {
139+
mockRequest(InteractionContext.builder()
140+
.request(TestRequest.builder()
141+
.method(GET).path("/deployments/test-deployment-id")
142+
.build())
143+
.response(TestResponse.builder()
144+
.status(OK)
145+
.payload("fixtures/client/v3/deployments/GET_{id}_response.json")
146+
.build())
147+
.build());
148+
149+
this.deployments
150+
.get(GetDeploymentRequest.builder()
151+
.deploymentId("test-deployment-id")
152+
.build())
153+
.as(StepVerifier::create)
154+
155+
.expectNext(GetDeploymentResponse.builder()
156+
.id("59c3d133-2b83-46f3-960e-7765a129aea4")
157+
.state(DeploymentState.DEPLOYING)
158+
.droplet(Relationship.builder()
159+
.id("44ccfa61-dbcf-4a0d-82fe-f668e9d2a962")
160+
.build())
161+
.previousDroplet(Relationship.builder()
162+
.id("cc6bc315-bd06-49ce-92c2-bc3ad45268c2")
163+
.build())
164+
.newProcesses(singletonList(Process.builder()
165+
.id("fd5d3e60-f88c-4c37-b1ae-667cfc65a856")
166+
.type("web-deployment-59c3d133-2b83-46f3-960e-7765a129aea4")
167+
.build()))
168+
.revision(Revision.builder()
169+
.id("56126cba-656a-4eba-a81e-7e9951b2df57")
170+
.version(1)
171+
.build())
172+
.createdAt("2018-04-25T22:42:10Z")
173+
.updatedAt("2018-04-25T22:42:10Z")
174+
.relationships(DeploymentRelationships.builder()
175+
.app(ToOneRelationship.builder()
176+
.data(Relationship.builder()
177+
.id("305cea31-5a44-45ca-b51b-e89c7a8ef8b2")
178+
.build())
179+
.build())
180+
.build())
181+
.link("self", Link.builder()
182+
.href("https://api.example.org/v3/deployments/59c3d133-2b83-46f3-960e-7765a129aea4")
183+
.build())
184+
.link("app", Link.builder()
185+
.href("https://api.example.org/v3/apps/305cea31-5a44-45ca-b51b-e89c7a8ef8b2")
186+
.build())
187+
.build())
188+
.expectComplete()
189+
.verify(Duration.ofSeconds(5));
190+
}
191+
192+
@Test
193+
public void list() {
194+
mockRequest(InteractionContext.builder()
195+
.request(TestRequest.builder()
196+
.method(GET).path("/deployments")
197+
.build())
198+
.response(TestResponse.builder()
199+
.status(OK)
200+
.payload("fixtures/client/v3/deployments/GET_response.json")
201+
.build())
202+
.build());
203+
204+
this.deployments
205+
.list(ListDeploymentsRequest.builder()
206+
.build())
207+
.as(StepVerifier::create)
208+
.expectNext(ListDeploymentsResponse.builder()
209+
.pagination(Pagination.builder()
210+
.totalResults(1)
211+
.totalPages(1)
212+
.first(Link.builder()
213+
.href("https://api.example.org/v3/deployments?page=1&per_page=2")
214+
.build())
215+
.last(Link.builder()
216+
.href("https://api.example.org/v3/deployments?page=1&per_page=2")
217+
.build())
218+
.build())
219+
.resource(DeploymentResource.builder()
220+
.id("59c3d133-2b83-46f3-960e-7765a129aea4")
221+
.state(DeploymentState.DEPLOYING)
222+
.droplet(Relationship.builder()
223+
.id("44ccfa61-dbcf-4a0d-82fe-f668e9d2a962")
224+
.build())
225+
.previousDroplet(Relationship.builder()
226+
.id("cc6bc315-bd06-49ce-92c2-bc3ad45268c2")
227+
.build())
228+
.newProcesses(singletonList(Process.builder()
229+
.id("fd5d3e60-f88c-4c37-b1ae-667cfc65a856")
230+
.type("web-deployment-59c3d133-2b83-46f3-960e-7765a129aea4")
231+
.build()))
232+
.revision(Revision.builder()
233+
.id("56126cba-656a-4eba-a81e-7e9951b2df57")
234+
.version(1)
235+
.build())
236+
.createdAt("2018-04-25T22:42:10Z")
237+
.updatedAt("2018-04-25T22:42:10Z")
238+
.relationships(DeploymentRelationships.builder()
239+
.app(ToOneRelationship.builder()
240+
.data(Relationship.builder()
241+
.id("305cea31-5a44-45ca-b51b-e89c7a8ef8b2")
242+
.build())
243+
.build())
244+
.build())
245+
.link("self", Link.builder()
246+
.href("https://api.example.org/v3/deployments/59c3d133-2b83-46f3-960e-7765a129aea4")
247+
.build())
248+
.link("app", Link.builder()
249+
.href("https://api.example.org/v3/apps/305cea31-5a44-45ca-b51b-e89c7a8ef8b2")
250+
.build())
251+
.build())
252+
.build())
253+
.expectComplete()
254+
.verify(Duration.ofSeconds(5));
255+
}
256+
257+
}

0 commit comments

Comments
 (0)