diff --git a/.github/workflows/access.yml b/.github/workflows/access.yml index 583a682d1e..0b7321b962 100644 --- a/.github/workflows/access.yml +++ b/.github/workflows/access.yml @@ -54,6 +54,7 @@ on: - '["unpaid-work-and-delius"]' - '["workforce-allocations-to-delius"]' - '["subject-access-requests-and-delius"]' + - '["common-platform-and-delius"]' # ^ add new projects here # GitHub Actions doesn't support dynamic choices, we must add each project here to enable manual deployments # See https://github.com/community/community/discussions/11795 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 21c94d95a3..694b9d062e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,6 +77,7 @@ jobs: - unpaid-work-and-delius - workforce-allocations-to-delius - subject-access-requests-and-delius + - common-platform-and-delius # ^ add new projects here # GitHub Actions doesn't support dynamic choices, we must add each project here to enable manual deployments # See https://github.com/community/community/discussions/11795 diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9ca512a3bf..9778435c7e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -69,6 +69,7 @@ on: - '["unpaid-work-and-delius"]' - '["workforce-allocations-to-delius"]' - '["subject-access-requests-and-delius"]' + - '["common-platform-and-delius"]' # ^ add new projects here # GitHub Actions doesn't support dynamic choices, we must add each project here to enable manual deployments # See https://github.com/community/community/discussions/11795 diff --git a/.github/workflows/messaging.yml b/.github/workflows/messaging.yml index f0c7ad2e2d..33e1cd88a5 100644 --- a/.github/workflows/messaging.yml +++ b/.github/workflows/messaging.yml @@ -37,6 +37,7 @@ on: - prison-identifier-and-delius-queue - assessment-summary-and-delius-queue - cas2-and-delius-queue + - common-platform-and-delius-queue # ^ add new queues here jobs: diff --git a/.github/workflows/service-catalogue.yml b/.github/workflows/service-catalogue.yml index c4c35e1efb..f73d78384c 100644 --- a/.github/workflows/service-catalogue.yml +++ b/.github/workflows/service-catalogue.yml @@ -54,6 +54,7 @@ on: - '["unpaid-work-and-delius"]' - '["workforce-allocations-to-delius"]' - '["subject-access-requests-and-delius"]' + - '["common-platform-and-delius"]' # ^ add new projects here # GitHub Actions doesn't support dynamic choices, we must add each project here to enable manual deployments # See https://github.com/community/community/discussions/11795 diff --git a/.idea/runConfigurations/common_platform_and_delius.xml b/.idea/runConfigurations/common_platform_and_delius.xml new file mode 100644 index 0000000000..6e921d526d --- /dev/null +++ b/.idea/runConfigurations/common_platform_and_delius.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/doc/tech-docs/source/services.html.md.erb b/doc/tech-docs/source/services.html.md.erb index e39e628af4..7519fd5a06 100644 --- a/doc/tech-docs/source/services.html.md.erb +++ b/doc/tech-docs/source/services.html.md.erb @@ -81,4 +81,5 @@ weight: 20 * [Probation Search And Delius](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/probation-search-and-delius) * [Core Person Record And Delius](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/core-person-record-and-delius) * [Subject Access Requests And Delius](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/subject-access-requests-and-delius) +* [Common Platform And Delius](https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/common-platform-and-delius)
  • ^ add new projects here
  • diff --git a/projects/common-platform-and-delius/.trivyignore b/projects/common-platform-and-delius/.trivyignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/projects/common-platform-and-delius/README.md b/projects/common-platform-and-delius/README.md new file mode 100644 index 0000000000..627bdd8e4a --- /dev/null +++ b/projects/common-platform-and-delius/README.md @@ -0,0 +1,3 @@ +# common-platform-and-delius + +// TODO Describe the service \ No newline at end of file diff --git a/projects/common-platform-and-delius/applicationinsights.json b/projects/common-platform-and-delius/applicationinsights.json new file mode 100644 index 0000000000..d8f00ec641 --- /dev/null +++ b/projects/common-platform-and-delius/applicationinsights.json @@ -0,0 +1,62 @@ +{ + "role": { + "name": "common-platform-and-delius" + }, + "customDimensions": { + "service.version": "${VERSION}", + "service.team": "probation-integration" + }, + "instrumentation": { + "logging": { + "level": "DEBUG" + }, + "springScheduling": { + "enabled": false + } + }, + "selfDiagnostics": { + "destination": "console" + }, + "sampling": { + "percentage": 100 + }, + "preview": { + "sampling": { + "overrides": [ + { + "telemetryType": "request", + "attributes": [ + { + "key": "http.url", + "value": "https?://[^/]+/health/?.*", + "matchType": "regexp" + } + ], + "percentage": 0 + }, + { + "telemetryType": "request", + "attributes": [ + { + "key": "http.url", + "value": "https?://[^/]+/info/?.*", + "matchType": "regexp" + } + ], + "percentage": 0 + }, + { + "telemetryType": "dependency", + "attributes": [ + { + "key": "db.operation", + "value": "SELECT", + "matchType": "strict" + } + ], + "percentage": 10 + } + ] + } + } +} \ No newline at end of file diff --git a/projects/common-platform-and-delius/build.gradle.kts b/projects/common-platform-and-delius/build.gradle.kts new file mode 100644 index 0000000000..2f628668cc --- /dev/null +++ b/projects/common-platform-and-delius/build.gradle.kts @@ -0,0 +1,36 @@ +import uk.gov.justice.digital.hmpps.extensions.ClassPathExtension + +apply(plugin = "com.google.cloud.tools.jib") + +dependencies { + implementation(project(":libs:audit")) + implementation(project(":libs:commons")) + implementation(project(":libs:messaging")) + implementation(project(":libs:oauth-client")) + + implementation("org.springframework.boot:spring-boot-starter-actuator") + implementation("org.springframework.boot:spring-boot-starter-data-jpa") + implementation("org.springframework.boot:spring-boot-starter-security") + implementation("org.springframework.boot:spring-boot-starter-validation") + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin") + + dev(project(":libs:dev-tools")) + dev("com.h2database:h2") + dev("org.testcontainers:oracle-xe") + + runtimeOnly("com.oracle.database.jdbc:ojdbc11") + + testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation(libs.bundles.mockito) +} + +configure { + jacocoExclusions = listOf( + "**/config/**", + "**/entity/**", + "**/AppKt.class" + ) +} diff --git a/projects/common-platform-and-delius/deploy/Chart.yaml b/projects/common-platform-and-delius/deploy/Chart.yaml new file mode 100644 index 0000000000..b467f908b5 --- /dev/null +++ b/projects/common-platform-and-delius/deploy/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +appVersion: '1.0' +description: A Helm chart for Kubernetes +name: common-platform-and-delius +version: 1.0.0 + +dependencies: + - name: generic-service + version: "3.2" + repository: https://ministryofjustice.github.io/hmpps-helm-charts + - name: generic-prometheus-alerts + version: "1.4" + repository: https://ministryofjustice.github.io/hmpps-helm-charts \ No newline at end of file diff --git a/projects/common-platform-and-delius/deploy/database/access.yml b/projects/common-platform-and-delius/deploy/database/access.yml new file mode 100644 index 0000000000..983628d322 --- /dev/null +++ b/projects/common-platform-and-delius/deploy/database/access.yml @@ -0,0 +1,9 @@ +database: + access: + username_key: /common-platform-and-delius/db-username + password_key: /common-platform-and-delius/db-password + + audit: + username: CommonPlatformAndDelius + forename: Probation Integration # TODO change this to something meaningful for your service + surname: Service diff --git a/projects/common-platform-and-delius/deploy/values-dev.yml b/projects/common-platform-and-delius/deploy/values-dev.yml new file mode 100644 index 0000000000..9c532df627 --- /dev/null +++ b/projects/common-platform-and-delius/deploy/values-dev.yml @@ -0,0 +1,20 @@ +enabled: false # TODO set this to true when you're ready to deploy your service + +generic-service: + ingress: + host: common-platform-and-delius-dev.hmpps.service.justice.gov.uk + + scheduledDowntime: + enabled: true + + env: + SENTRY_ENVIRONMENT: dev + SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_HMPPS-AUTH_TOKEN-URI: https://sign-in-dev.hmpps.service.justice.gov.uk/auth/oauth/token + + SPRING_DATASOURCE_HIKARI_MAXIMUMPOOLSIZE: 5 + SPRING_DATASOURCE_HIKARI_MINIMUMIDLE: 0 + + LOGGING_LEVEL_UK_GOV_DIGITAL_JUSTICE_HMPPS: DEBUG + +generic-prometheus-alerts: + businessHoursOnly: true diff --git a/projects/common-platform-and-delius/deploy/values-preprod.yml b/projects/common-platform-and-delius/deploy/values-preprod.yml new file mode 100644 index 0000000000..5a96ee30fb --- /dev/null +++ b/projects/common-platform-and-delius/deploy/values-preprod.yml @@ -0,0 +1,15 @@ +enabled: false # TODO set this to true when you're ready to deploy your service + +generic-service: + ingress: + host: common-platform-and-delius-preprod.hmpps.service.justice.gov.uk + + scheduledDowntime: + enabled: true + + env: + SENTRY_ENVIRONMENT: preprod + SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_HMPPS-AUTH_TOKEN-URI: https://sign-in-preprod.hmpps.service.justice.gov.uk/auth/oauth/token + +generic-prometheus-alerts: + businessHoursOnly: true \ No newline at end of file diff --git a/projects/common-platform-and-delius/deploy/values-prod.yml b/projects/common-platform-and-delius/deploy/values-prod.yml new file mode 100644 index 0000000000..d258de2ad5 --- /dev/null +++ b/projects/common-platform-and-delius/deploy/values-prod.yml @@ -0,0 +1,9 @@ +enabled: false # TODO set this to true when you're ready to deploy your service + +generic-service: + ingress: + host: common-platform-and-delius.hmpps.service.justice.gov.uk + + env: + SENTRY_ENVIRONMENT: prod + SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_HMPPS-AUTH_TOKEN-URI: https://sign-in.hmpps.service.justice.gov.uk/auth/oauth/token diff --git a/projects/common-platform-and-delius/deploy/values.yaml b/projects/common-platform-and-delius/deploy/values.yaml new file mode 100644 index 0000000000..456c964b0f --- /dev/null +++ b/projects/common-platform-and-delius/deploy/values.yaml @@ -0,0 +1,29 @@ +# Common values +generic-service: + productId: HMPPS518 + nameOverride: common-platform-and-delius + serviceAccountName: common-platform-and-delius + + image: + repository: ghcr.io/ministryofjustice/hmpps-probation-integration-services/common-platform-and-delius + + ingress: + tlsSecretName: common-platform-and-delius-cert + + namespace_secrets: + common: + SPRING_DATASOURCE_URL: DB_URL + common-platform-and-delius-client-credentials: + OAUTH2_CLIENT-ID: CLIENT_ID + OAUTH2_CLIENT-SECRET: CLIENT_SECRET + common-platform-and-delius-database: + SPRING_DATASOURCE_USERNAME: DB_USERNAME + SPRING_DATASOURCE_PASSWORD: DB_PASSWORD + common-platform-and-delius-sentry: + SENTRY_DSN: SENTRY_DSN + common-platform-and-delius-queue: + MESSAGING_CONSUMER_QUEUE: QUEUE_NAME + +generic-prometheus-alerts: + targetApplication: common-platform-and-delius + diff --git a/projects/common-platform-and-delius/settings.gradle.kts b/projects/common-platform-and-delius/settings.gradle.kts new file mode 100644 index 0000000000..1710db332e --- /dev/null +++ b/projects/common-platform-and-delius/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "common-platform-and-delius" diff --git a/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt b/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt new file mode 100644 index 0000000000..f6ea94c9a7 --- /dev/null +++ b/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/DataLoader.kt @@ -0,0 +1,25 @@ +package uk.gov.justice.digital.hmpps.data + +import jakarta.annotation.PostConstruct +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.context.event.ApplicationReadyEvent +import org.springframework.context.ApplicationListener +import org.springframework.stereotype.Component +import uk.gov.justice.digital.hmpps.data.generator.UserGenerator +import uk.gov.justice.digital.hmpps.user.AuditUserRepository + +@Component +@ConditionalOnProperty("seed.database") +class DataLoader( + private val auditUserRepository: AuditUserRepository +) : ApplicationListener { + + @PostConstruct + fun saveAuditUser() { + auditUserRepository.save(UserGenerator.AUDIT_USER) + } + + override fun onApplicationEvent(are: ApplicationReadyEvent) { + // Perform dev/test database setup here, using JPA repositories and generator classes... + } +} diff --git a/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/MessageGenerator.kt b/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/MessageGenerator.kt new file mode 100644 index 0000000000..5ed8de87fc --- /dev/null +++ b/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/MessageGenerator.kt @@ -0,0 +1,8 @@ +package uk.gov.justice.digital.hmpps.data.generator + +import uk.gov.justice.digital.hmpps.message.HmppsDomainEvent +import uk.gov.justice.digital.hmpps.resourceloader.ResourceLoader + +object MessageGenerator { + val EXAMPLE = ResourceLoader.message("example-message") +} diff --git a/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/UserGenerator.kt b/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/UserGenerator.kt new file mode 100644 index 0000000000..30cbcb1683 --- /dev/null +++ b/projects/common-platform-and-delius/src/dev/kotlin/uk/gov/justice/digital/hmpps/data/generator/UserGenerator.kt @@ -0,0 +1,7 @@ +package uk.gov.justice.digital.hmpps.data.generator + +import uk.gov.justice.digital.hmpps.user.AuditUser + +object UserGenerator { + val AUDIT_USER = AuditUser(IdGenerator.getAndIncrement(), "CommonPlatformAndDelius") +} diff --git a/projects/common-platform-and-delius/src/dev/resources/messages/example-message.json b/projects/common-platform-and-delius/src/dev/resources/messages/example-message.json new file mode 100644 index 0000000000..3ec3f10524 --- /dev/null +++ b/projects/common-platform-and-delius/src/dev/resources/messages/example-message.json @@ -0,0 +1,17 @@ +{ + "Type": "Notification", + "MessageId": "aa2c2828-167f-529b-8e19-73735a2fb85c", + "TopicArn": "arn:aws:sns:eu-west-2:000000000000:example", + "Message": "{\"eventType\":\"example\",\"version\":1,\"description\":\"Example event\",\"detailUrl\":\"http://localhost:{wiremock.port}/example/123\",\"occurredAt\":\"2022-07-27T15:22:08.452612281+01:00\",\"additionalInformation\":{\"exampleId\":\"123\"},\"personReference\":{\"identifiers\":[{\"type\":\"CRN\",\"value\":\"A000001\"}]}}", + "Timestamp": "2022-07-27T14:22:08.509Z", + "SignatureVersion": "1", + "Signature": "EXAMPLE", + "SigningCertURL": "https://sns.eu-west-2.amazonaws.com/EXAMPLE.pem", + "UnsubscribeURL": "https://sns.eu-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=EXAMPLE", + "MessageAttributes": { + "eventType": { + "Type": "String", + "Value": "example" + } + } +} \ No newline at end of file diff --git a/projects/common-platform-and-delius/src/dev/resources/simulations/mappings/hmpps-auth.json b/projects/common-platform-and-delius/src/dev/resources/simulations/mappings/hmpps-auth.json new file mode 100644 index 0000000000..e64fc33914 --- /dev/null +++ b/projects/common-platform-and-delius/src/dev/resources/simulations/mappings/hmpps-auth.json @@ -0,0 +1,21 @@ +{ + "request": { + "method": "POST", + "urlPath": "/auth/oauth/token" + }, + "response": { + "headers": { + "Content-Type": "application/json" + }, + "status": 200, + "jsonBody": { + "access_token": "token", + "token_type": "bearer", + "expires_in": 9999999999, + "scope": "read write", + "sub": "probation-integration-dev", + "auth_source": "none", + "iss": "https://sign-in-dev.hmpps.service.justice.gov.uk/auth/issuer" + } + } +} \ No newline at end of file diff --git a/projects/common-platform-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt b/projects/common-platform-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt new file mode 100644 index 0000000000..2c6461b551 --- /dev/null +++ b/projects/common-platform-and-delius/src/integrationTest/kotlin/uk/gov/justice/digital/hmpps/IntegrationTest.kt @@ -0,0 +1,43 @@ +package uk.gov.justice.digital.hmpps + +import org.junit.jupiter.api.Test +import org.mockito.Mockito.atLeastOnce +import org.mockito.kotlin.verify +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Value +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.mock.mockito.MockBean +import uk.gov.justice.digital.hmpps.data.generator.MessageGenerator +import uk.gov.justice.digital.hmpps.message.Notification +import uk.gov.justice.digital.hmpps.messaging.HmppsChannelManager +import uk.gov.justice.digital.hmpps.telemetry.TelemetryService +import uk.gov.justice.digital.hmpps.telemetry.TelemetryMessagingExtensions.notificationReceived +import java.util.concurrent.TimeoutException + +@SpringBootTest +internal class IntegrationTest { + @Value("\${messaging.consumer.queue}") + lateinit var queueName: String + + @Autowired + lateinit var channelManager: HmppsChannelManager + + @MockBean + lateinit var telemetryService: TelemetryService + + @Test + fun `message is logged to telemetry`() { + // Given a message + val notification = Notification(message = MessageGenerator.EXAMPLE) + + // When it is received + try { + channelManager.getChannel(queueName).publishAndWait(notification) + } catch (_: TimeoutException) { + // Note: Remove this try/catch when the MessageListener logic has been implemented + } + + // Then it is logged to telemetry + verify(telemetryService, atLeastOnce()).notificationReceived(notification) + } +} diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/App.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/App.kt new file mode 100644 index 0000000000..fe1c2e7f71 --- /dev/null +++ b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/App.kt @@ -0,0 +1,13 @@ +package uk.gov.justice.digital.hmpps + +import org.openfolder.kotlinasyncapi.springweb.EnableAsyncApi +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication + +@EnableAsyncApi +@SpringBootApplication +class App + +fun main(args: Array) { + runApplication(*args) +} diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/config/AsyncApiConfig.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/config/AsyncApiConfig.kt new file mode 100644 index 0000000000..33649eca8d --- /dev/null +++ b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/config/AsyncApiConfig.kt @@ -0,0 +1,30 @@ +package uk.gov.justice.digital.hmpps.config + +import org.openfolder.kotlinasyncapi.springweb.service.AsyncApiExtension +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +class AsyncApiConfig { + @Bean + fun asyncApiExtension() = AsyncApiExtension.builder(order = 1) { + info.title("common-platform-and-delius") + servers { + server("dev") { + url("https://sqs.eu-west-2.amazonaws.com/754256621582/probation-integration-dev-common-platform-and-delius-queue") + protocol("sqs") + } + server("preprod") { + url("https://sqs.eu-west-2.amazonaws.com/754256621582/probation-integration-preprod-common-platform-and-delius-queue") + protocol("sqs") + } + server("prod") { + url("https://sqs.eu-west-2.amazonaws.com/754256621582/probation-integration-prod-common-platform-and-delius-queue") + protocol("sqs") + } + } + externalDocs { + url("https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/common-platform-and-delius/") + } + } +} diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/config/RestClientConfig.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/config/RestClientConfig.kt new file mode 100644 index 0000000000..d81e4461ed --- /dev/null +++ b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/config/RestClientConfig.kt @@ -0,0 +1,21 @@ +package uk.gov.justice.digital.hmpps.config + +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.web.client.RestClient +import uk.gov.justice.digital.hmpps.config.security.createClient +import uk.gov.justice.digital.hmpps.integrations.example.ExampleClient + +@Configuration +class RestClientConfig(private val oauth2Client: RestClient) { + + @Bean + fun exampleClient(@Value("\${integrations.example.url}") apiBaseUrl: String): ExampleClient { + return createClient( + oauth2Client.mutate() + .baseUrl(apiBaseUrl) + .build() + ) + } +} diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/example/ExampleClient.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/example/ExampleClient.kt new file mode 100644 index 0000000000..c164d63afd --- /dev/null +++ b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/integrations/example/ExampleClient.kt @@ -0,0 +1,9 @@ +package uk.gov.justice.digital.hmpps.integrations.example + +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.service.annotation.GetExchange + +interface ExampleClient { + @GetExchange(value = "/example/{inputId}") + fun getExampleAPICall(@PathVariable("inputId") inputId: String): String +} diff --git a/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt new file mode 100644 index 0000000000..1411b9fb01 --- /dev/null +++ b/projects/common-platform-and-delius/src/main/kotlin/uk/gov/justice/digital/hmpps/messaging/Handler.kt @@ -0,0 +1,29 @@ +package uk.gov.justice.digital.hmpps.messaging + +import org.openfolder.kotlinasyncapi.annotation.channel.Channel +import org.openfolder.kotlinasyncapi.annotation.channel.Publish +import org.springframework.stereotype.Component +import uk.gov.justice.digital.hmpps.converter.NotificationConverter +import uk.gov.justice.digital.hmpps.message.HmppsDomainEvent +import uk.gov.justice.digital.hmpps.message.Notification +import uk.gov.justice.digital.hmpps.telemetry.TelemetryService +import uk.gov.justice.digital.hmpps.telemetry.TelemetryMessagingExtensions.notificationReceived + +@Component +@Channel("common-platform-and-delius-queue") +class Handler( + override val converter: NotificationConverter, + private val telemetryService: TelemetryService +) : NotificationHandler { + @Publish( + messages = [ + // TODO list the event types here that this service will subscribe to. For example, + // Message(name = "approved-premises/application-assessed"), + // Message(title = "probation-case.prison-identifier.added"), + ] + ) + override fun handle(notification: Notification) { + telemetryService.notificationReceived(notification) + TODO("Not yet implemented") + } +} diff --git a/projects/common-platform-and-delius/src/main/resources/application.yml b/projects/common-platform-and-delius/src/main/resources/application.yml new file mode 100644 index 0000000000..7a2d427f19 --- /dev/null +++ b/projects/common-platform-and-delius/src/main/resources/application.yml @@ -0,0 +1,96 @@ +# Default config +server.shutdown: graceful +spring: + jackson: + default-property-inclusion: non_null + jpa: + hibernate.ddl-auto: validate + database-platform: org.hibernate.dialect.OracleDialect + properties: + hibernate: + timezone.default_storage: NORMALIZE + query.mutation_strategy: org.hibernate.query.sqm.mutation.internal.inline.InlineMutationStrategy + query.mutation_strategy.persistent: + create_tables: false + drop_tables: false + query.mutation_strategy.global_temporary: + create_tables: false + drop_tables: false + security.oauth2.client: + registration: + default: + provider: hmpps-auth + authorization-grant-type: client_credentials + client-id: ${oauth2.client-id} + client-secret: ${oauth2.client-secret} + provider: + hmpps-auth: + token-uri: http://localhost:${wiremock.port}/auth/oauth/token + threads.virtual.enabled: true + +delius.db.username: CommonPlatformAndDelius # Should match value in [deploy/database/access.yml]. + +management: + endpoints.web: + base-path: / + exposure.include: [ "health", "info" ] + endpoint.health.show-details: always + +info.productId: HMPPS518 # https://developer-portal.hmpps.service.justice.gov.uk/products/185 + + +--- +# Shared dev/test config +spring.config.activate.on-profile: [ "dev", "integration-test" ] +server.shutdown: immediate + +spring: + datasource.url: jdbc:h2:file:./dev;MODE=Oracle;DEFAULT_NULL_ORDERING=HIGH;AUTO_SERVER=true;AUTO_SERVER_PORT=9092 + jpa.hibernate.ddl-auto: create-drop + +seed.database: true +wiremock.enabled: true +context.initializer.classes: uk.gov.justice.digital.hmpps.wiremock.WireMockInitialiser + +messaging.consumer.queue: message-queue + +integrations: + example: + url: http://localhost:${wiremock.port}/example + +oauth2: + client-id: common-platform-and-delius + client-secret: common-platform-and-delius + +logging.level: + uk.gov.justice.digital.hmpps: DEBUG + org.hibernate.tool.schema: ERROR + org.apache.activemq: WARN + +--- +spring.config.activate.on-profile: integration-test +spring.datasource.url: jdbc:h2:mem:./test;MODE=Oracle;DEFAULT_NULL_ORDERING=HIGH + +--- +spring.config.activate.on-profile: oracle +spring.datasource.url: 'jdbc:tc:oracle:slim-faststart:///XEPDB1' + +--- +spring.config.activate.on-profile: delius-db +spring: + datasource: + url: 'jdbc:oracle:thin:@//localhost:1521/XEPDB1' + username: delius_pool + password: NDelius1 + jpa.hibernate.ddl-auto: validate +seed.database: false +delius.db.username: NationalUser + +--- +spring.config.activate.on-profile: localstack +spring.cloud.aws: + sqs.endpoint: http://localhost:4566 + sns.endpoint: http://localhost:4566 + credentials: + access-key: localstack + secret-key: localstack diff --git a/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/messaging/HandlerTest.kt b/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/messaging/HandlerTest.kt new file mode 100644 index 0000000000..5345a539df --- /dev/null +++ b/projects/common-platform-and-delius/src/test/kotlin/uk/gov/justice/digital/hmpps/messaging/HandlerTest.kt @@ -0,0 +1,42 @@ +package uk.gov.justice.digital.hmpps.messaging + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.InjectMocks +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.verify +import uk.gov.justice.digital.hmpps.converter.NotificationConverter +import uk.gov.justice.digital.hmpps.data.generator.MessageGenerator +import uk.gov.justice.digital.hmpps.message.HmppsDomainEvent +import uk.gov.justice.digital.hmpps.message.Notification +import uk.gov.justice.digital.hmpps.telemetry.TelemetryService +import uk.gov.justice.digital.hmpps.telemetry.TelemetryMessagingExtensions.notificationReceived + +@ExtendWith(MockitoExtension::class) +internal class HandlerTest { + @Mock + lateinit var telemetryService: TelemetryService + + @Mock + lateinit var converter: NotificationConverter + + @InjectMocks + lateinit var handler: Handler + + @Test + fun `message is logged to telemetry`() { + // Given a message + val notification = Notification(message = MessageGenerator.EXAMPLE) + + // When it is received + try { + handler.handle(notification) + } catch (_: NotImplementedError) { + // Note: Remove this try/catch when the Handler logic has been implemented + } + + // Then it is logged to telemetry + verify(telemetryService).notificationReceived(notification) + } +} diff --git a/projects/common-platform-and-delius/tech-docs/.gitignore b/projects/common-platform-and-delius/tech-docs/.gitignore new file mode 100644 index 0000000000..80d5de85a7 --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/.gitignore @@ -0,0 +1,20 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile ~/.gitignore_global + +# Ignore bundler config +/.bundle + +# Ignore the build directory +/build + +# Ignore cache +/.sass-cache +/.cache + +# Ignore .DS_store file +.DS_Store + +Staticfile.auth diff --git a/projects/common-platform-and-delius/tech-docs/.template_version b/projects/common-platform-and-delius/tech-docs/.template_version new file mode 100644 index 0000000000..57ff8862e1 --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/.template_version @@ -0,0 +1,3 @@ +--- +:remote: https://github.com/alphagov/tech-docs-template.git +:revision: b37e894 \ No newline at end of file diff --git a/projects/common-platform-and-delius/tech-docs/Gemfile b/projects/common-platform-and-delius/tech-docs/Gemfile new file mode 100644 index 0000000000..afef363c09 --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/Gemfile @@ -0,0 +1,12 @@ +# If you do not have OpenSSL installed, change +# the following line to use 'http://' +source 'https://rubygems.org' + +# For faster file watcher updates on Windows: +gem 'wdm', '~> 0.1.0', platforms: [:mswin, :mingw, :x64_mingw] + +# Windows does not come with time zone data +gem 'tzinfo-data', platforms: [:mswin, :mingw, :x64_mingw, :jruby] + +# Include the tech docs gem +gem 'govuk_tech_docs' diff --git a/projects/common-platform-and-delius/tech-docs/Gemfile.lock b/projects/common-platform-and-delius/tech-docs/Gemfile.lock new file mode 100644 index 0000000000..b387d6c3c4 --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/Gemfile.lock @@ -0,0 +1,179 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (7.0.7.2) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + addressable (2.8.4) + public_suffix (>= 2.0.2, < 6.0) + autoprefixer-rails (10.4.13.0) + execjs (~> 2) + backports (3.24.1) + chronic (0.10.2) + chunky_png (1.4.0) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.12.2) + commonmarker (0.23.10) + compass (1.0.3) + chunky_png (~> 1.2) + compass-core (~> 1.0.2) + compass-import-once (~> 1.0.5) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + sass (>= 3.3.13, < 3.5) + compass-core (1.0.3) + multi_json (~> 1.0) + sass (>= 3.3.0, < 3.5) + compass-import-once (1.0.5) + sass (>= 3.2, < 3.5) + concurrent-ruby (1.2.2) + contracts (0.17) + dotenv (2.8.1) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + erubis (2.7.0) + eventmachine (1.2.7) + execjs (2.8.1) + fast_blank (1.0.1) + fastimage (2.2.6) + ffi (1.15.5) + govuk_tech_docs (3.3.1) + autoprefixer-rails (~> 10.2) + chronic (~> 0.10.2) + middleman (~> 4.0) + middleman-autoprefixer (~> 2.10.0) + middleman-compass (>= 4.0.0) + middleman-livereload + middleman-search-gds + middleman-sprockets (~> 4.0.0) + middleman-syntax (~> 3.2.0) + nokogiri + openapi3_parser (~> 0.9.0) + redcarpet (~> 3.5.1) + haml (5.2.2) + temple (>= 0.8.0) + tilt + hamster (3.0.0) + concurrent-ruby (~> 1.0) + hashie (3.6.0) + http_parser.rb (0.8.0) + i18n (1.6.0) + concurrent-ruby (~> 1.0) + kramdown (2.4.0) + rexml + listen (3.8.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + memoist (0.16.2) + middleman (4.4.3) + coffee-script (~> 2.2) + haml (>= 4.0.5, < 6.0) + kramdown (>= 2.3.0) + middleman-cli (= 4.4.3) + middleman-core (= 4.4.3) + middleman-autoprefixer (2.10.0) + autoprefixer-rails (>= 9.1.4) + middleman-core (>= 3.3.3) + middleman-cli (4.4.3) + thor (>= 0.17.0, < 2.0) + middleman-compass (4.0.1) + compass (>= 1.0.0, < 2.0.0) + middleman-core (>= 4.0.0) + middleman-core (4.4.3) + activesupport (>= 6.1, < 7.1) + addressable (~> 2.4) + backports (~> 3.6) + bundler (~> 2.0) + contracts (~> 0.13) + dotenv + erubis + execjs (~> 2.0) + fast_blank + fastimage (~> 2.0) + hamster (~> 3.0) + hashie (~> 3.4) + i18n (~> 1.6.0) + listen (~> 3.0) + memoist (~> 0.14) + padrino-helpers (~> 0.15.0) + parallel + rack (>= 1.4.5, < 3) + sassc (~> 2.0) + servolux + tilt (~> 2.0.9) + toml + uglifier (~> 3.0) + webrick + middleman-livereload (3.4.7) + em-websocket (~> 0.5.1) + middleman-core (>= 3.3) + rack-livereload (~> 0.3.15) + middleman-search-gds (0.11.2) + execjs (~> 2.6) + middleman-core (>= 3.2) + nokogiri (~> 1.6) + middleman-sprockets (4.0.0) + middleman-core (~> 4.0) + sprockets (>= 3.0) + middleman-syntax (3.2.0) + middleman-core (>= 3.2) + rouge (~> 3.2) + minitest (5.18.0) + multi_json (1.15.0) + nokogiri (1.16.5-x86_64-linux) + racc (~> 1.4) + openapi3_parser (0.9.2) + commonmarker (~> 0.17) + padrino-helpers (0.15.3) + i18n (>= 0.6.7, < 2) + padrino-support (= 0.15.3) + tilt (>= 1.4.1, < 3) + padrino-support (0.15.3) + parallel (1.22.1) + parslet (2.0.0) + public_suffix (5.0.1) + racc (1.7.3) + rack (2.2.8.1) + rack-livereload (0.3.17) + rack + rb-fsevent (0.11.2) + rb-inotify (0.10.1) + ffi (~> 1.0) + redcarpet (3.5.1) + rexml (3.3.6) + strscan + rouge (3.30.0) + sass (3.4.25) + sassc (2.4.0) + ffi (~> 1.9) + servolux (0.13.0) + sprockets (4.2.0) + concurrent-ruby (~> 1.0) + rack (>= 2.2.4, < 4) + strscan (3.1.0) + temple (0.10.0) + thor (1.2.1) + tilt (2.0.11) + toml (0.3.0) + parslet (>= 1.8.0, < 3.0.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + uglifier (3.2.0) + execjs (>= 0.3.0, < 3) + webrick (1.8.2) + +PLATFORMS + x86_64-linux + +DEPENDENCIES + govuk_tech_docs + tzinfo-data + wdm (~> 0.1.0) + +BUNDLED WITH + 2.3.26 diff --git a/projects/common-platform-and-delius/tech-docs/config.rb b/projects/common-platform-and-delius/tech-docs/config.rb new file mode 100644 index 0000000000..76c77d53dd --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/config.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +require "govuk_tech_docs" + +GovukTechDocs.configure(self) + +activate :relative_assets +set :relative_links, true diff --git a/projects/common-platform-and-delius/tech-docs/config/tech-docs.yml b/projects/common-platform-and-delius/tech-docs/config/tech-docs.yml new file mode 100644 index 0000000000..a62fb019b1 --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/config/tech-docs.yml @@ -0,0 +1,41 @@ +# Host to use for canonical URL generation (without trailing slash) +host: https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/common-platform-and-delius + +# Header-related options +service_name: HMPPS Common Platform And Delius +service_link: https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs/projects/common-platform-and-delius + +# Links to show on right-hand-side of header +header_links: + Home: https://ministryofjustice.github.io/hmpps-probation-integration-services/tech-docs + GitHub: https://github.com/ministryofjustice/hmpps-probation-integration-services#readme + Slack: https://mojdt.slack.com/archives/C02HQ4M2YQN # #probation-integration-tech channel + +# Enables search functionality. This indexes pages only and is not recommended for single-page sites. +enable_search: true + +# Tracking ID from Google Analytics (e.g. UA-XXXX-Y) +ga_tracking_id: + +# Enable multipage navigation in the sidebar +multipage_nav: true + +# Enable collapsible navigation in the sidebar +collapsible_nav: true + +# Table of contents depth – how many levels to include in the table of contents. +# If your ToC is too long, reduce this number and we'll only show higher-level +# headings. +max_toc_heading_level: 2 + +# Prevent robots from indexing (e.g. whilst in development) +prevent_indexing: false + +# Contribution +show_contribution_banner: true +github_repo: ministryofjustice/hmpps-probation-integration-services +github_branch: main + +# Slack +owner_slack_workspace: mojdt +default_owner_slack: '#probation-integration-tech' diff --git a/projects/common-platform-and-delius/tech-docs/source/asyncapi-reference.html.md.erb b/projects/common-platform-and-delius/tech-docs/source/asyncapi-reference.html.md.erb new file mode 100644 index 0000000000..e66f243dc1 --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/source/asyncapi-reference.html.md.erb @@ -0,0 +1,12 @@ +--- +title: AsyncAPI Reference +source_url: 'https://github.com/ministryofjustice/hmpps-probation-integration-services/blob/main/projects/common-platform-and-delius/tech-docs/source/asyncapi-reference.html.md.erb' +weight: 30 +--- + +# AsyncAPI Reference + + + + + diff --git a/projects/common-platform-and-delius/tech-docs/source/index.html.md.erb b/projects/common-platform-and-delius/tech-docs/source/index.html.md.erb new file mode 100644 index 0000000000..26fb37b60f --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/source/index.html.md.erb @@ -0,0 +1,7 @@ +--- +title: About +source_url: 'https://github.com/ministryofjustice/hmpps-probation-integration-services/blob/main/projects/common-platform-and-delius/tech-docs/source/index.html.md.erb' +weight: 10 +--- + +<%= URI.open('https://raw.githubusercontent.com/ministryofjustice/hmpps-probation-integration-services/main/projects/common-platform-and-delius/README.md').read.gsub(/tech-docs\/source\//, "./") %> \ No newline at end of file diff --git a/projects/common-platform-and-delius/tech-docs/source/javascripts/application.js b/projects/common-platform-and-delius/tech-docs/source/javascripts/application.js new file mode 100644 index 0000000000..8a5d80b842 --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/source/javascripts/application.js @@ -0,0 +1 @@ +//= require govuk_tech_docs diff --git a/projects/common-platform-and-delius/tech-docs/source/stylesheets/print.css.scss b/projects/common-platform-and-delius/tech-docs/source/stylesheets/print.css.scss new file mode 100644 index 0000000000..82b181c017 --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/source/stylesheets/print.css.scss @@ -0,0 +1,3 @@ +$is-print: true; + +@import "govuk_tech_docs"; diff --git a/projects/common-platform-and-delius/tech-docs/source/stylesheets/screen-old-ie.css.scss b/projects/common-platform-and-delius/tech-docs/source/stylesheets/screen-old-ie.css.scss new file mode 100644 index 0000000000..da90cca5b0 --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/source/stylesheets/screen-old-ie.css.scss @@ -0,0 +1,4 @@ +$is-ie: true; +$ie-version: 8; + +@import "govuk_tech_docs"; diff --git a/projects/common-platform-and-delius/tech-docs/source/stylesheets/screen.css.scss b/projects/common-platform-and-delius/tech-docs/source/stylesheets/screen.css.scss new file mode 100644 index 0000000000..f0456338fd --- /dev/null +++ b/projects/common-platform-and-delius/tech-docs/source/stylesheets/screen.css.scss @@ -0,0 +1 @@ +@import "govuk_tech_docs"; diff --git a/settings.gradle.kts b/settings.gradle.kts index 1391c4a62d..b2df2f9ceb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,7 @@ rootProject.name = "probation-integration-services" include( // ⌄ add new projects here + "common-platform-and-delius", "subject-access-requests-and-delius", "accredited-programmes-and-oasys", "approved-premises-and-delius",