Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"build": {
"dockerfile": "../infrastructure/images/build-container/Dockerfile",
"args": {
"INCLUDE_DEV_CERTS": "true"
"INCLUDE_DEV_CERTS": "true",
"AWS_DIR": "${localEnv:HOME}/.aws"
}
},
"customizations": {
Expand Down Expand Up @@ -38,11 +39,12 @@
"omzPlugins": "https://github.com/zsh-users/zsh-autosuggestions.git https://github.com/zsh-users/zsh-syntax-highlighting.git"
}
},
"initializeCommand": "scripts/devcontainer/create-docker-network-if-required.sh && cp .tool-versions ${localWorkspaceFolder}/infrastructure/images/build-container/resources/.tool-versions && mkdir -p ${localEnv:HOME}/.proxygen",
"postCreateCommand": "doas apk add --no-cache openjdk21-jre && scripts/devcontainer/configure-zsh.sh && bash -c 'source ~/.bashrc && make config && pyenv activate pathology && make dependencies'",
"initializeCommand": "scripts/devcontainer/create-docker-network-if-required.sh && cp .tool-versions ${localWorkspaceFolder}/infrastructure/images/build-container/resources/.tool-versions && mkdir -p ${localEnv:HOME}/.proxygen && mkdir -p ${localEnv:HOME}/.aws",
"postCreateCommand": "doas apk add --no-cache openjdk21-jre aws-cli && scripts/devcontainer/configure-zsh.sh && bash -c 'source ~/.bashrc && make config && pyenv activate pathology && make dependencies'",
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind,consistency=cached",
"source=${localEnv:HOME}/.proxygen,target=/home/pathology-dev/.proxygen,type=bind,consistency=cached"
"source=${localEnv:HOME}/.proxygen,target=/home/pathology-dev/.proxygen,type=bind,consistency=cached",
"source=${localEnv:HOME}/.aws,target=/home/pathology-dev/.aws,type=bind,consistency=cached"
],
"remoteUser": "pathology-dev",
"containerUser": "pathology-dev",
Expand Down
14 changes: 3 additions & 11 deletions .github/workflows/preview-env.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ jobs:
cd pathology-api/target/
FN="${{ steps.names.outputs.function_name }}"
EXPIRY_THRESHOLD="${TOKEN_EXPIRY_THRESHOLD:-30s}"
JWKS_SECRET="${JWKS_SECRET_NAME:-/cds/pathology/dev/jwks/secret}"
PRIVATE_KEY="${APIM_PRIVATE_KEY:-/cds/pathology/dev/apim/private-key}"
API_KEY="${APIM_APIKEY:-/cds/pathology/dev/apim/api-key}"
MTLS_CERT="${API_MTLS_CERT:-/cds/pathology/dev/mtls/client1-key-public}"
Expand Down Expand Up @@ -330,19 +329,12 @@ jobs:
echo "url = ${{ steps.names.outputs.int_preview_url }}"

# ---------- Handle mock endpoints ----------
- name: Get Secrets for mocks
uses: aws-actions/aws-secretsmanager-get-secrets@2cb1a461cbd4865ac4299648312e4704c646cd53
with:
secret-ids: |
/cds/pathology/dev/jwks/secret
name-transformation: lowercase

