diff --git a/gateway-api/src/gateway_api/app.py b/gateway-api/src/gateway_api/app.py index 1ee168b6..4edd0f83 100644 --- a/gateway-api/src/gateway_api/app.py +++ b/gateway-api/src/gateway_api/app.py @@ -1,7 +1,7 @@ import os import traceback -from flask import Flask, request +from flask import Flask, Request, request from flask.wrappers import Response from gateway_api.common.error import AbstractCDGError, UnexpectedError @@ -12,6 +12,7 @@ ) app = Flask(__name__) +app.logger.setLevel("INFO") def get_app_host() -> str: @@ -30,8 +31,29 @@ def get_app_port() -> int: return int(port) +def log_request_received(request: Request) -> None: + log_details = { + "description": "Received request", + "method": request.method, + "path": request.path, + "headers": dict(request.headers), + } + app.logger.info(log_details) + + +def log_error(error: AbstractCDGError) -> None: + log_details = { + "description": "An error occurred", + "error_type": type(error).__name__, + "error_message": str(error), + "traceback": traceback.format_exc(), + } + app.logger.error(log_details) + + @app.route("/patient/$gpc.getstructuredrecord", methods=["POST"]) def get_structured_record() -> Response: + log_request_received(request) response = GetStructuredRecordResponse() response.mirror_headers(request) try: @@ -40,11 +62,11 @@ def get_structured_record() -> Response: provider_response = controller.run(request=get_structured_record_request) response.add_provider_response(provider_response) except AbstractCDGError as e: - e.log() + log_error(e) response.add_error_response(e) except Exception: error = UnexpectedError(traceback=traceback.format_exc()) - error.log() + log_error(error) response.add_error_response(error) return response.build() diff --git a/gateway-api/src/gateway_api/common/error.py b/gateway-api/src/gateway_api/common/error.py index e6135865..57be0565 100644 --- a/gateway-api/src/gateway_api/common/error.py +++ b/gateway-api/src/gateway_api/common/error.py @@ -1,4 +1,3 @@ -import traceback from dataclasses import dataclass from http.client import BAD_GATEWAY, BAD_REQUEST, INTERNAL_SERVER_ERROR, NOT_FOUND @@ -37,9 +36,6 @@ def operation_outcome(self) -> OperationOutcome: ) return operation_outcome - def log(self) -> None: - print(traceback.format_exc(), flush=True) - @property def message(self) -> str: return self._message.format(**self.additional_details) diff --git a/gateway-api/tests/conftest.py b/gateway-api/tests/conftest.py index 851eee98..f77c729d 100644 --- a/gateway-api/tests/conftest.py +++ b/gateway-api/tests/conftest.py @@ -214,7 +214,7 @@ def _fetch_env_variable[T]( REMOTE_TEST_USERNAME_ENV_VAR = "REMOTE_TEST_USERNAME" -DEFAULT_REMOTE_TEST_USERNAME = "656005750104" +DEFAULT_REMOTE_TEST_USERNAME = "656005750101" def _get_remote_test_username() -> str: diff --git a/proxygen/README.md b/proxygen/README.md index 6c960f85..40e27f6d 100644 --- a/proxygen/README.md +++ b/proxygen/README.md @@ -62,7 +62,8 @@ Proxygen deploys a proxy instance using an OpenAPI specification file. The speci * the **target endpoint URL** to which the proxy will forward traffic; * the **access controls** and scopes a user needs to access the proxy; -* the **mTLS secret name** pointing to the certificate the backend expects. +* the **mTLS secret name** pointing to the certificate the backend expects; +* the **target-identity** to add user identity headers to the request. At deploy time, this template is concatenated with the main API specification (`gateway-api/openapi.yaml`), the target URL and mTLS secret are injected, and the resulting file is passed to the Proxygen CLI. diff --git a/proxygen/x-nhsd-apim.template.yaml b/proxygen/x-nhsd-apim.template.yaml index e8cba5a1..e2870ade 100644 --- a/proxygen/x-nhsd-apim.template.yaml +++ b/proxygen/x-nhsd-apim.template.yaml @@ -11,3 +11,6 @@ x-nhsd-apim: security: type: mtls secret: + target-identity: + - name: cis2-uuid + - name: cis2-urid