Skip to content

An API to help prisoners create a personal development plan for their time in prison and after release

License

Notifications You must be signed in to change notification settings

ministryofjustice/hmpps-education-and-work-plan-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hmpps-education-and-work-plan-api

repo standards badge CircleCI Docker Repository on Quay API docs

About

A Kotlin application providing APIs to support managing Education And Work Plans for prisoners.

Team

This application is in development by the Farsight Consulting team Personal Learning Plans (PLP). They can be contacted on MOJ Slack channel #plp-dev.

Health

The application has a health endpoint found at /health which indicates if the app is running and is healthy.

Ping

The application has a ping endpoint found at /ping which indicates that the app is responding to requests.

Configuring the project

JDK

To develop and build the application locally you will need JDK 21 installed and configured.

Ktlint formatting

Ktlint is used to format the source code and a task runs in the Circle build to check the formatting.

You should run the following commands to make sure that the source code is formatted locally before it breaks the Circle build.

Apply ktlint formatting rules to Intellij

./gradlew ktlintApplyToIdea

Or to apply to all Intellij projects:

./gradlew ktlintApplyToIdeaGlobally

Run ktlint formatter on git commit

./gradlew addKtlintFormatGitPreCommitHook

Running the app

The easiest (and slowest) way to run the app is to use docker compose to create the service and all dependencies.

docker-compose pull

docker-compose up

  • See http://localhost:8081/health to check the app is running.
  • See http://localhost:8081/swagger-ui/index.html?configUrl=/v3/api-docs to explore the OpenAPI spec document.

Environment variables

The following environment variables are required in order for the app to start:

General

Name Description
SERVER_PORT The port that the application will run on
HMPPS_AUTH_URL The URL for OAuth 2.0 authorisation server

Database

Name Description
DB_SERVER The host of the DB server
DB_NAME The name of the database instance
DB_USER The application's DB username
DB_PASS The DB user's password

Application Insights

Name Description
APPINSIGHTS_INSTRUMENTATIONKEY The instrumentation key for App Insights
APPLICATIONINSIGHTS_CONNECTION_STRING The connection string for App Insights
APPLICATIONINSIGHTS_CONFIGURATION_FILE A configuration file for App Insights

APIs

Name Description
PRISON_API_URL The URL of the Prison API
PRISON_API_CLIENT_ID hmpps-auth oauth2 client-id for connecting to the Prison API
PRISON_API_CLIENT_SECRET hmpps-auth oauth2 client-secret for connecting to the Prison API
PRISONER_SEARCH_API_URL The URL of the Prisoner Search API
PRISONER_SEARCH_API_CLIENT_ID hmpps-auth oauth2 client-id for connecting to the Prisoner Search API
PRISONER_SEARCH_API_CLIENT_SECRET hmpps-auth oauth2 client-secret for connecting to the Prisoner Search API
MANAGE_USERS_API_URL The URL of the Manage Users API
MANAGE_USERS_API_CLIENT_ID hmpps-auth oauth2 client-id for connecting to the Manage Users API
MANAGE_USERS_API_CLIENT_SECRET hmpps-auth oauth2 client-secret for connecting to the Manage Users API

Development and maintenance

Running the tests

To run the test suite (unit and integration):

./gradle clean check

Integration test dependencies

The integration tests spin up the following docker containers, therefore a docker runtime is required on local development environments in order to run the tests.

  • postgres - A real postgres instance is used rather than h2 in order to properly test various constraints etc. (h2 is more forgiving that postgres in this respect)

Monitoring, tracing and event reporting

The API is instrumented with the opentelemetry and Application Insights java agent. Useful data can be found and reported on via the Azure Application Insights console, all under the cloud_RoleName property of hmpps-education-and-work-plan-api.

The Application Insights console and the Kusto Query Language will be your friend here, but some example queries are described below.

All example query links below are for nomisapi-t3 (dev) - you will need to change the scope in order to target preprod or prod.

HTTP requests

Each HTTP request is logged in Application Insights. These can be queried as follows:

The where name clause is significant, otherwise the query will also return hits to the /health and /info endpoints.