- name: Create or update mock Lambda (on open/sync/reopen)
if: github.event.action != 'closed'
env:
TOKEN_EXPIRY_TIME: ${{ secrets.TOKEN_LIFETIME }}
AUTH_URL: "${{ steps.names.outputs.mock_preview_url }}/apim/oauth2/token"
JWKS_SECRET: ${{ env._cds_pathology_dev_jwks_secret }}
JWKS_SECRET_NAME: ${{ secrets.JWKS_SECRET_NAME }}
PUBLIC_KEY_URL: "https://pki.dev.endpoints.pathology-laboratory-reporting.national.nhs.uk/pathology.jwks"
DYNAMODB_TABLE_NAME: "mock_services_dev"
run: |
Expand Down Expand Up @@ -374,7 +366,7 @@ jobs:
TOKEN_LIFETIME=$TOKEN_LIFETIME, \
AUTH_URL=$AUTH_URL, \
PUBLIC_KEY_URL=$PUBLIC_KEY_URL, \
API_KEY=$JWKS_SECRET, \
API_KEY_SECRET_NAME="${JWKS_SECRET_NAME:-/cds/pathology/dev/jwks/secret}", \
TOKEN_TABLE_NAME=$DYNAMODB_TABLE_NAME, \
PDM_TABLE_NAME=$DYNAMODB_TABLE_NAME, \
MNS_TABLE_NAME=$DYNAMODB_TABLE_NAME \
Expand All @@ -392,7 +384,7 @@ jobs:
TOKEN_LIFETIME=$TOKEN_LIFETIME, \
AUTH_URL=$AUTH_URL, \
PUBLIC_KEY_URL=$PUBLIC_KEY_URL, \
API_KEY=$JWKS_SECRET, \
API_KEY_SECRET_NAME="${JWKS_SECRET_NAME:-/cds/pathology/dev/jwks/secret}", \
TOKEN_TABLE_NAME=$DYNAMODB_TABLE_NAME, \
PDM_TABLE_NAME=$DYNAMODB_TABLE_NAME, \
MNS_TABLE_NAME=$DYNAMODB_TABLE_NAME \
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,5 @@
},
// Disabling automatic port forwarding as the devcontainer should already have access to any required ports.
"remote.autoForwardPorts": false,
"python-envs.defaultEnvManager": "ms-python.python:pyenv"
"python-envs.defaultEnvManager": "ms-python.python:system"
}
17 changes: 10 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ docker := docker
endif

dockerNetwork := pathology-local
pythonPlatform := manylinux2014_$(shell uname -m)

# ==============================================================================

Expand Down Expand Up @@ -58,7 +59,8 @@ build-pathology:
@echo "Packaging dependencies..."
@poetry build --format=wheel
VERSION=$$(poetry version -s)
@pip install "dist/pathology_api-$$VERSION-py3-none-any.whl" --target "./target/pathology-api" --platform manylinux2014_x86_64 --only-binary=:all:
@echo Building pathology API: version=$$VERSION, platform=${pythonPlatform}
@pip install "dist/pathology_api-$$VERSION-py3-none-any.whl" --target "./target/pathology-api" --platform ${pythonPlatform} --only-binary=:all:
# Copy lambda_handler file separately as it is not included within the package.
@cp lambda_handler.py ./target/pathology-api/
@cd ./target/pathology-api
Expand All @@ -84,7 +86,8 @@ build-mocks:
@echo "Packaging dependencies..."
@poetry build --format=wheel
VERSION=$$(poetry version -s)
@pip install "dist/pathology_api_mocks-$$VERSION-py3-none-any.whl" --target "./target/mocks" --platform manylinux2014_x86_64 --only-binary=:all:
@echo Building mocks: version=$$VERSION, platform=${pythonPlatform}
@pip install "dist/pathology_api_mocks-$$VERSION-py3-none-any.whl" --target "./target/mocks" --platform ${pythonPlatform} --only-binary=:all:
# Copy lambda_handler file separately as it is not included within the package.
@cp lambda_handler.py ./target/mocks/
@cd ./target/mocks
Expand All @@ -108,24 +111,24 @@ build-images: build # Build the project artefact @Pipeline
@cp -r mocks/target/mocks infrastructure/images/mocks/resources/build

