From 4ad9f38d1e5149826b942460fa2c685e6e183ee2 Mon Sep 17 00:00:00 2001 From: "marcin.mielnicki" Date: Mon, 15 Apr 2024 09:32:10 +0200 Subject: [PATCH 01/12] Add GetEmailResourceTest --- .../email/rest/EmailClient.java | 1 + .../email/rest/EmailController.java | 7 +++ .../email/rest/EmailService.java | 4 ++ .../email/rest/ExternalEmailClient.java | 5 ++ .../email/rest/GetEmailResourceTest.groovy | 52 +++++++++++++++++++ 5 files changed, 69 insertions(+) create mode 100644 part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailClient.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailClient.java index aa0e706..5dd0ca0 100644 --- a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailClient.java +++ b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailClient.java @@ -3,4 +3,5 @@ public interface EmailClient { void send(EmailRequest email); + EmailRequest read(String id); } diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailController.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailController.java index bd259d9..e723a54 100644 --- a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailController.java +++ b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailController.java @@ -1,6 +1,8 @@ package pl.allegro.tech.workshops.testsparallelexecution.email.rest; import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -15,6 +17,11 @@ public EmailController(EmailService emailService) { this.emailService = emailService; } + @GetMapping("/{id}") + public EmailRequest createEmail(@PathVariable String id) { + return emailService.getEmail(id); + } + @PostMapping() public void createEmail(@Valid @RequestBody EmailRequest email) { emailService.sendEmail(email); diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java index eab2665..cdcf2f8 100644 --- a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java +++ b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java @@ -26,4 +26,8 @@ public void sendEmail(EmailRequest email) { e); } } + + public EmailRequest getEmail(String id) { + return emailClient.read(id); + } } diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java index 8fec2f7..83c5c6d 100644 --- a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java +++ b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java @@ -31,4 +31,9 @@ public void send(EmailRequest email) { retryTemplate.execute(context -> restTemplate.postForEntity("/external-api-service/emails", email, Void.class)); } + @Override + public EmailRequest read(String id) { + return restTemplate.getForEntity("/external-api-service/emails/" + id, EmailRequest.class).getBody(); + } + } diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy new file mode 100644 index 0000000..803361d --- /dev/null +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy @@ -0,0 +1,52 @@ +package pl.allegro.tech.workshops.testsparallelexecution.email.rest + +import com.github.tomakehurst.wiremock.WireMockServer +import pl.allegro.tech.workshops.testsparallelexecution.BaseTestWithRest +import spock.lang.Shared + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse +import static com.github.tomakehurst.wiremock.client.WireMock.get +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo +import static org.springframework.http.HttpHeaders.CONTENT_TYPE +import static org.springframework.http.HttpStatus.OK +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE + +class GetEmailResourceTest extends BaseTestWithRest { + + @Shared + WireMockServer wiremockServer + + private String emailId = "2" + + def setupSpec() { + wiremockServer = new WireMockServer(8099) + wiremockServer.start() + } + + def cleanupSpec() { + wiremockServer.stop() + } + + def cleanup() { + wiremockServer.resetAll() + } + + def "get e-mail"() { + given: + wiremockServer.stubFor(get(urlEqualTo("/external-api-service/emails/$emailId")) + .willReturn(aResponse() + .withBody("""{"subject": "test subject", "sender": "from@example.com", "recipient": "to@example.com"}""") + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withStatus(200) + ) + ) + + when: + def result = restClient.get("/emails/$emailId", EmailRequest) + + then: + result.statusCode == OK + result.body == EmailRequest.of("test subject", "from@example.com", "to@example.com") + } + +} From b929e08aca09e6f5ebc24978da4f1ca1dfbd2a09 Mon Sep 17 00:00:00 2001 From: "marcin.mielnicki" Date: Mon, 15 Apr 2024 12:45:45 +0200 Subject: [PATCH 02/12] Add more tests to GetEmailResourceTest --- .../email/rest/EmailService.java | 10 ++- .../email/rest/ExternalEmailClient.java | 2 +- .../rest/EmailsByRestResourceTest.groovy | 2 + .../email/rest/GetEmailResourceTest.groovy | 72 +++++++++++++++++++ 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java index cdcf2f8..d65a267 100644 --- a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java +++ b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java @@ -28,6 +28,14 @@ public void sendEmail(EmailRequest email) { } public EmailRequest getEmail(String id) { - return emailClient.read(id); + try { + return emailClient.read(id); + } catch (Exception e) { + throw new ErrorResponseException( + HttpStatus.INTERNAL_SERVER_ERROR, + ProblemDetail.forStatusAndDetail(HttpStatus.INTERNAL_SERVER_ERROR, "Email service communication error. " + e.getMessage()), + e); + } + } } diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java index 83c5c6d..b98e96f 100644 --- a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java +++ b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java @@ -33,7 +33,7 @@ public void send(EmailRequest email) { @Override public EmailRequest read(String id) { - return restTemplate.getForEntity("/external-api-service/emails/" + id, EmailRequest.class).getBody(); + return retryTemplate.execute(context -> restTemplate.getForEntity("/external-api-service/emails/" + id, EmailRequest.class).getBody()); } } diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailsByRestResourceTest.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailsByRestResourceTest.groovy index 68af7f2..bb5c9c9 100644 --- a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailsByRestResourceTest.groovy +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailsByRestResourceTest.groovy @@ -106,6 +106,7 @@ class EmailsByRestResourceTest extends BaseTestWithRest { } def "handle email service errors (status=#errorResponse.status, fault=#errorResponse.fault, delay=#errorResponse.fixedDelayMilliseconds)"() { + given: def email = EmailRequest.of(subject, "from@example.com", "to@example.com") wiremockServer.stubFor(post(urlEqualTo("/external-api-service/emails")) .willReturn(errorResponse) @@ -130,6 +131,7 @@ class EmailsByRestResourceTest extends BaseTestWithRest { } def "retry email sending after error response (status=#errorResponse.status, fault=#errorResponse.fault, delay=#errorResponse.fixedDelayMilliseconds)"() { + given: def email = EmailRequest.of(subject, "from@example.com", "to@example.com") wiremockServer.stubFor(post(urlEqualTo("/external-api-service/emails")) .willReturn(errorResponse) diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy index 803361d..595dfa4 100644 --- a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy @@ -1,18 +1,25 @@ package pl.allegro.tech.workshops.testsparallelexecution.email.rest import com.github.tomakehurst.wiremock.WireMockServer +import com.github.tomakehurst.wiremock.stubbing.Scenario +import org.springframework.http.ProblemDetail import pl.allegro.tech.workshops.testsparallelexecution.BaseTestWithRest import spock.lang.Shared import static com.github.tomakehurst.wiremock.client.WireMock.aResponse import static com.github.tomakehurst.wiremock.client.WireMock.get import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo +import static com.github.tomakehurst.wiremock.http.Fault.CONNECTION_RESET_BY_PEER +import static com.github.tomakehurst.wiremock.http.Fault.EMPTY_RESPONSE import static org.springframework.http.HttpHeaders.CONTENT_TYPE +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR import static org.springframework.http.HttpStatus.OK import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE class GetEmailResourceTest extends BaseTestWithRest { + private static final String VALID_BODY = """{"subject": "test subject", "sender": "from@example.com", "recipient": "to@example.com"}""" + @Shared WireMockServer wiremockServer @@ -29,16 +36,69 @@ class GetEmailResourceTest extends BaseTestWithRest { def cleanup() { wiremockServer.resetAll() + wiremockServer.resetScenarios() } def "get e-mail"() { given: wiremockServer.stubFor(get(urlEqualTo("/external-api-service/emails/$emailId")) .willReturn(aResponse() + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withStatus(200) .withBody("""{"subject": "test subject", "sender": "from@example.com", "recipient": "to@example.com"}""") + ) + ) + + when: + def result = restClient.get("/emails/$emailId", EmailRequest) + + then: + result.statusCode == OK + result.body == EmailRequest.of("test subject", "from@example.com", "to@example.com") + } + + def "handle email service errors (status=#errorResponse.status, fault=#errorResponse.fault, delay=#errorResponse.fixedDelayMilliseconds)"() { + given: + wiremockServer.stubFor(get(urlEqualTo("/external-api-service/emails/$emailId")) + .willReturn(errorResponse) + ) + + when: + def result = restClient.get("/emails/$emailId", ProblemDetail) + + then: + result.statusCode == INTERNAL_SERVER_ERROR + result.body.detail.contains expectedDetail + + where: + errorResponse || expectedDetail + aResponse().withStatus(400) || "400 Bad Request" + aResponse().withStatus(500) || "500 Server Error" + aResponse().withFault(EMPTY_RESPONSE) || "Unexpected end of file from server" + aResponse().withFault(CONNECTION_RESET_BY_PEER) || "Connection reset" + aResponse().withFixedDelay(1000) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withStatus(200) + .withBody(VALID_BODY) || "Read timed out" + } + + def "retry email fetching after error response (status=#errorResponse.status, fault=#errorResponse.fault, delay=#errorResponse.fixedDelayMilliseconds)"() { + given: + wiremockServer.stubFor(get(urlEqualTo("/external-api-service/emails/$emailId")) + .willReturn(errorResponse) + .inScenario("retry scenario") + .whenScenarioStateIs(Scenario.STARTED) + .willSetStateTo('after error') + ) + wiremockServer.stubFor(get(urlEqualTo("/external-api-service/emails/$emailId")) + .willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) .withStatus(200) + .withBody("""{"subject": "test subject", "sender": "from@example.com", "recipient": "to@example.com"}""") ) + .inScenario("retry scenario") + .whenScenarioStateIs('after error') + .willSetStateTo('after ok') ) when: @@ -47,6 +107,18 @@ class GetEmailResourceTest extends BaseTestWithRest { then: result.statusCode == OK result.body == EmailRequest.of("test subject", "from@example.com", "to@example.com") + + where: + errorResponse << [ + aResponse().withStatus(400), + aResponse().withStatus(500), + aResponse().withFault(EMPTY_RESPONSE), + aResponse().withFault(CONNECTION_RESET_BY_PEER), + aResponse().withFixedDelay(1000) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withStatus(200) + .withBody(VALID_BODY) + ] } } From f06bca3457d8b8744ddadf4978ec0b911b67d399 Mon Sep 17 00:00:00 2001 From: "marcin.mielnicki" Date: Tue, 16 Apr 2024 07:56:39 +0200 Subject: [PATCH 03/12] Rename test class --- ...sByRestResourceTest.groovy => SendEmailResourceTest.groovy} | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/{EmailsByRestResourceTest.groovy => SendEmailResourceTest.groovy} (98%) diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailsByRestResourceTest.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy similarity index 98% rename from part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailsByRestResourceTest.groovy rename to part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy index bb5c9c9..e594125 100644 --- a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailsByRestResourceTest.groovy +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy @@ -8,7 +8,6 @@ import spock.lang.Shared import static com.github.tomakehurst.wiremock.client.WireMock.aResponse import static com.github.tomakehurst.wiremock.client.WireMock.equalTo -import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath import static com.github.tomakehurst.wiremock.client.WireMock.post import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo @@ -39,7 +38,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE } */ -class EmailsByRestResourceTest extends BaseTestWithRest { +class SendEmailResourceTest extends BaseTestWithRest { @Shared WireMockServer wiremockServer From 0bb86d6157cb4763f1160617cedcb63301da9664 Mon Sep 17 00:00:00 2001 From: "marcin.mielnicki" Date: Tue, 16 Apr 2024 07:58:35 +0200 Subject: [PATCH 04/12] Rename EmailRequest to Email --- .../testsparallelexecution/email/rest/Email.java | 12 ++++++++++++ .../email/rest/EmailClient.java | 4 ++-- .../email/rest/EmailController.java | 4 ++-- .../email/rest/EmailRequest.java | 12 ------------ .../email/rest/EmailService.java | 4 ++-- .../email/rest/ExternalEmailClient.java | 6 +++--- .../email/rest/GetEmailResourceTest.groovy | 8 ++++---- .../email/rest/SendEmailResourceTest.groovy | 8 ++++---- .../email/messagebroker/Email.java | 12 ++++++++++++ .../email/messagebroker/EmailClient.java | 2 +- .../email/messagebroker/EmailController.java | 2 +- .../email/messagebroker/EmailRequest.java | 12 ------------ .../email/messagebroker/EmailService.java | 2 +- .../messagebroker/MessageBrokerEmailClient.java | 4 ++-- .../EmailsByMessageBrokerResourceTest.groovy | 12 ++++++------ 15 files changed, 52 insertions(+), 52 deletions(-) create mode 100644 part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/Email.java delete mode 100644 part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailRequest.java create mode 100644 part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/Email.java delete mode 100644 part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailRequest.java diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/Email.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/Email.java new file mode 100644 index 0000000..191afb2 --- /dev/null +++ b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/Email.java @@ -0,0 +1,12 @@ +package pl.allegro.tech.workshops.testsparallelexecution.email.rest; + + +import jakarta.validation.constraints.NotBlank; + +public record Email(String subject, @NotBlank String sender, String recipient) { + + static public Email of(String subject, String sender, String recipient) { + return new Email(subject, sender, recipient); + } + +} \ No newline at end of file diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailClient.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailClient.java index 5dd0ca0..ca58434 100644 --- a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailClient.java +++ b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailClient.java @@ -1,7 +1,7 @@ package pl.allegro.tech.workshops.testsparallelexecution.email.rest; public interface EmailClient { - void send(EmailRequest email); + void send(Email email); - EmailRequest read(String id); + Email read(String id); } diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailController.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailController.java index e723a54..f00034b 100644 --- a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailController.java +++ b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailController.java @@ -18,12 +18,12 @@ public EmailController(EmailService emailService) { } @GetMapping("/{id}") - public EmailRequest createEmail(@PathVariable String id) { + public Email createEmail(@PathVariable String id) { return emailService.getEmail(id); } @PostMapping() - public void createEmail(@Valid @RequestBody EmailRequest email) { + public void createEmail(@Valid @RequestBody Email email) { emailService.sendEmail(email); } diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailRequest.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailRequest.java deleted file mode 100644 index cd9115c..0000000 --- a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailRequest.java +++ /dev/null @@ -1,12 +0,0 @@ -package pl.allegro.tech.workshops.testsparallelexecution.email.rest; - - -import jakarta.validation.constraints.NotBlank; - -public record EmailRequest(String subject, @NotBlank String sender, String recipient) { - - static public EmailRequest of(String subject, String sender, String recipient) { - return new EmailRequest(subject, sender, recipient); - } - -} \ No newline at end of file diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java index d65a267..5a5f29e 100644 --- a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java +++ b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/EmailService.java @@ -16,7 +16,7 @@ public EmailService(EmailClient emailClient) { this.emailClient = emailClient; } - public void sendEmail(EmailRequest email) { + public void sendEmail(Email email) { try { emailClient.send(email); } catch (Exception e) { @@ -27,7 +27,7 @@ public void sendEmail(EmailRequest email) { } } - public EmailRequest getEmail(String id) { + public Email getEmail(String id) { try { return emailClient.read(id); } catch (Exception e) { diff --git a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java index b98e96f..63210ec 100644 --- a/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java +++ b/part2.2-rest/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/rest/ExternalEmailClient.java @@ -27,13 +27,13 @@ public ExternalEmailClient(RestTemplateBuilder builder, @Value("${application.se } @Override - public void send(EmailRequest email) { + public void send(Email email) { retryTemplate.execute(context -> restTemplate.postForEntity("/external-api-service/emails", email, Void.class)); } @Override - public EmailRequest read(String id) { - return retryTemplate.execute(context -> restTemplate.getForEntity("/external-api-service/emails/" + id, EmailRequest.class).getBody()); + public Email read(String id) { + return retryTemplate.execute(context -> restTemplate.getForEntity("/external-api-service/emails/" + id, Email.class).getBody()); } } diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy index 595dfa4..0813323 100644 --- a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy @@ -50,11 +50,11 @@ class GetEmailResourceTest extends BaseTestWithRest { ) when: - def result = restClient.get("/emails/$emailId", EmailRequest) + def result = restClient.get("/emails/$emailId", Email) then: result.statusCode == OK - result.body == EmailRequest.of("test subject", "from@example.com", "to@example.com") + result.body == Email.of("test subject", "from@example.com", "to@example.com") } def "handle email service errors (status=#errorResponse.status, fault=#errorResponse.fault, delay=#errorResponse.fixedDelayMilliseconds)"() { @@ -102,11 +102,11 @@ class GetEmailResourceTest extends BaseTestWithRest { ) when: - def result = restClient.get("/emails/$emailId", EmailRequest) + def result = restClient.get("/emails/$emailId", Email) then: result.statusCode == OK - result.body == EmailRequest.of("test subject", "from@example.com", "to@example.com") + result.body == Email.of("test subject", "from@example.com", "to@example.com") where: errorResponse << [ diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy index e594125..788261a 100644 --- a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy @@ -61,7 +61,7 @@ class SendEmailResourceTest extends BaseTestWithRest { def "send e-mail"() { given: - def email = EmailRequest.of(subject, "from@example.com", "to@example.com") + def email = Email.of(subject, "from@example.com", "to@example.com") wiremockServer.stubFor(post(urlEqualTo("/external-api-service/emails")) .willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) @@ -81,7 +81,7 @@ class SendEmailResourceTest extends BaseTestWithRest { def "do not sent email without sender"() { given: - def email = EmailRequest.of(subject, sender, "to@example.com") + def email = Email.of(subject, sender, "to@example.com") wiremockServer.stubFor(post(urlEqualTo("/external-api-service/emails")) .willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) @@ -106,7 +106,7 @@ class SendEmailResourceTest extends BaseTestWithRest { def "handle email service errors (status=#errorResponse.status, fault=#errorResponse.fault, delay=#errorResponse.fixedDelayMilliseconds)"() { given: - def email = EmailRequest.of(subject, "from@example.com", "to@example.com") + def email = Email.of(subject, "from@example.com", "to@example.com") wiremockServer.stubFor(post(urlEqualTo("/external-api-service/emails")) .willReturn(errorResponse) ) @@ -131,7 +131,7 @@ class SendEmailResourceTest extends BaseTestWithRest { def "retry email sending after error response (status=#errorResponse.status, fault=#errorResponse.fault, delay=#errorResponse.fixedDelayMilliseconds)"() { given: - def email = EmailRequest.of(subject, "from@example.com", "to@example.com") + def email = Email.of(subject, "from@example.com", "to@example.com") wiremockServer.stubFor(post(urlEqualTo("/external-api-service/emails")) .willReturn(errorResponse) .inScenario("retry scenario") diff --git a/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/Email.java b/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/Email.java new file mode 100644 index 0000000..b630f64 --- /dev/null +++ b/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/Email.java @@ -0,0 +1,12 @@ +package pl.allegro.tech.workshops.testsparallelexecution.email.messagebroker; + + +import jakarta.validation.constraints.NotBlank; + +public record Email(String subject, @NotBlank String sender, String recipient) { + + static public Email of(String subject, String sender, String recipient) { + return new Email(subject, sender, recipient); + } + +} \ No newline at end of file diff --git a/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailClient.java b/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailClient.java index 5bd77bb..dbc272d 100644 --- a/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailClient.java +++ b/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailClient.java @@ -1,6 +1,6 @@ package pl.allegro.tech.workshops.testsparallelexecution.email.messagebroker; public interface EmailClient { - void send(EmailRequest email); + void send(Email email); } diff --git a/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailController.java b/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailController.java index af226bc..aec31d8 100644 --- a/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailController.java +++ b/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailController.java @@ -16,7 +16,7 @@ public EmailController(EmailService emailService) { } @PostMapping() - public void createEmail(@Valid @RequestBody EmailRequest email) { + public void createEmail(@Valid @RequestBody Email email) { emailService.sendEmail(email); } diff --git a/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailRequest.java b/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailRequest.java deleted file mode 100644 index 6da1ec3..0000000 --- a/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailRequest.java +++ /dev/null @@ -1,12 +0,0 @@ -package pl.allegro.tech.workshops.testsparallelexecution.email.messagebroker; - - -import jakarta.validation.constraints.NotBlank; - -public record EmailRequest(String subject, @NotBlank String sender, String recipient) { - - static public EmailRequest of(String subject, String sender, String recipient) { - return new EmailRequest(subject, sender, recipient); - } - -} \ No newline at end of file diff --git a/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailService.java b/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailService.java index 70397aa..1a614a7 100644 --- a/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailService.java +++ b/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailService.java @@ -12,7 +12,7 @@ public class EmailService { public EmailService(EmailClient emailClient) { this.emailClient = emailClient; } - public void sendEmail(EmailRequest email) { + public void sendEmail(Email email) { emailClient.send(email); } } diff --git a/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/MessageBrokerEmailClient.java b/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/MessageBrokerEmailClient.java index 674c757..9a0ee5f 100644 --- a/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/MessageBrokerEmailClient.java +++ b/part2.3-message-broker/src/main/java/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/MessageBrokerEmailClient.java @@ -36,7 +36,7 @@ public MessageBrokerEmailClient(@Value("${application.services.message-broker.ur } @Override - public void send(EmailRequest email) { + public void send(Email email) { try { String message = new ObjectMapper().writeValueAsString(EmailServiceEvent.from(email)); HermesResponse hermesResponse = client.publishJSON(topic, message).get(); @@ -50,7 +50,7 @@ public void send(EmailRequest email) { } record EmailServiceEvent(String from, String to, String subject) { - public static EmailServiceEvent from(EmailRequest email) { + public static EmailServiceEvent from(Email email) { return new EmailServiceEvent(email.sender(), email.recipient(), email.subject()); } } diff --git a/part2.3-message-broker/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailsByMessageBrokerResourceTest.groovy b/part2.3-message-broker/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailsByMessageBrokerResourceTest.groovy index 8d8e79c..aed0833 100644 --- a/part2.3-message-broker/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailsByMessageBrokerResourceTest.groovy +++ b/part2.3-message-broker/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/messagebroker/EmailsByMessageBrokerResourceTest.groovy @@ -41,7 +41,7 @@ class EmailsByMessageBrokerResourceTest extends BaseTestWithRest implements Herm def "send e-mail"() { given: - def email = EmailRequest.of(subject, "from@example.com", "to@example.com") + def email = Email.of(subject, "from@example.com", "to@example.com") /** * Hints: * - Replace `jsonTopic` with {@link pl.allegro.tech.hermes.mock.HermesMockDefine#jsonTopic(java.lang.String, pl.allegro.tech.hermes.mock.exchange.Response, java.lang.Class, java.util.function.Predicate)} @@ -51,7 +51,7 @@ class EmailsByMessageBrokerResourceTest extends BaseTestWithRest implements Herm hermesMock.define().jsonTopic(topic, aResponse().build()) when: - def result = restClient.post("/emails", email, EmailRequest) + def result = restClient.post("/emails", email, Email) then: result.statusCode == OK @@ -64,13 +64,13 @@ class EmailsByMessageBrokerResourceTest extends BaseTestWithRest implements Herm def "do not sent email without sender"() { given: - def email = EmailRequest.of(subject, sender, "to@example.com") + def email = Email.of(subject, sender, "to@example.com") hermesMock.define().jsonTopic(topic, aResponse().build()) // sleep to simulate long response sleep 500 when: - def result = restClient.post("/emails", email, EmailRequest) + def result = restClient.post("/emails", email, Email) then: result.statusCode == BAD_REQUEST @@ -81,11 +81,11 @@ class EmailsByMessageBrokerResourceTest extends BaseTestWithRest implements Herm } def "handle email service errors"() { - def email = EmailRequest.of(subject, "from@example.com", "to@example.com") + def email = Email.of(subject, "from@example.com", "to@example.com") hermesMock.define().jsonTopic(topic, errorResponse) when: - def result = restClient.post("/emails", email, EmailRequest) + def result = restClient.post("/emails", email, Email) then: result.statusCode == INTERNAL_SERVER_ERROR From 61f1a306390bfdbc0eadc97978bf918cb6fe53d9 Mon Sep 17 00:00:00 2001 From: "marcin.mielnicki" Date: Tue, 16 Apr 2024 08:05:32 +0200 Subject: [PATCH 05/12] Use urlPathMatching/urlPathEqualTo in tests --- .../email/rest/GetEmailResourceTest.groovy | 10 +++++----- .../email/rest/SendEmailResourceTest.groovy | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy index 0813323..06942b4 100644 --- a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy @@ -8,7 +8,7 @@ import spock.lang.Shared import static com.github.tomakehurst.wiremock.client.WireMock.aResponse import static com.github.tomakehurst.wiremock.client.WireMock.get -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching import static com.github.tomakehurst.wiremock.http.Fault.CONNECTION_RESET_BY_PEER import static com.github.tomakehurst.wiremock.http.Fault.EMPTY_RESPONSE import static org.springframework.http.HttpHeaders.CONTENT_TYPE @@ -41,7 +41,7 @@ class GetEmailResourceTest extends BaseTestWithRest { def "get e-mail"() { given: - wiremockServer.stubFor(get(urlEqualTo("/external-api-service/emails/$emailId")) + wiremockServer.stubFor(get(urlPathMatching("/external-api-service/emails/.*")) .willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) .withStatus(200) @@ -59,7 +59,7 @@ class GetEmailResourceTest extends BaseTestWithRest { def "handle email service errors (status=#errorResponse.status, fault=#errorResponse.fault, delay=#errorResponse.fixedDelayMilliseconds)"() { given: - wiremockServer.stubFor(get(urlEqualTo("/external-api-service/emails/$emailId")) + wiremockServer.stubFor(get(urlPathMatching("/external-api-service/emails/.*")) .willReturn(errorResponse) ) @@ -84,13 +84,13 @@ class GetEmailResourceTest extends BaseTestWithRest { def "retry email fetching after error response (status=#errorResponse.status, fault=#errorResponse.fault, delay=#errorResponse.fixedDelayMilliseconds)"() { given: - wiremockServer.stubFor(get(urlEqualTo("/external-api-service/emails/$emailId")) + wiremockServer.stubFor(get(urlPathMatching("/external-api-service/emails/.*")) .willReturn(errorResponse) .inScenario("retry scenario") .whenScenarioStateIs(Scenario.STARTED) .willSetStateTo('after error') ) - wiremockServer.stubFor(get(urlEqualTo("/external-api-service/emails/$emailId")) + wiremockServer.stubFor(get(urlPathMatching("/external-api-service/emails/.*")) .willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) .withStatus(200) diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy index 788261a..9420f75 100644 --- a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy @@ -10,7 +10,7 @@ import static com.github.tomakehurst.wiremock.client.WireMock.aResponse import static com.github.tomakehurst.wiremock.client.WireMock.equalTo import static com.github.tomakehurst.wiremock.client.WireMock.post import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo import static com.github.tomakehurst.wiremock.http.Fault.CONNECTION_RESET_BY_PEER import static com.github.tomakehurst.wiremock.http.Fault.EMPTY_RESPONSE import static org.springframework.http.HttpHeaders.ACCEPT @@ -62,7 +62,7 @@ class SendEmailResourceTest extends BaseTestWithRest { def "send e-mail"() { given: def email = Email.of(subject, "from@example.com", "to@example.com") - wiremockServer.stubFor(post(urlEqualTo("/external-api-service/emails")) + wiremockServer.stubFor(post(urlPathEqualTo("/external-api-service/emails")) .willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) .withStatus(200) @@ -74,7 +74,7 @@ class SendEmailResourceTest extends BaseTestWithRest { then: result.statusCode == OK - wiremockServer.verify(1, postRequestedFor(urlEqualTo("/external-api-service/emails")) + wiremockServer.verify(1, postRequestedFor(urlPathEqualTo("/external-api-service/emails")) .withHeader(ACCEPT, equalTo("application/json, application/*+json")) ) } @@ -82,7 +82,7 @@ class SendEmailResourceTest extends BaseTestWithRest { def "do not sent email without sender"() { given: def email = Email.of(subject, sender, "to@example.com") - wiremockServer.stubFor(post(urlEqualTo("/external-api-service/emails")) + wiremockServer.stubFor(post(urlPathEqualTo("/external-api-service/emails")) .willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) .withStatus(200) @@ -96,7 +96,7 @@ class SendEmailResourceTest extends BaseTestWithRest { then: result.statusCode == BAD_REQUEST - wiremockServer.verify(0, postRequestedFor(urlEqualTo("/external-api-service/emails")) + wiremockServer.verify(0, postRequestedFor(urlPathEqualTo("/external-api-service/emails")) .withHeader(ACCEPT, equalTo("application/json, application/*+json")) ) @@ -107,7 +107,7 @@ class SendEmailResourceTest extends BaseTestWithRest { def "handle email service errors (status=#errorResponse.status, fault=#errorResponse.fault, delay=#errorResponse.fixedDelayMilliseconds)"() { given: def email = Email.of(subject, "from@example.com", "to@example.com") - wiremockServer.stubFor(post(urlEqualTo("/external-api-service/emails")) + wiremockServer.stubFor(post(urlPathEqualTo("/external-api-service/emails")) .willReturn(errorResponse) ) @@ -132,13 +132,13 @@ class SendEmailResourceTest extends BaseTestWithRest { def "retry email sending after error response (status=#errorResponse.status, fault=#errorResponse.fault, delay=#errorResponse.fixedDelayMilliseconds)"() { given: def email = Email.of(subject, "from@example.com", "to@example.com") - wiremockServer.stubFor(post(urlEqualTo("/external-api-service/emails")) + wiremockServer.stubFor(post(urlPathEqualTo("/external-api-service/emails")) .willReturn(errorResponse) .inScenario("retry scenario") .whenScenarioStateIs(Scenario.STARTED) .willSetStateTo('after error') ) - wiremockServer.stubFor(post(urlEqualTo("/external-api-service/emails")) + wiremockServer.stubFor(post(urlPathEqualTo("/external-api-service/emails")) .willReturn(aResponse() .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) .withStatus(200) From cff0db5be364ce03aafb4d99b42cce363f5276e7 Mon Sep 17 00:00:00 2001 From: "marcin.mielnicki" Date: Tue, 16 Apr 2024 08:32:42 +0200 Subject: [PATCH 06/12] Start Wiremock once, update diagrams --- .../BaseTestWithRest.groovy | 1 + part2.2-rest/.readme/sequence.md | 11 ++++++++++ part2.2-rest/.readme/sequence.svg | 7 +------ .../email/rest/GetEmailResourceTest.groovy | 21 +++++++------------ .../email/rest/SendEmailResourceTest.groovy | 19 ++++++----------- .../email/rest/WiremockConfig.groovy | 17 +++++++++++++++ .../email/rest/WiremockPortSupport.groovy | 14 +++++++++++++ .../src/test/resources/application.yml | 2 +- 8 files changed, 58 insertions(+), 34 deletions(-) create mode 100644 part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/WiremockConfig.groovy create mode 100644 part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/WiremockPortSupport.groovy diff --git a/commons-rest/src/main/groovy/pl/allegro/tech/workshops/testsparallelexecution/BaseTestWithRest.groovy b/commons-rest/src/main/groovy/pl/allegro/tech/workshops/testsparallelexecution/BaseTestWithRest.groovy index e55514f..c0ff99e 100644 --- a/commons-rest/src/main/groovy/pl/allegro/tech/workshops/testsparallelexecution/BaseTestWithRest.groovy +++ b/commons-rest/src/main/groovy/pl/allegro/tech/workshops/testsparallelexecution/BaseTestWithRest.groovy @@ -1,5 +1,6 @@ package pl.allegro.tech.workshops.testsparallelexecution + import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.web.client.TestRestTemplate diff --git a/part2.2-rest/.readme/sequence.md b/part2.2-rest/.readme/sequence.md index 52cf808..5d6983c 100644 --- a/part2.2-rest/.readme/sequence.md +++ b/part2.2-rest/.readme/sequence.md @@ -8,4 +8,15 @@ sequenceDiagram REST API ->>+ external service: POST /external-api-service/emails
{"subject": "New ...", "sender": "...", "recipient": "..."} external service -->>- REST API: response REST API -->>- User: response + Note over User, external service: read e-mail + User ->>+ REST API: GET /emails/{id} + REST API ->>+ external service: GET /external-api-service/emails/{id} + external service -->>- REST API: response
{"subject": "New ...", "sender": "...", "recipient": "..."} + REST API -->>- User: response
{"subject": "New ...", "sender": "...", "recipient": "..."} ``` + +Convert to svg format + +```shell +npx @mermaid-js/mermaid-cli mmdc -i part2.2-rest/.readme/sequence.md -o part2.2-rest/.readme/sequence.svg -t dark -b transparent +``` \ No newline at end of file diff --git a/part2.2-rest/.readme/sequence.svg b/part2.2-rest/.readme/sequence.svg index 8a29573..d755f11 100644 --- a/part2.2-rest/.readme/sequence.svg +++ b/part2.2-rest/.readme/sequence.svg @@ -1,6 +1 @@ -external e-mail REST serviceREST APIUserexternal e-mail REST serviceREST APIUsersend e-mailPOST /emails {"subject": "New ...", "sender": "...", "recipient": "..."}POST /external-api-service/emails {"subject": "New ...", "sender": "...", "recipient": "..."}responseresponse \ No newline at end of file +external e-mail REST serviceREST APIUserexternal e-mail REST serviceREST APIUsersend e-mailread e-mailPOST /emails {"subject": "New ...", "sender": "...", "recipient": "..."}POST /external-api-service/emails {"subject": "New ...", "sender": "...", "recipient": "..."}responseresponseGET /emails/{id}GET /external-api-service/emails/{id}response {"subject": "New ...", "sender": "...", "recipient": "..."}response {"subject": "New ...", "sender": "...", "recipient": "..."} \ No newline at end of file diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy index 06942b4..2a690d3 100644 --- a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/GetEmailResourceTest.groovy @@ -2,9 +2,10 @@ package pl.allegro.tech.workshops.testsparallelexecution.email.rest import com.github.tomakehurst.wiremock.WireMockServer import com.github.tomakehurst.wiremock.stubbing.Scenario +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Import import org.springframework.http.ProblemDetail import pl.allegro.tech.workshops.testsparallelexecution.BaseTestWithRest -import spock.lang.Shared import static com.github.tomakehurst.wiremock.client.WireMock.aResponse import static com.github.tomakehurst.wiremock.client.WireMock.get @@ -16,24 +17,16 @@ import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR import static org.springframework.http.HttpStatus.OK import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE -class GetEmailResourceTest extends BaseTestWithRest { +@Import(WiremockConfig) +class GetEmailResourceTest extends BaseTestWithRest implements WiremockPortSupport { - private static final String VALID_BODY = """{"subject": "test subject", "sender": "from@example.com", "recipient": "to@example.com"}""" + @Autowired + private WireMockServer wiremockServer - @Shared - WireMockServer wiremockServer + private static final String VALID_BODY = """{"subject": "test subject", "sender": "from@example.com", "recipient": "to@example.com"}""" private String emailId = "2" - def setupSpec() { - wiremockServer = new WireMockServer(8099) - wiremockServer.start() - } - - def cleanupSpec() { - wiremockServer.stop() - } - def cleanup() { wiremockServer.resetAll() wiremockServer.resetScenarios() diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy index 9420f75..243896d 100644 --- a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/SendEmailResourceTest.groovy @@ -2,9 +2,10 @@ package pl.allegro.tech.workshops.testsparallelexecution.email.rest import com.github.tomakehurst.wiremock.WireMockServer import com.github.tomakehurst.wiremock.stubbing.Scenario +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Import import org.springframework.http.ProblemDetail import pl.allegro.tech.workshops.testsparallelexecution.BaseTestWithRest -import spock.lang.Shared import static com.github.tomakehurst.wiremock.client.WireMock.aResponse import static com.github.tomakehurst.wiremock.client.WireMock.equalTo @@ -38,22 +39,14 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE } */ -class SendEmailResourceTest extends BaseTestWithRest { +@Import(WiremockConfig) +class SendEmailResourceTest extends BaseTestWithRest implements WiremockPortSupport { - @Shared - WireMockServer wiremockServer + @Autowired + private WireMockServer wiremockServer private String subject = "New workshops!" - def setupSpec() { - wiremockServer = new WireMockServer(8099) - wiremockServer.start() - } - - def cleanupSpec() { - wiremockServer.stop() - } - def cleanup() { wiremockServer.resetAll() wiremockServer.resetScenarios() diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/WiremockConfig.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/WiremockConfig.groovy new file mode 100644 index 0000000..40571d6 --- /dev/null +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/WiremockConfig.groovy @@ -0,0 +1,17 @@ +package pl.allegro.tech.workshops.testsparallelexecution.email.rest + +import com.github.tomakehurst.wiremock.WireMockServer +import org.springframework.beans.factory.annotation.Value +import org.springframework.boot.test.context.TestConfiguration +import org.springframework.context.annotation.Bean + +@TestConfiguration +class WiremockConfig { + + @Bean + WireMockServer getWiremockServer(@Value('${wiremock.port}') int wiremockPort) { + return new WireMockServer(wiremockPort).tap { + it.start() + } + } +} diff --git a/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/WiremockPortSupport.groovy b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/WiremockPortSupport.groovy new file mode 100644 index 0000000..cc27078 --- /dev/null +++ b/part2.2-rest/src/test/groovy/pl/allegro/tech/workshops/testsparallelexecution/email/rest/WiremockPortSupport.groovy @@ -0,0 +1,14 @@ +package pl.allegro.tech.workshops.testsparallelexecution.email.rest + +import org.springframework.test.context.DynamicPropertyRegistry +import org.springframework.test.context.DynamicPropertySource +import org.springframework.test.util.TestSocketUtils + +trait WiremockPortSupport { + + @DynamicPropertySource + static void configurePort(DynamicPropertyRegistry registry) { + int port = TestSocketUtils.findAvailableTcpPort() + registry.add("wiremock.port", () -> port) + } +} diff --git a/part2.2-rest/src/test/resources/application.yml b/part2.2-rest/src/test/resources/application.yml index 1c9c970..cd78e70 100644 --- a/part2.2-rest/src/test/resources/application.yml +++ b/part2.2-rest/src/test/resources/application.yml @@ -1 +1 @@ -application.services.email.url: http://localhost:8099 +application.services.email.url: http://localhost:${wiremock.port} From 65bdadde170e7243396fbcaae99c7c8eb609ec73 Mon Sep 17 00:00:00 2001 From: "marcin.mielnicki" Date: Tue, 16 Apr 2024 09:28:12 +0200 Subject: [PATCH 07/12] Update diagram --- part2.2-rest/.readme/sequence.md | 4 ++-- part2.2-rest/.readme/sequence.svg | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/part2.2-rest/.readme/sequence.md b/part2.2-rest/.readme/sequence.md index 5d6983c..16d26a3 100644 --- a/part2.2-rest/.readme/sequence.md +++ b/part2.2-rest/.readme/sequence.md @@ -18,5 +18,5 @@ sequenceDiagram Convert to svg format ```shell -npx @mermaid-js/mermaid-cli mmdc -i part2.2-rest/.readme/sequence.md -o part2.2-rest/.readme/sequence.svg -t dark -b transparent -``` \ No newline at end of file +npx @mermaid-js/mermaid-cli mmdc -i part2.2-rest/.readme/sequence.md -o part2.2-rest/.readme/sequence.svg -t dark --cssFile .readme/diagrams.css +``` diff --git a/part2.2-rest/.readme/sequence.svg b/part2.2-rest/.readme/sequence.svg index d755f11..abff5dd 100644 --- a/part2.2-rest/.readme/sequence.svg +++ b/part2.2-rest/.readme/sequence.svg @@ -1 +1,6 @@ -external e-mail REST serviceREST APIUserexternal e-mail REST serviceREST APIUsersend e-mailread e-mailPOST /emails {"subject": "New ...", "sender": "...", "recipient": "..."}POST /external-api-service/emails {"subject": "New ...", "sender": "...", "recipient": "..."}responseresponseGET /emails/{id}GET /external-api-service/emails/{id}response {"subject": "New ...", "sender": "...", "recipient": "..."}response {"subject": "New ...", "sender": "...", "recipient": "..."} \ No newline at end of file +external e-mail REST serviceREST APIUserexternal e-mail REST serviceREST APIUsersend e-mailread e-mailPOST /emails {"subject": "New ...", "sender": "...", "recipient": "..."}POST /external-api-service/emails {"subject": "New ...", "sender": "...", "recipient": "..."}responseresponseGET /emails/{id}GET /external-api-service/emails/{id}response {"subject": "New ...", "sender": "...", "recipient": "..."}response {"subject": "New ...", "sender": "...", "recipient": "..."} \ No newline at end of file From 141ec664b9cfb3379638ad2ccc85b2d464aeac4a Mon Sep 17 00:00:00 2001 From: "marcin.mielnicki" Date: Tue, 16 Apr 2024 09:44:04 +0200 Subject: [PATCH 08/12] Update diagram --- part2.2-rest/.readme/sequence.md | 2 +- part2.2-rest/.readme/sequence.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/part2.2-rest/.readme/sequence.md b/part2.2-rest/.readme/sequence.md index 16d26a3..765fb73 100644 --- a/part2.2-rest/.readme/sequence.md +++ b/part2.2-rest/.readme/sequence.md @@ -18,5 +18,5 @@ sequenceDiagram Convert to svg format ```shell -npx @mermaid-js/mermaid-cli mmdc -i part2.2-rest/.readme/sequence.md -o part2.2-rest/.readme/sequence.svg -t dark --cssFile .readme/diagrams.css +npx @mermaid-js/mermaid-cli mmdc -i part2.2-rest/.readme/sequence.md -o part2.2-rest/.readme/sequence.svg -b transparent --cssFile .readme/diagrams.css ``` diff --git a/part2.2-rest/.readme/sequence.svg b/part2.2-rest/.readme/sequence.svg index abff5dd..2dee104 100644 --- a/part2.2-rest/.readme/sequence.svg +++ b/part2.2-rest/.readme/sequence.svg @@ -1,4 +1,4 @@ -external e-mail REST serviceREST APIUserexternal e-mail REST serviceREST APIUsersend e-mailread e-mailPOST /emails {"subject": "New ...", "sender": "...", "recipient": "..."}POST /external-api-service/emails {"subject": "New ...", "sender": "...", "recipient": "..."}responseresponseGET /emails/{id}GET /external-api-service/emails/{id}response {"subject": "New ...", "sender": "...", "recipient": "..."}response {"subject": "New ...", "sender": "...", "recipient": "..."}