diff --git a/README.md b/README.md index 75e9dee..c54d337 100644 --- a/README.md +++ b/README.md @@ -4,133 +4,10 @@ [![Docker Repository on ghcr](https://img.shields.io/badge/ghcr.io-repository-2496ED.svg?logo=docker)](https://ghcr.io/ministryofjustice/hmpps-person-integration-api) [![API docs](https://img.shields.io/badge/API_docs_-view-85EA2D.svg?logo=swagger)](https://hmpps-person-integration-api-dev.hmpps.service.justice.gov.uk/webjars/swagger-ui/index.html?configUrl=/v3/api-docs) -Template github repo used for new Kotlin based projects. +This is a Spring Boot service, written in Kotlin, which acts as an interface to the data in the Core Person Record and Person Protected Characteristics domains. -# Instructions +## Contents -If this is a HMPPS project then the project will be created as part of bootstrapping - -see [dps-project-bootstrap](https://github.com/ministryofjustice/dps-project-bootstrap). You are able to specify a -template application using the `github_template_repo` attribute to clone without the need to manually do this yourself -within GitHub. +1. [Building, Testing and Running](readme/build_test_run.md) +2. [Architecture Decision Records](architecture-decision-record/README.md) -This project is community managed by the mojdt `#kotlin-dev` slack channel. -Please raise any questions or queries there. Contributions welcome! - -Our security policy is located [here](https://github.com/ministryofjustice/hmpps-person-integration-api/security/policy). - -Documentation to create new service is located [here](https://tech-docs.hmpps.service.justice.gov.uk/applicationplatform/newservice-GHA/). - -## Creating a Cloud Platform namespace - -When deploying to a new namespace, you may wish to use the -[templates project namespace](https://github.com/ministryofjustice/cloud-platform-environments/tree/main/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-templates-dev) -as the basis for your new namespace. This namespace contains both the kotlin and typescript template projects, -which is the usual way that projects are setup. - -Copy this folder and update all the existing namespace references to correspond to the environment to which you're deploying. - -If you only need the kotlin configuration then remove all typescript references and remove the elasticache configuration. - -To ensure the correct github teams can approve releases, you will need to make changes to the configuration in `resources/service-account-github` where the appropriate team names will need to be added (based on [lines 98-100](https://github.com/ministryofjustice/cloud-platform-environments/blob/main/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-templates-dev/resources/serviceaccount-github.tf#L98) and the reference appended to the teams list below [line 112](https://github.com/ministryofjustice/cloud-platform-environments/blob/main/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-templates-dev/resources/serviceaccount-github.tf#L112)). Note: hmpps-sre is in this list to assist with deployment issues. - -Submit a PR to the Cloud Platform team in -#ask-cloud-platform. Further instructions from the Cloud Platform team can be found in -the [Cloud Platform User Guide](https://user-guide.cloud-platform.service.justice.gov.uk/#cloud-platform-user-guide) - -## Renaming from HMPPS Template Kotlin - github Actions - -Once the new repository is deployed. Navigate to the repository in github, and select the `Actions` tab. -Click the link to `Enable Actions on this repository`. - -Find the Action workflow named: `rename-project-create-pr` and click `Run workflow`. This workflow will -execute the `rename-project.bash` and create Pull Request for you to review. Review the PR and merge. - -Note: ideally this workflow would run automatically however due to a recent change github Actions are not -enabled by default on newly created repos. There is no way to enable Actions other then to click the button in the UI. -If this situation changes we will update this project so that the workflow is triggered during the bootstrap project. -Further reading: - -The script takes six arguments: - -### New project name - -This should start with `hmpps-` e.g. `hmpps-prison-visits` so that it can be easily distinguished in github from -other departments projects. Try to avoid using abbreviations so that others can understand easily what your project is. - -### Slack channel for release notifications - -By default, release notifications are only enabled for production. The circleci configuration can be amended to send -release notifications for deployments to other environments if required. Note that if the configuration is amended, -the slack channel should then be amended to your own team's channel as `dps-releases` is strictly for production release -notifications. If the slack channel is set to something other than `dps-releases`, production release notifications -will still automatically go to `dps-releases` as well. This is configured by `releases-slack-channel` in -`.circleci/config.yml`. - -### Slack channel for pipeline security notifications - -Ths channel should be specific to your team and is for daily / weekly security scanning job results. It is your team's -responsibility to keep up-to-date with security issues and update your application so that these jobs pass. You will -only be notified if the jobs fail. The scan results can always be found in circleci for your project. This is -configured by `alerts-slack-channel` in `.circleci/config.yml`. - -### Non production kubernetes alerts - -By default Prometheus alerts are created in the application namespaces to monitor your application e.g. if your -application is crash looping, there are a significant number of errors from the ingress. Since Prometheus runs in -cloud platform AlertManager needs to be setup first with your channel. Please see -[Create your own custom alerts](https://user-guide.cloud-platform.service.justice.gov.uk/documentation/monitoring-an-app/how-to-create-alarms.html) -in the Cloud Platform user guide. Once that is setup then the `custom severity label` can be used for -`alertSeverity` in the `helm_deploy/values-*.yaml` configuration. - -Normally it is worth setting up two separate labels and therefore two separate slack channels - one for your production -alerts and one for your non-production alerts. Using the same channel can mean that production alerts are sometimes -lost within non-production issues. - -### Production kubernetes alerts - -This is the severity label for production, determined by the `custom severity label`. See the above -#non-production-kubernetes-alerts for more information. This is configured in `helm_deploy/values-prod.yaml`. - -### Product ID - -This is so that we can link a component to a product and thus provide team and product information in the Developer -Portal. Refer to the developer portal at https://developer-portal.hmpps.service.justice.gov.uk/products to find your -product id. This is configured in `helm_deploy//values.yaml`. - -## Manually branding from template app - -Run the `rename-project.bash` without any arguments. This will prompt for the six required parameters and create a PR. -The script requires a recent version of `bash` to be installed, as well as GNU `sed` in the path. - -## TODOs and Examples - -We have tried to provide some examples of best practice in the application - so there are lots of TODOs in the code -where changes are required to meet your requirements. There is an `ExampleResource` that includes best practice and also -serve as spring security examples. The template typescript project has a demonstration that calls this endpoint as well. - -For the demonstration, rather than introducing a dependency on a different service, this application calls out to -itself. This is only to show a service calling out to another service and is certainly not recommended! - -## Running the application locally - -The application comes with a `dev` spring profile that includes default settings for running locally. This is not -necessary when deploying to kubernetes as these values are included in the helm configuration templates - -e.g. `values-dev.yaml`. - -There is also a `docker-compose.yml` that can be used to run a local instance of the template in docker and also an -instance of HMPPS Auth (required if your service calls out to other services using a token). - -```bash -docker compose pull && docker compose up -``` - -will build the application and run it and HMPPS Auth within a local docker instance. - -### Running the application in Intellij - -```bash -docker compose pull && docker compose up --scale hmpps-person-integration-api=0 -``` - -will just start a docker instance of HMPPS Auth. The application should then be started with a `dev` active profile -in Intellij. diff --git a/architecture-decision-record/0000-separate-domain-specific-code-by-package.md b/architecture-decision-record/0000-separate-domain-specific-code-by-package.md new file mode 100644 index 0000000..956a395 --- /dev/null +++ b/architecture-decision-record/0000-separate-domain-specific-code-by-package.md @@ -0,0 +1,36 @@ +[Contents](README.md), +[Next >](0001-structure-packages-by-api-version.md) + +# 0. Separate domain specific code by package + +Date: 2024-11-21 + +## Status + +✅ Accepted + +## Context + +The HMPPS Person integration API provides an interface to access data from two different domains. +The `Core Person Record` domain and the `Person Protected Characteristics` domain. These domains are +related but may be separated out into separate services in the future. + +## Decision + +There will be a top level package for each domain, `corepersonrecord` and `personprotectedcharacteristics` which will keep +any domain specific logic separate. A `common` package will be used for any shared code. + +``` +project/ +├── src/ +│ ├── main/ +│ │ ├── kotlin/ +│ │ │ ├── common/ # Common code shared across domains +│ │ │ ├── corepersonrecord/ # Core person record package +│ │ │ ├── personprotectedcharacteristics/ # Person protected characteristics package +│ │ └── resources/ +``` + +## Consequences + +N/A \ No newline at end of file diff --git a/architecture-decision-record/0001-structure-packages-by-api-version.md b/architecture-decision-record/0001-structure-packages-by-api-version.md new file mode 100644 index 0000000..4dc6f84 --- /dev/null +++ b/architecture-decision-record/0001-structure-packages-by-api-version.md @@ -0,0 +1,40 @@ +[< Previous](0001-structure-packages-by-api-version.md), +[Contents](README.md), +[Next >](0002-include-username-in-client-credential-token.md) + +# 1. Structure packages by API version + +Date: 2024-11-21 + +## Status + +✅ Accepted + +## Context + +This API is likely to go through multiple iterations as data models change and expand. To ensure the +API can evolve without causing friction to clients, we will version the API whenever there are breaking changes. +As there may be multiple versions of the API live at a given time we need to code structured and easy to maintain and understand. + +## Decision + +Code specific to a specific API version will be stored in a separate package. + +``` +project/ +├── src/ +│ ├── main/ +│ │ ├── kotlin/ +│ │ │ ├── common/ # Common code shared across modules or components +│ │ │ ├── corepersonrecord/ # Core person record module +│ │ │ │ ├── shared/ # Code common between versions +│ │ │ │ ├── v1/ # Version 1 specific code +│ │ │ │ ├── v2/ # Version 2 specific code +│ │ └── resources/ +``` + +## Consequences + +We will need to refactor the current package structure when we start introducing version 2 functionality. + + diff --git a/architecture-decision-record/0002-include-username-in-client-credential-token.md b/architecture-decision-record/0002-include-username-in-client-credential-token.md new file mode 100644 index 0000000..c7e222d --- /dev/null +++ b/architecture-decision-record/0002-include-username-in-client-credential-token.md @@ -0,0 +1,30 @@ +[< Previous](0002-include-username-in-client-credential-token.md), +[Contents](README.md), +[Next >](9999-end.md) + + + +# 2. Include username in client credentials token + +Date: 2024-11-21 + +## Status + +✅ Accepted + +## Context + +The HMPPS Person Integration API will make calls to downstream services using the OAuth 2.0 client credentials grant for authorisation. +The API will be authorised to make calls to downstream services however for audit purposes the username of the instigating user is required. +The HMPPS Auth service provides functionality to include a username within an OAuth token obtained using client credentials which can then be +verified and extracted by downstream services. + +## Decision + +The API will make use of the HMPPS Auth functionality to include a username within the token generated whe using a client credentials grant. + +## Consequences + +In order to the HMPPS Auth functionality to include the username in token when using the client credentials grant will require a non-standard +OAuth token request query. + diff --git a/architecture-decision-record/9999-end.md b/architecture-decision-record/9999-end.md new file mode 100644 index 0000000..b014c68 --- /dev/null +++ b/architecture-decision-record/9999-end.md @@ -0,0 +1,3 @@ +No more records + +[Back to Contents](README.md) diff --git a/architecture-decision-record/README.md b/architecture-decision-record/README.md new file mode 100644 index 0000000..ccf17db --- /dev/null +++ b/architecture-decision-record/README.md @@ -0,0 +1,17 @@ +# HMPPS Person Integration API Architecture Decisions + +This is a record of architectural decisions made during the development of the HMPPS Person Integration API project. + +## Table of contents + +* ✅ [Use separate packages for domain specific code](0000-separate-domain-specific-code-by-package.md) +* ✅ [Structure packages be API version](0001-structure-packages-by-api-version.md) +* ✅ [Include username in client credentials token](0002-include-username-in-client-credential-token.md) + +### Statuses: + +* Proposed: 🤔 +* Accepted: ✅ +* Rejected: ❌ +* Superseded: ⌛️ +* Amended: ♻️ diff --git a/readme/build_test_run.md b/readme/build_test_run.md new file mode 100644 index 0000000..8a3ac22 --- /dev/null +++ b/readme/build_test_run.md @@ -0,0 +1,128 @@ +[< Back](../README.md) +--- + +## Building + +To build the project without tests run: + +``` +./gradlew clean build -x test +``` + +## Testing + +To run the unit and integration tests: +``` +./gradlew test +``` + +## Running Locally + +There are two variation for running the application locally. + +- [Running against containerised dependencies](#Running against containerised dependencies) +- [Running against dependencies deployed in dev](#Running against dependencies deployed in dev) + +### Running against containerised dependencies + +The following command will build and run the application via docker compose along with containers for HMPPS Auth and Prison API. + +> NOTE: A client with the required roles will need to be added to the containerised version of HMPPS Auth in order to generate OAuth tokens. +> The client id and secret can then be referenced in a .env file as the `SYSTEM_CLIENT_ID` and `SYSTEM_CLIENT_SECRET`. + +``` +docker compose pull && docker compose up --build +``` + +This will run the application on http://localhost:8080 and the swagger docs will be found at http://localhost:8080/swagger-ui/index.html# . + +#### Running through Gradle or IntelliJ + +If you want to run the application through IntelliJ or command line with gradle using the containerised dependencies then use: + +``` +docker compose pull && docker compose up --scale hmpps-person-integration-api=0 +``` + +Then start the application using Gradle or IntelliJ. + +> NOTE: The required client credentials environment variables (`SYSTEM_CLIENT_ID` and `SYSTEM_CLIENT_SECRET`) will need to set prior to starting the application. + +**IntelliJ:** + +Run or debug the main class with the spring active profile set to `dev`: + +**Gradle:** + +``` +./gradlew bootRun --args='--spring.profiles.active=dev' +``` + +### Running against dependencies deployed in dev + +In order to run against deployed dependencies in dev the + +
+Environment variables required +
+Note, client credentials from the dev namespace (hmpps-person-integration-api-dev) kubernetes secrets. + +``` +SYSTEM_CLIENT_ID= +SYSTEM_CLIENT_SECRET= +HMPPS_AUTH_URL=https://sign-in-dev.hmpps.service.justice.gov.uk/auth +PRISON_API_BASE_URL=https://prison-api-dev.prison.service.justice.gov.uk +``` +
+ +Once the environment variables have been set the application can be run via Gradle or IntelliJ using the commands in [this section](#running-through-gradle-or-intellij) + +## Common gradle tasks + +To list project dependencies, run: + +``` +./gradlew dependencies +``` + +To check for dependency updates, run: +``` +./gradlew dependencyUpdates --warning-mode all +``` + +To run an OWASP dependency check, run: +``` +./gradlew clean dependencyCheckAnalyze --info +``` + +To upgrade the gradle wrapper version, run: +``` +./gradlew wrapper --gradle-version= +``` + +To automatically update project dependencies, run: +``` +./gradlew useLatestVersions +``` + +#### Ktlint Gradle Tasks + +To run Ktlint check: +``` +./gradlew ktlintCheck +``` + +To run Ktlint format: +``` +./gradlew ktlintFormat +``` + +To register pre-commit check to run Ktlint format: +``` +./gradlew addKtlintFormatGitPreCommitHook +``` + +...or to register pre-commit check to only run Ktlint check: +``` +./gradlew addKtlintCheckGitPreCommitHook +``` \ No newline at end of file