Skip to content

Commit 93da6f8

Browse files
committed
adding tests and wrapping up futures service
1 parent 3070869 commit 93da6f8

File tree

7 files changed

+104
-60
lines changed

7 files changed

+104
-60
lines changed

spring-cloud-modules/spring-cloud-openfeign-2/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@
77
<artifactId>spring-cloud-openfeign-2</artifactId>
88
<name>spring-cloud-openfeign-2</name>
99
<description>OpenFeign project for Spring Boot</description>
10+
<build>
11+
<plugins>
12+
<plugin>
13+
<groupId>org.apache.maven.plugins</groupId>
14+
<artifactId>maven-compiler-plugin</artifactId>
15+
<configuration>
16+
<source>9</source>
17+
<target>9</target>
18+
</configuration>
19+
</plugin>
20+
</plugins>
21+
</build>
1022

1123
<parent>
1224
<groupId>com.baeldung.spring.cloud</groupId>

spring-cloud-modules/spring-cloud-openfeign-2/src/main/java/com/baeldung/cloud/openfeign/completablefuturefeignclient/PaymentMethodClient.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
import java.util.List;
99

10-
@FeignClient(name = "paymentClient", url = "http://payments-api.com")
10+
@FeignClient(name = "paymentClient", url = "http://localhost:8083")
1111
public interface PaymentMethodClient {
1212

13-
@RequestMapping(method = RequestMethod.GET, value = "/payments/methods")
14-
List<String> getAvailablePaymentMethods(@RequestParam(name = "site_id") String siteId);
13+
@RequestMapping(method = RequestMethod.POST, value = "/purchase")
14+
String processPurchase(@RequestParam(name = "site_id") String siteId);
1515
}

