Skip to content

Commit ae7f964

Browse files
[CDAPI-78]: created mock for apim
1 parent f55afb7 commit ae7f964

17 files changed

Lines changed: 2439 additions & 36 deletions

File tree

.github/workflows/preview-env.yaml

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ env:
2020
PYTHON_VERSION: 3.14
2121
LAMBDA_RUNTIME: python3.14
2222
LAMBDA_HANDLER: lambda_handler.handler
23-
MOCK_LAMBDA_HANDLER: handler.handler
23+
MOCK_LAMBDA_HANDLER: lambda_handler.handler
2424
MTLS_SECRET_NAME: ${{ vars.PREVIEW_ENV_MTLS_SECRET_NAME }}
2525
PROXYGEN_KEY_ID: ${{ vars.PREVIEW_ENV_PROXYGEN_KEY_ID }}
2626
PROXYGEN_CLIENT_ID: ${{ vars.PREVIEW_ENV_PROXYGEN_CLIENT_ID }}
@@ -48,18 +48,10 @@ jobs:
4848
with:
4949
python-version: ${{ env.PYTHON_VERSION }}
5050

51-
- name: Package artifact
51+
- name: Package artifacts
5252
run: |
5353
make build
5454
55-
# Place holder mock artifact packaging to allow testing of mock API in preview environment;
56-
# can be extended to build a real mock Lambda if needed
57-
- name: Package mock artifact
58-
run: |
59-
cd infrastructure/environments/preview
60-
rm -f mock_artifact.zip
61-
zip -r mock_artifact.zip .
62-
6355
- name: Select AWS role inputs
6456
id: role-select
6557
env:
@@ -207,8 +199,14 @@ jobs:
207199
if: github.event.action != 'closed'
208200
env:
209201
TOKEN_EXPIRY_TIME: ${{ secrets.TOKEN_LIFETIME }}
202+
JWT_ALGORITHMS: "RS512"
203+
AUTH_URL: "${{ steps.names.outputs.mock_preview_url }}/oauth2/token"
204+
JWKS_SECRET: "${{ secrets.JWKS_SECRET }}"
205+
PUBLIC_KEY_URL: "https://example.com"
206+
TOKEN_TABLE_NAME: "mock_services_dev"
210207
run: |
211-
cd infrastructure/environments/preview
208+
cd mocks/target/
209+
JWKS_SECRET="${JWKS_SECRET_NAME:-/cds/pathology/dev/jwks/secret}"
212210
MFN="${{ steps.names.outputs.mock_function_name }}"
213211
SAFE="${{ steps.branch.outputs.safe }}"
214212
TOKEN_LIFETIME="${TOKEN_EXPIRY_TIME:-15m}"
@@ -233,18 +231,28 @@ jobs:
233231
--handler "${{ env.MOCK_LAMBDA_HANDLER }}" \
234232
--environment "Variables={CLIENT_PUBLIC_KEY_ARN=mock, \
235233
DDB_INDEX_TAG=$SAFE, \
236-
TOKEN_LIFETIME=$TOKEN_LIFETIME}" || true
234+
TOKEN_LIFETIME=$TOKEN_LIFETIME, \
235+
AUTH_URL=$AUTH_URL, \
236+
PUBLIC_KEY_URL=$PUBLIC_KEY_URL, \
237+
API_KEY=$JWKS_SECRET, \
238+
TOKEN_TABLE_NAME=$TOKEN_TABLE_NAME \
239+
}" || true
237240
wait_for_lambda_ready
238-
aws lambda update-function-code --function-name "$MFN" --zip-file "fileb://mock_artifact.zip" --publish
241+
aws lambda update-function-code --function-name "$MFN" --zip-file "fileb://artifact.zip" --publish
239242
else
240243
aws lambda create-function --function-name "$MFN" \
241244
--runtime "${{ env.LAMBDA_RUNTIME }}" \
242245
--handler "${{ env.MOCK_LAMBDA_HANDLER }}" \
243-
--zip-file "fileb://mock_artifact.zip" \
246+
--zip-file "fileb://artifact.zip" \
244247
--role "${{ steps.role-select.outputs.lambda_role }}" \
245248
--environment "Variables={CLIENT_PUBLIC_KEY_ARN=mock, \
246249
DDB_INDEX_TAG=$SAFE, \
247-
TOKEN_LIFETIME=$TOKEN_LIFETIME}" \
250+
TOKEN_LIFETIME=$TOKEN_LIFETIME, \
251+
AUTH_URL=$AUTH_URL, \
252+
PUBLIC_KEY_URL=$PUBLIC_KEY_URL, \
253+
API_KEY=$JWKS_SECRET, \
254+
TOKEN_TABLE_NAME=$TOKEN_TABLE_NAME, \
255+
}" \
248256
--publish
249257
wait_for_lambda_ready
250258
fi
@@ -454,7 +462,7 @@ jobs:
454462
'**Deployment Complete**',
455463
`- Preview URL: [${url}](${url}) — [Status](${url}/_status)`,
456464
` - Smoke Test: ${smokeReadable} (HTTP ${smokeStatus})`,
457-
`- Mock URL: [${mock_url}](${mock_url})`,
465+
`- Mock URL: [${mock_url}](${mock_url}) — [Status](${mock_url}/_status)`,
458466
` - Smoke Mock Test: ${smokeMockReadable} (HTTP ${smokeMockStatus})`,
459467
`- Proxy URL: [${proxy_url}](${proxy_url})`,
460468
`- Lambda Function: ${fn}`,

.gitleaksignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@ cd9c0efec38c5d63053dd865e5d4e207c0760d91:docs/guides/Perform_static_analysis.md:
66

77
pathology-api/pyproject.toml:ipv4:51
88
pathology-api/pyproject.toml:ipv4:50
9-
109
mocks/pyproject.toml:ipv4:54
1110
mocks/pyproject.toml:ipv4:55

Makefile

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ dockerNetwork := pathology-local
1818

1919
.PHONY: dependencies
2020
dependencies: # Install dependencies needed to build and test the project @Pipeline
21-
cd pathology-api && poetry sync
21+
@cd pathology-api && poetry sync
22+
@cd ../mocks && poetry sync
2223

23-
.PHONY: build
24-
build: clean-artifacts dependencies
24+
.PHONY: build-pathology
25+
build-pathology:
2526
@cd pathology-api
27+
@echo "Starting build for pathology API..."
2628
@echo "Running type checks..."
2729
@rm -rf target && rm -rf dist
2830
@poetry run mypy --no-namespace-packages .
@@ -35,13 +37,39 @@ build: clean-artifacts dependencies
3537
@cd ./target/pathology-api
3638
@zip -r "../artifact.zip" .
3739

40+
.PHONY: build-mocks
41+
build-mocks:
42+
@cd mocks
43+
@echo "Starting build for mocks..."
44+
@echo "Running type checks..."
45+
@rm -rf target && rm -rf dist
46+
@poetry run mypy --no-namespace-packages .
47+
@echo "Packaging dependencies..."
48+
@poetry build --format=wheel
49+
VERSION=$$(poetry version -s)
50+
@pip install "dist/pathology_api_mocks-$$VERSION-py3-none-any.whl" --target "./target/mocks" --platform manylinux2014_x86_64 --only-binary=:all:
51+
# Copy lambda_handler file separately as it is not included within the package.
52+
@cp lambda_handler.py ./target/mocks/
53+
@cd ./target/mocks
54+
@zip -r "../artifact.zip" .
55+
56+
.PHONY: build
57+
build: clean-artifacts dependencies build-pathology build-mocks
58+
@echo "Built artifacts for both pathology and mocks"
59+
60+
3861
.PHONY: build-images
3962
build-images: build # Build the project artefact @Pipeline
4063
@mkdir infrastructure/images/pathology-api/resources/build/
4164
@cp pathology-api/target/artifact.zip infrastructure/images/pathology-api/resources/build/
4265
@mkdir infrastructure/images/pathology-api/resources/build/pathology-api
4366
@unzip infrastructure/images/pathology-api/resources/build/artifact.zip -d infrastructure/images/pathology-api/resources/build/pathology-api
4467