requests
| where cloud_RoleName == 'hmpps-education-and-work-plan-api'
| where name has '/action-plans'
| order by timestamp 

Custom events

A number of custom events are triggered at various points in the API. The custom event names can be discovered with the following query

customEvents
| where cloud_RoleName == 'hmpps-education-and-work-plan-api'
| distinct name

Projecting fields from custom dimensions

A query can include field projections, including projecting named fields from within the custom dimensions data.
For example

customEvents
| where cloud_RoleName == 'hmpps-education-and-work-plan-api'
| where name == 'goal-create'
| project 
    timestamp,
    status = customDimensions.status, 
    reference = customDimensions.reference,
    stepCount = customDimensions.stepCount
| order by timestamp  

Charting data

Queries can contain aggregate functions, and the results rendered in charts. For example, this query produces a column chart of the number of goals created per day that were created with more than 2 steps:

customEvents
| where cloud_RoleName == 'hmpps-education-and-work-plan-api'
| where name == 'goal-create'
| where customDimensions.stepCount > 2
| summarize count() by bin(timestamp, 1d)
| render columnchart

Joining data

Several objects within the Application Insights "tables" contain an operation_Id field which is effectively a correlation ID between objects. For example, this query produces a report of usernames who have created goals with more than 2 steps. It does this by querying the customEvents table for records whose name is goal-create and whose custom dimension field stepCount is greater than 2. It then joins on the requests table on the operation_Id field, projecting out the custom dimension field username back out to the outer query.

customEvents
| where cloud_RoleName == 'hmpps-education-and-work-plan-api'
| where 
    name == 'goal-create'
    and customDimensions.stepCount > 2
| join kind=innerunique
    (requests
        | where cloud_RoleName == 'hmpps-education-and-work-plan-api'
        | project 
            operation_Id, 
            username = customDimensions.username
    )
    on operation_Id
| project
    timestamp,
    username
| order by timestamp desc 

JVM problems

There could be problems with the JVM used in the API, such as running out of threads or memory.

Various JVM related metrics are pushed to Application Insights by Spring/Micrometer. Run the following query to see what metrics are available:

customMetrics
| where cloud_RoleName == 'hmpps-education-and-work-plan-api'
| where name startswith 'jvm'
| order by timestamp desc 

For example, if the memory usage is consistently high you may need to increase the memory allocated in the helm_dploy/hmpps-education-and-work-plan-api/values.yaml file env var JAVA_OPTS.

API external dependencies

This API consumes, and is therefore dependent on, data from the following APIs:

  • hmpps-auth - Standard HMPPS Digital configuration; used for Spring Security.
  • application-insights - Standard HMPPS Digital configuration; used for telemetry and event tracing.
  • prison-api - The Prison API; used for looking up a Prisoner's prison history.
  • manage-users-api - The Manage Users API; used for looking up the full name (display name) of DPS users.
  • prisoner-search-api - The Prisoner Search API; used for looking up Prisoner data in order to get their release date.

API consumers

The following are the known consumers of this API. Any changes to this API - especially breaking or potentially breaking changes should consider the use case of these consumers.

As is standard in HMPPS projects the term "service UI" specifically means the node/express service codebase; and not the UI running in the browser. UI's running in the browser do not make xhr/ajax style requests directly to the APIs.

  • hmpps-eduction-and-work-plan-ui - The Education and Work Plan service UI (aka PLP)
    The REST API endpoints exposed by this API are consumed by the service UI. Roles required are dependent on the API endpoint being consumed - see the individual controller methods and/or swagger spec for specific details.
  • hmpps-prisoner-profile - The DPS Prisoner Profile UI
    The DPS Prisoner Profile UI consumes the GET /action-plans/{prisonNumber}/goals endpoint in order to retrieve the prisoner's active goals from their action plan. The role required is ROLE_EDUCATION_AND_WORK_PLAN__GOALS__RO

Feature Toggles

Features can be toggled by setting the relevant environment variable.

Name Default Value Type Description
SOME_TOGGLE_ENABLED false Boolean Example feature toggle, for demonstration purposes.

About

An API to help prisoners create a personal development plan for their time in prison and after release

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages