diff --git a/build.gradle b/build.gradle index 30802617..00888def 100644 --- a/build.gradle +++ b/build.gradle @@ -28,10 +28,11 @@ apply { from("$rootDir/gradle/github/jar.gradle") from("$rootDir/gradle/tasks/apitest.gradle") + from("$rootDir/gradle/dependencies/spring-cloud.gradle") } dependencies { - implementation(group: 'uk.gov.hmcts.cp', name: 'api-cp-crime-hearing-case-event-subscription', version: '1.0.0-cc7de31') + implementation(group: 'uk.gov.hmcts.cp', name: 'api-cp-crime-hearing-case-event-subscription', version: '1.0.2') // This is proving to be a real puzzle. This is actually included in the api published pom // ( though with scope of "runtime" ) diff --git a/gradle/dependencies/spring-cloud.gradle b/gradle/dependencies/spring-cloud.gradle index 799e46c2..4341487e 100644 --- a/gradle/dependencies/spring-cloud.gradle +++ b/gradle/dependencies/spring-cloud.gradle @@ -6,6 +6,8 @@ dependencyManagement { dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' - testImplementation 'org.wiremock.integrations:wiremock-spring-boot:3.2.0' -} \ No newline at end of file + testImplementation 'org.wiremock:wiremock-standalone:3.3.1' + + +} diff --git a/src/main/java/uk/gov/hmcts/cp/subscription/client/DocumentServiceClient.java b/src/main/java/uk/gov/hmcts/cp/subscription/client/DocumentServiceClient.java new file mode 100644 index 00000000..9263d096 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/cp/subscription/client/DocumentServiceClient.java @@ -0,0 +1,18 @@ +package uk.gov.hmcts.cp.subscription.client; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import uk.gov.hmcts.cp.openapi.model.PcrEventPayload; + +@FeignClient( + name = "document-service", + url = "${document-service.url}" +) +public interface DocumentServiceClient { + @PostMapping( + value = "/client-webhook-url", + consumes = "application/json" + ) + void updateDocumentMetadata(@RequestBody PcrEventPayload request); +} diff --git a/src/main/java/uk/gov/hmcts/cp/subscription/services/WebhookService.java b/src/main/java/uk/gov/hmcts/cp/subscription/services/WebhookService.java new file mode 100644 index 00000000..93b1873f --- /dev/null +++ b/src/main/java/uk/gov/hmcts/cp/subscription/services/WebhookService.java @@ -0,0 +1,26 @@ +package uk.gov.hmcts.cp.subscription.services; + +import feign.FeignException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.cp.openapi.model.PcrEventPayload; +import uk.gov.hmcts.cp.subscription.client.DocumentServiceClient; + +@Service +@RequiredArgsConstructor +@Slf4j +public class WebhookService { + + private final DocumentServiceClient client; + + public void processPcrEvent(final PcrEventPayload payload) { + try { + client.updateDocumentMetadata(payload); + log.info("Successfully updated document metadata"); + } catch (FeignException ex) { + log.error("Failed to update document metadata", ex); + throw ex; + } + } +} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 7635bbdb..85dc9378 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -6,7 +6,7 @@ material-client: spring: application: - name: service-hmcts-springboot-demo-postgres + name: service-cp-crime-hearing-case-event-subscription jpa: open-in-view: false datasource: @@ -18,6 +18,9 @@ spring: locations: classpath:db/migration baseline-on-migrate: true +document-service: + url: ${DOCUMENT_SERVICE_URL:http://localhost:8082} + management: endpoints: web: diff --git a/src/test/java/uk/gov/hmcts/cp/subscription/client/DocumentServiceClientIntegrationTest.java b/src/test/java/uk/gov/hmcts/cp/subscription/client/DocumentServiceClientIntegrationTest.java new file mode 100644 index 00000000..1fe8eb3c --- /dev/null +++ b/src/test/java/uk/gov/hmcts/cp/subscription/client/DocumentServiceClientIntegrationTest.java @@ -0,0 +1,94 @@ +package uk.gov.hmcts.cp.subscription.client; + +import com.github.tomakehurst.wiremock.junit5.WireMockExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.cloud.openfeign.FeignAutoConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import uk.gov.hmcts.cp.openapi.model.PcrEventPayload; +import uk.gov.hmcts.cp.subscription.integration.IntegrationTestBase; + +import java.util.UUID; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.containing; +import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) +class DocumentServiceClientIntegrationTest extends IntegrationTestBase { + + @RegisterExtension + static WireMockExtension wireMockServer = WireMockExtension.newInstance() + .options(wireMockConfig().dynamicPort()) + .build(); + + @Autowired + private DocumentServiceClient documentServiceClient; + + @DynamicPropertySource + static void configureProperties(DynamicPropertyRegistry registry) { + registry.add("document-service.url", wireMockServer::baseUrl); + registry.add("spring.cloud.discovery.enabled", () -> "false"); + registry.add("spring.cloud.service-registry.auto-registration.enabled", () -> "false"); + } + + @Test + void should_send_request_when_document_service_returns_no_content() { + wireMockServer.stubFor(post(urlEqualTo("/client-webhook-url")) + .willReturn(aResponse() + .withStatus(204))); + + PcrEventPayload payload = new PcrEventPayload(); + payload.setEventId(UUID.randomUUID()); + + documentServiceClient.updateDocumentMetadata(payload); + + wireMockServer.verify(postRequestedFor(urlEqualTo("/client-webhook-url")) + .withHeader("Content-Type", containing("application/json"))); + } + + @Test + void should_handle_successful_response() { + wireMockServer.stubFor(post(urlEqualTo("/client-webhook-url")) + .willReturn(aResponse() + .withStatus(200))); + + PcrEventPayload payload = new PcrEventPayload(); + payload.setEventId(UUID.randomUUID()); + + documentServiceClient.updateDocumentMetadata(payload); + + wireMockServer.verify(1, postRequestedFor( + urlEqualTo("/client-webhook-url"))); + } + + @Test + void should_send_correct_payload_to_document_service() { + UUID eventId = UUID.randomUUID(); + + wireMockServer.stubFor(post(urlEqualTo("/client-webhook-url")) + .willReturn(aResponse() + .withStatus(204))); + + PcrEventPayload payload = new PcrEventPayload(); + payload.setEventId(eventId); + + documentServiceClient.updateDocumentMetadata(payload); + + wireMockServer.verify(postRequestedFor(urlEqualTo("/client-webhook-url")) + .withHeader("Content-Type", containing("application/json")) + .withRequestBody(matchingJsonPath("$.eventId", equalTo(eventId.toString())))); + } +} \ No newline at end of file diff --git a/src/test/java/uk/gov/hmcts/cp/subscription/services/WebhookServiceIntegrationTest.java b/src/test/java/uk/gov/hmcts/cp/subscription/services/WebhookServiceIntegrationTest.java new file mode 100644 index 00000000..c550cd37 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/cp/subscription/services/WebhookServiceIntegrationTest.java @@ -0,0 +1,54 @@ +package uk.gov.hmcts.cp.subscription.services; + +import com.github.tomakehurst.wiremock.junit5.WireMockExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import uk.gov.hmcts.cp.openapi.model.PcrEventPayload; +import uk.gov.hmcts.cp.subscription.integration.IntegrationTestBase; + +import java.util.UUID; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.containing; +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.urlPathMatching; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) +class WebhookServiceIntegrationTest extends IntegrationTestBase { + + @RegisterExtension + static WireMockExtension wireMockServer = WireMockExtension.newInstance() + .options(wireMockConfig().dynamicPort()) + .build(); + + @DynamicPropertySource + static void configureProperties(DynamicPropertyRegistry registry) { + registry.add("document-service.url", wireMockServer::baseUrl); + registry.add("spring.cloud.discovery.enabled", () -> "false"); + registry.add("spring.cloud.service-registry.auto-registration.enabled", () -> "false"); + } + + @Autowired + private WebhookService webhookService; + + @Test + void should_call_document_service_to_update_metadata() { + wireMockServer.stubFor(post(urlPathMatching("/client-webhook-url")) + .willReturn(aResponse().withStatus(200))); + + PcrEventPayload payload = PcrEventPayload.builder() + .eventId(UUID.randomUUID()) + .build(); + + webhookService.processPcrEvent(payload); + + wireMockServer.verify(postRequestedFor(urlPathMatching("/client-webhook-url")) + .withHeader("Content-Type", containing("application/json"))); + } +}