68+
@mkdir infrastructure/images/mocks/resources/build/
69+
@cp mocks/target/artifact.zip infrastructure/images/mocks/resources/build/
70+
@mkdir infrastructure/images/mocks/resources/build/mocks
71+
@unzip infrastructure/images/mocks/resources/build/artifact.zip -d infrastructure/images/mocks/resources/build/mocks
72+
4573
@echo "Building Docker image using Docker. Utilising python version: ${PYTHON_VERSION} ..."
4674
@$(docker) buildx build --load --platform=linux/amd64 --provenance=false --build-arg PYTHON_VERSION=${PYTHON_VERSION} -t localhost/pathology-api-image infrastructure/images/pathology-api
4775
@echo "Docker image 'pathology-api-image' built successfully!"
@@ -50,18 +78,37 @@ build-images: build # Build the project artefact @Pipeline
5078
@$(docker) buildx build --load --build-arg PYTHON_VERSION=${PYTHON_VERSION} -t localhost/api-gateway-mock-image infrastructure/images/api-gateway-mock
5179
@echo "Docker image 'api-gateway-mock-image' built successfully!"
5280

81+
@echo "Building mocks Docker image using Docker. Utilising python version: ${PYTHON_VERSION} ..."
82+
@$(docker) buildx build --load --platform=linux/amd64 --provenance=false --build-arg PYTHON_VERSION=${PYTHON_VERSION} -t localhost/mocks-image infrastructure/images/mocks
83+
@echo "Docker image 'mocks-image' built successfully!"
84+
5385
publish: # Publish the project artefact @Pipeline
5486
# TODO: Implement the artefact publishing step
5587

5688
deploy: clean-docker build-images # Deploy the project artefact to the target environment @Pipeline
5789
$(docker) network create $(dockerNetwork) || echo "Docker network '$(dockerNetwork)' already exists."
58-
$(docker) run --platform linux/amd64 --name pathology-api -p 5001:8080 --network $(dockerNetwork) -d localhost/pathology-api-image
90+
$(docker) run --platform linux/amd64 --name pathology-api -p 5001:8080 --network $(dockerNetwork) -d localhost/pathology-api-image
91+
$(docker) run --platform linux/amd64 --name mocks -p 5003:8080 --network $(dockerNetwork) -d localhost/mocks-image
5992
$(docker) run --name api-gateway-mock -p 5002:5000 --network $(dockerNetwork) -d localhost/api-gateway-mock-image
93+
$(docker) run --name api-gateway-mock-2 -p 5005:5000 -e TARGET_CONTAINER='MOCKS' --network $(dockerNetwork) -d localhost/api-gateway-mock-image
94+
95+
# .PHONY: quick-deploy-mock
96+
# quick-deploy-mock: build-mocks
97+
# @echo "Stopping mocks container..."
98+
# @$(docker) stop mocks || echo "No mocks container currently running."
99+
100+
# @echo "Removing mocks container..."
101+
# @$(docker) rm mocks || echo "No mocks container currently exists."
102+
103+
# @$(docker) run --platform linux/amd64 --name mocks -p 5003:8080 --network $(dockerNetwork) -d localhost/mocks-image
104+
60105

61106
clean-artifacts:
62107
@echo "Removing build artefacts..."
63108
@rm -rf infrastructure/images/pathology-api/resources/build/
64109
@rm -rf pathology-api/target && rm -rf pathology-api/dist
110+
@rm -rf infrastructure/images/mocks/resources/build/
111+
@rm -rf mocks/target && rm -rf mocks/dist
65112

66113
clean-docker: stop
67114
@echo "Removing pathology API container..."
@@ -70,6 +117,12 @@ clean-docker: stop
70117
@echo "Removing api-gateway-mock container..."
71118
@$(docker) rm api-gateway-mock || echo "No api-gateway-mock container currently exists."
72119