spring-cloud-modules/spring-cloud-openfeign-2/src/main/java/com/baeldung/cloud/openfeign/completablefuturefeignclient/Purchase.java

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,12 @@
33
public class Purchase {
44

55
private String siteId;
6-
private long orderId;
76

8-
public Purchase(String siteId, long orderId) {
7+
public Purchase(String siteId) {
98
this.siteId = siteId;
10-
this.orderId = orderId;
119
}
1210

1311
public String getSiteId() {
1412
return siteId;
1513
}
16-
17-
public void setSiteId(String siteId) {
18-
this.siteId = siteId;
19-
}
20-
21-
public long getOrderId() {
22-
return orderId;
23-
}
24-
25-
public void setOrderId(long orderId) {
26-
this.orderId = orderId;
27-
}
2814
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package com.baeldung.cloud.openfeign.completablefuturefeignclient;
22

3+
import feign.FeignException;
34
import org.springframework.stereotype.Service;
45

56
import java.util.List;
67
import java.util.concurrent.CompletableFuture;
8+
import java.util.concurrent.ExecutionException;
9+
import java.util.concurrent.TimeUnit;
10+
11+
import static java.lang.String.format;
712

813
@Service
914
public class PurchaseService {
@@ -16,13 +21,26 @@ public PurchaseService(PaymentMethodClient paymentMethodClient, ReportClient rep
1621
this.reportClient = reportClient;
1722
}
1823

19-
public void executePurchase(Purchase purchase) {
24+
public String executePurchase(Purchase purchase) throws ExecutionException, InterruptedException {
25+
CompletableFuture<String> paymentMethodsFuture = CompletableFuture.supplyAsync(() -> paymentMethodClient.processPurchase(purchase.getSiteId()))
26+
.handle((res, ex) -> {
27+
if (ex.getCause() instanceof FeignException) {
28+
int status = ((FeignException) ex.getCause()).status();
29+
30+
if (status == 404) {
31+
return null;
32+
}
33+
}
34+
return res;
35+
})
36+
.orTimeout(2, TimeUnit.SECONDS);
37+
38+
CompletableFuture<Void> reportFuture = CompletableFuture.runAsync(() -> reportClient.sendReport("Purchase Order Report"))
39+
.orTimeout(1, TimeUnit.SECONDS);
2040

21-
ReportRequest report = new ReportRequest("Creating purchase for order", purchase.getOrderId(), purchase.getSiteId());
41+
CompletableFuture.allOf(paymentMethodsFuture, reportFuture)
42+
.join();
2243

23-
CompletableFuture.allOf(
24-
CompletableFuture.supplyAsync(() -> paymentMethodClient.getAvailablePaymentMethods(purchase.getSiteId())),
25-
CompletableFuture.runAsync(() -> reportClient.sendReport(report))
26-
);
44+
return paymentMethodsFuture.get();
2745
}
2846
}

spring-cloud-modules/spring-cloud-openfeign-2/src/main/java/com/baeldung/cloud/openfeign/completablefuturefeignclient/ReportClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
import org.springframework.web.bind.annotation.RequestMapping;
66
import org.springframework.web.bind.annotation.RequestMethod;
77

8-
@FeignClient(name = "reportClient", url = "http://reports-api.com")
8+
@FeignClient(name = "reportClient", url = "http://localhost:8083")
99
public interface ReportClient {
1010

1111
@RequestMapping(method = RequestMethod.POST, value = "/reports")
12-
void sendReport(@RequestBody ReportRequest reportRequest);
12+
void sendReport(@RequestBody String reportRequest);
1313
}

spring-cloud-modules/spring-cloud-openfeign-2/src/main/java/com/baeldung/cloud/openfeign/completablefuturefeignclient/ReportRequest.java

Lines changed: 0 additions & 34 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.baeldung.cloud.openfeign.completablefuturefeignclient;
2+
3+
import com.baeldung.cloud.openfeign.ExampleApplication;
4+
import com.github.tomakehurst.wiremock.WireMockServer;
5+
import org.junit.jupiter.api.AfterEach;
6+
import org.junit.jupiter.api.BeforeEach;
7+
import org.junit.jupiter.api.Test;
8+
import org.junit.jupiter.api.extension.ExtendWith;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.boot.test.context.SpringBootTest;
11+
import org.springframework.http.HttpStatus;
12+
import org.springframework.test.context.junit.jupiter.SpringExtension;
13+
14+
import java.util.concurrent.ExecutionException;
15+
16+
import static com.github.tomakehurst.wiremock.client.WireMock.*;
17+
import static org.junit.Assert.assertNull;
18+
import static org.junit.Assert.assertThrows;
19+
import static org.mockito.ArgumentMatchers.any;
20+
21+
@ExtendWith(SpringExtension.class)
22+
@SpringBootTest(classes = ExampleApplication.class)
23+
class PurchaseServiceIntegrationTest {
24+
25+
@Autowired
26+
private PurchaseService purchaseService;
27+
28+
@Autowired
29+
private PaymentMethodClient paymentMethodClient;
30+
31+
@Autowired
32+
private ReportClient reportClient;
33+
34+
private WireMockServer wireMockServer;
35+
36+
@BeforeEach
37+
public void startWireMockServer() {
38+
wireMockServer = new WireMockServer(8083);
39+
configureFor("localhost", 8083);
40+
wireMockServer.start();
41+
}
42+
43+
@AfterEach
44+
public void stopWireMockServer() {
45+
wireMockServer.stop();
46+
}
47+
48+
@Test
49+
void executePurchase() throws ExecutionException, InterruptedException {
50+
stubFor(post(urlEqualTo("/purchase?site_id=BR"))
51+
.willReturn(aResponse().withStatus(HttpStatus.NOT_FOUND.value())));
52+
53+
stubFor(post(urlEqualTo("/reports"))
54+
.willReturn(aResponse().withStatus(HttpStatus.OK.value())));
55+
56+
Purchase purchase = new Purchase("BR");
57+
58+
String result = purchaseService.executePurchase(purchase);
59+
60+
assertNull(result);
61+
}
62+
}

0 commit comments

Comments
 (0)