@echo "Building Docker image using Docker. Utilising python version: ${PYTHON_VERSION} ..."
@$(docker) buildx build --load --platform=linux/amd64 --provenance=false --build-arg PYTHON_VERSION=${PYTHON_VERSION} -t localhost/pathology-api-image infrastructure/images/pathology-api
@$(docker) buildx build --load --provenance=false --build-arg PYTHON_VERSION=${PYTHON_VERSION} -t localhost/pathology-api-image infrastructure/images/pathology-api
@echo "Docker image 'pathology-api-image' built successfully!"

@echo "Building api gateway image using Docker. Utilising python version: ${PYTHON_VERSION} ..."
@$(docker) buildx build --load --build-arg PYTHON_VERSION=${PYTHON_VERSION} -t localhost/api-gateway-mock-image infrastructure/images/api-gateway-mock
@echo "Docker image 'api-gateway-mock-image' built successfully!"

@echo "Building mocks Docker image using Docker. Utilising python version: ${PYTHON_VERSION} ..."
@$(docker) buildx build --load --platform=linux/amd64 --provenance=false --build-arg PYTHON_VERSION=${PYTHON_VERSION} -t localhost/mocks-image infrastructure/images/mocks
@$(docker) buildx build --load --provenance=false --build-arg PYTHON_VERSION=${PYTHON_VERSION} -t localhost/mocks-image infrastructure/images/mocks
@echo "Docker image 'mocks-image' built successfully!"

publish: # Publish the project artefact @Pipeline
# TODO: Implement the artefact publishing step

deploy: clean-docker build-images # Deploy the project artefact to the target environment @Pipeline
deploy: clean-docker env-local-dev build-images # Deploy the project artefact to the target environment @Pipeline
$(docker) network create $(dockerNetwork) || echo "Docker network '$(dockerNetwork)' already exists."
$(docker) run --platform linux/amd64 --name pathology-api -p 5001:8080 --network $(dockerNetwork) -d localhost/pathology-api-image
$(docker) run --platform linux/amd64 --name mocks -p 5003:8080 --network $(dockerNetwork) -d localhost/mocks-image
$(docker) run --name pathology-api -p 5001:8080 --env-file=".env.pathology-api.local" --mount type=bind,src=$(AWS_DIR),dst=/root/.aws --network $(dockerNetwork) -d localhost/pathology-api-image
$(docker) run --name mocks -p 5003:8080 --env-file=".env.mock.local" --mount type=bind,src=$(AWS_DIR),dst=/root/.aws --network $(dockerNetwork) -d localhost/mocks-image
$(docker) run --name pathology-api-gateway -p 5002:5000 -e TARGET_CONTAINER='PATHOLOGY_API' -e TARGET_URL='http://pathology-api:8080' --network $(dockerNetwork) -d localhost/api-gateway-mock-image
$(docker) run --name mocks-api-gateway -p 5005:5000 -e TARGET_CONTAINER='MOCKS' -e TARGET_URL='http://mocks:8080' --network $(dockerNetwork) -d localhost/api-gateway-mock-image

Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@ Once the build container has been built and is up and running, A few different `
- `deploy` - builds the codebase and deploys it within a separate container locally.
- `clean` - stops and removes any containers outside of the Dev container locally.

### AWS Credentials

The local deployment containers make use of AWS resources which require you to be authenticated with AWS to be accessed.

For first time set up you should run `aws configure sso`.
The session name can be anything e.g. `dev-session`.
The URL is the same one we use to select an account to log into AWS console or you can use the one provided under access keys on that same portal.
The region should be set to eu-west-2.
You can leave the registration scopes as default `sso:account:access`.
It will then open a browser link which you will have to log onto and accept the permissions request.

It will then asks you which account to use, select the one you would like to use.
Set the default region for the profile to eu-west-2.
Leave the profile name as default as this will need to match the automatic one set by the make command.

After you have setup a session you can login using that session again by running the command `aws sso login --profile AWS-CDSPath-DEV_DevAccess-859065147940`
or `aws sso login --ssp-session [session-name]`

### Testing

There are `make` tasks for you to configure to run your tests. Run `make test` to see how they work. You should be able to use the same entry points for local development as in your CI pipeline.
Expand Down
3 changes: 2 additions & 1 deletion bruno/APIM/Get_Auth_Token.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Get Auth Token
type: http
seq: 1
seq: 2
}

post {
Expand Down Expand Up @@ -57,6 +57,7 @@ script:pre-request {
const environment = bru.getGlobalEnvVar("APIM_ENV")
generateAuthToken(bru, req, `https://${environment}.api.service.nhs.uk/oauth2/token`, bru.getEnvVar("KID"));
}