120+
@echo "Removing mocks container..."
121+
@$(docker) rm mocks || echo "No mocks container currently exists."
122+
123+
@echo "Removing api-gateway-mock-2 container..."
124+
@$(docker) rm api-gateway-mock-2 || echo "No api-gateway-mock-2 container currently exists."
125+
73126
clean:: clean-artifacts clean-docker # Clean-up project resources (main) @Operations
74127

75128
.PHONY: stop
@@ -80,6 +133,12 @@ stop:
80133
@echo "Stopping api-gateway-mock container..."
81134
@$(docker) stop api-gateway-mock || echo "No api-gateway-mock container currently running."
82135

136+
@echo "Stopping mocks container..."
137+
@$(docker) stop mocks || echo "No mocks container currently running."
138+
139+
@echo "Stopping api-gateway-mock-2 container..."
140+
@$(docker) stop api-gateway-mock-2 || echo "No api-gateway-mock-2 container currently running."
141+
83142
config:: # Configure development environment (main) @Configuration
84143
# Configure poetry to trust dev certificate if specified
85144
@if [[ -n "$${DEV_CERTS_INCLUDED}" ]]; then \

infrastructure/environments/preview/handler.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
"""
2-
Simple lambda handler function for an debugging environment.
3-
This is used to verify that the environment is working and to inspect incoming requests.
4-
"""
5-
1+
# Simple lambda handler function for an debugging environment.
2+
# used to verify that the environment is working and to inspect incoming requests.
63
import json
74
import logging
85
from typing import Any

infrastructure/images/api-gateway-mock/resources/server.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
from logging.config import dictConfig
23

34
import requests
@@ -25,7 +26,12 @@
2526
)
2627

2728
app = Flask(__name__) # NOSONAR python:S4502
28-
cors = CORS(app, resources={r"/*": {"origins": "http://localhost:5002"}})
29+
TARGET_CONTAINER = os.environ.get("TARGET_CONTAINER")
30+
31+
if TARGET_CONTAINER == "MOCKS":
32+
cors = CORS(app, resources={r"/*": {"origins": "http://localhost:5004"}})
33+
else:
34+
cors = CORS(app, resources={r"/*": {"origins": "http://localhost:5002"}})
2935

3036

3137
@app.route( # NOSONAR python:S3752
@@ -37,9 +43,15 @@
3743
def forward_request(path_params):
3844
app.logger.info("received request with data: %s", request.get_data(as_text=True))
3945

46+
if TARGET_CONTAINER == "MOCKS":
47+
base_url = "http://mocks:8080" # NOSONAR python:S5332
48+
content_type = "application/x-www-form-urlencoded"
49+
else:
50+
base_url = "http://pathology-api:8080" # NOSONAR python:S5332
51+
content_type = "application/json"
52+
4053
response = requests.post(
41-
"http://pathology-api:8080/2015-03-31" # NOSONAR python:S5332
42-
"/functions/function/invocations",
54+
f"{base_url}/2015-03-31/functions/function/invocations",
4355
json={
4456
"body": request.get_data(as_text=True).replace("\n", "").replace(" ", ""),
4557
"requestContext": {
@@ -55,7 +67,7 @@ def forward_request(path_params):
5567
"rawQueryString": "",
5668
"pathParameters": {"proxy": path_params},
5769
},
58-
headers={"Content-Type": "application/json"},
70+
headers={"Content-Type": content_type},
5971
timeout=120,
6072
)
6173

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Retrieve the python version from build arguments, deliberately set to "invalid" by default to highlight when no version is provided when building the container.
2+
ARG PYTHON_VERSION=invalid
3+
# Use the specified python version to retrieve the required base lambda image.
4+
ARG url=public.ecr.aws/lambda/python:${PYTHON_VERSION}
5+
FROM $url
6+
7+
COPY resources/ /resources
8+
9+
COPY /resources/build/mocks ${LAMBDA_TASK_ROOT}
10+
11+
CMD [ "lambda_handler.handler" ]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

mocks/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/target
2+
/dist
3+
/.coverage

mocks/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Mocks Lambda
2+
3+
## Testing
4+
5+
### Continuous
6+
7+
### Quick Test Commands
8+
9+
## Project Structure
10+
11+
### Implementing new mock

0 commit comments

Comments
 (0)