script:post-response {
bru.setGlobalEnvVar("auth_token", res.getBody().access_token)
}
Expand Down
2 changes: 1 addition & 1 deletion bruno/APIM/Post_Document_Bundle_via_APIM.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Post Document Bundle via APIM
type: http
seq: 2
seq: 3
}

post {
Expand Down
2 changes: 1 addition & 1 deletion bruno/APIM/Post_Document_Bundle_via_APIM_INT.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Post Document Bundle via APIM - INT
type: http
seq: 3
seq: 4
}

post {
Expand Down
80 changes: 80 additions & 0 deletions bruno/APIM/Post_Document_Bundle_via_Local_Deployment.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
meta {
name: Post Document Bundle via Local Deployment
type: http
seq: 5
}

post {
url: http://localhost:5002/FHIR/R4/Bundle
body: json
auth: none
}

headers {
Content-Type: application/fhir+json
X-Correlation-ID: c0ccbce4-d41f-4f6a-9958-c32b48fe46e2
}

body:json {
{
"resourceType": "Bundle",
"type": "document",
"entry": [
{
"fullUrl": "composition",
"resource": {
"resourceType": "Composition",
"extension": [
{
"url": "http://hl7.eu/fhir/StructureDefinition/composition-basedOn-order-or-requisition",
"valueReference": {
"reference": "servicerequest"
}
}
],
"subject": {
"identifier": {
"system": "https://fhir.nhs.uk/Id/nhs-number",
"value": "test-nhs-number"
}
}
}
},
{
"fullUrl": "servicerequest",
"resource": {
"resourceType": "ServiceRequest",
"requester": {
"reference": "practitionerrole"
}
}
},
{
"fullUrl": "practitionerrole",
"resource": {
"resourceType": "PractitionerRole",
"organization": {
"reference": "organization"
}
}
},
{
"fullUrl": "organization",
"resource": {
"resourceType": "Organization",
"identifier": [
{
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
"value": "testOrg"
}
]
}
}
]
}
}

settings {
encodeUrl: true
timeout: 0
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_CDAPI-150_Organization_Identifier_With_Empty_String
type: http
seq: 38
seq: 4
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_CDAPI-150_Subject_Identifier_With_Empty_String
type: http
seq: 37
seq: 7
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_MNS_Service_Experience_Bad_Gateway_Error
type: http
seq: 9
seq: 6
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_MNS_Service_Experience_Gateway_Timeout_Error
type: http
seq: 11
seq: 5
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_MNS_Service_Experience_Validation_Error
type: http
seq: 14
seq: 5
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_MNS_Service_Returns_Client_Side_Error
type: http
seq: 8
seq: 5
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_PDM_Api_Server_Error
type: http
seq: 18
seq: 5
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_PDM_Api_Validation_Error
type: http
seq: 15
seq: 5
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_PDM_Bundle_Succesful_Response
type: http
seq: 19
seq: 5
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_With_Incorrect_ReferenceType
type: http
seq: 21
seq: 5
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_With_Incorrect_ReferenceType_in_Extension
type: http
seq: 20
seq: 5
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_With_Invalid_Identifiers_in_Organization
type: http
seq: 29
seq: 5
}

post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: Test_With_Multiple_Bundle_Entries_With_Same_URL
type: http
seq: 32
seq: 5
}

post {
Expand Down
Loading
Loading