diff --git a/.coveragerc b/.coveragerc index 25451b355..f52bf74da 100644 --- a/.coveragerc +++ b/.coveragerc @@ -5,4 +5,5 @@ omit = tests/* **/tests/* application/dos_db_handler/*.py + **/conftest.py branch = True diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index bbbc8d9db..2167bb12c 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -1,4 +1,4 @@ -name: 'Dependency Review' +name: "Dependency Review" on: [pull_request] permissions: @@ -8,7 +8,7 @@ jobs: dependency-review: runs-on: ubuntu-latest steps: - - name: 'Checkout Repository' + - name: "Checkout Repository" uses: actions/checkout@v4 - - name: 'Dependency Review' - uses: actions/dependency-review-action@v2 + - name: "Dependency Review" + uses: actions/dependency-review-action@v3 diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 5595e4e10..2bd76a50a 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -4,9 +4,9 @@ on: pull_request: types: [opened, edited, synchronize, reopened] branches-ignore: - - 'dependabot/**' - - 'release/**' - - 'main' + - "dependabot/**" + - "release/**" + - "main" permissions: contents: read diff --git a/.github/workflows/update-pull-request-description.yml b/.github/workflows/update-pull-request-description.yml index 759159f4c..08bfeb2cf 100644 --- a/.github/workflows/update-pull-request-description.yml +++ b/.github/workflows/update-pull-request-description.yml @@ -4,7 +4,7 @@ on: pull_request: types: [opened] branches-ignore: - - 'dependabot/**' + - "dependabot/**" permissions: contents: read @@ -38,6 +38,6 @@ jobs: - uses: tzkhan/pr-update-action@v2 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" - head-branch-regex: '${{ env.BRANCH_DESIGNATOR }}/.*' + head-branch-regex: "${{ env.BRANCH_DESIGNATOR }}/.*" body-template: ${{ steps.template.outputs.result }} - body-update-action: 'replace' + body-update-action: "replace" diff --git a/Makefile b/Makefile index ccc8a7a9f..d6cf6ccfa 100644 --- a/Makefile +++ b/Makefile @@ -106,6 +106,7 @@ UNIT_TEST_ARGS=" \ -e POWERTOOLS_LOG_DEDUPLICATION_DISABLED="1" \ --volume $(APPLICATION_DIR)/common:/tmp/.packages/common \ --volume $(APPLICATION_DIR)/change_event_dlq_handler:/tmp/.packages/change_event_dlq_handler \ + --volume $(APPLICATION_DIR)/dos_db_handler:/tmp/.packages/dos_db_handler \ --volume $(APPLICATION_DIR)/dos_db_update_dlq_handler:/tmp/.packages/dos_db_update_dlq_handler \ --volume $(APPLICATION_DIR)/event_replay:/tmp/.packages/event_replay \ --volume $(APPLICATION_DIR)/ingest_change_event:/tmp/.packages/ingest_change_event \ @@ -113,6 +114,7 @@ UNIT_TEST_ARGS=" \ --volume $(APPLICATION_DIR)/service_matcher:/tmp/.packages/service_matcher \ --volume $(APPLICATION_DIR)/service_sync:/tmp/.packages/service_sync \ --volume $(APPLICATION_DIR)/slack_messenger:/tmp/.packages/slack_messenger \ + --volume $(APPLICATION_DIR)/quality_checker:/tmp/.packages/quality_checker \ " integration-test-autoflags-no-logs: # End to end test DI project - mandatory: PROFILE; optional: ENVIRONMENT, PARALLEL_TEST_COUNT @@ -169,58 +171,64 @@ remove-development-environments: # Removes development environments - mandatory: done # ============================================================================== -# Service Sync +# Change Event Dead Letter Queue Handler (change-event-dlq-handler) -service-sync-build-and-deploy: ### Build and deploy service sync lambda docker image - mandatory: PROFILE, ENVIRONMENT, FUNCTION_NAME - make build-and-deploy-single-function FUNCTION_NAME=service-sync +change-event-dlq-handler-build-and-deploy: ### Build and deploy change event dlq handler lambda docker image - mandatory: PROFILE, ENVIRONMENT + make build-and-deploy-single-function FUNCTION_NAME=change-event-dlq-handler # ============================================================================== -# Slack Messenger +# DoS DB Update Dead Letter Queue Handler (dos-db-update-dlq-handler) -slack-messenger-build-and-deploy: ### Build and deploy slack messenger lambda docker image - mandatory: PROFILE, ENVIRONMENT, FUNCTION_NAME - make build-and-deploy-single-function FUNCTION_NAME=slack-messenger +dos-db-update-dlq-handler-build-and-deploy: ### Build and deploy dos db update dlq handler lambda docker image - mandatory: PROFILE, ENVIRONMENT + make build-and-deploy-single-function FUNCTION_NAME=dos-db-update-dlq-handler # ============================================================================== -# Service Matcher +# DoS DB Checker Handler (dos-db-handler) -service-matcher-build-and-deploy: ### Build and deploy service matcher lambda docker image - mandatory: PROFILE, ENVIRONMENT, FUNCTION_NAME - make build-and-deploy-single-function FUNCTION_NAME=service-matcher +dos-db-handler-build-and-deploy: ### Build and deploy test db checker handler lambda docker image - mandatory: PROFILE, ENVIRONMENT + make build-and-deploy-single-function FUNCTION_NAME=dos-db-handler # ============================================================================== -# Change Event Dead Letter Queue Handler (change-event-dlq-handler) +# Event Replay lambda (event-replay) -change-event-dlq-handler-build-and-deploy: ### Build and deploy change event dlq handler lambda docker image - mandatory: PROFILE, ENVIRONMENT, FUNCTION_NAME - make build-and-deploy-single-function FUNCTION_NAME=change-event-dlq-handler +event-replay-build-and-deploy: ### Build and deploy event replay lambda docker image - mandatory: PROFILE, ENVIRONMENT + make build-and-deploy-single-function FUNCTION_NAME=event-replay # ============================================================================== -# DoS DB Update Dead Letter Queue Handler (dos-db-update-dlq-handler) Nonprod only +# Ingest Change Event -dos-db-update-dlq-handler-build-and-deploy: ### Build and deploy dos db update dlq handler lambda docker image - mandatory: PROFILE, ENVIRONMENT, FUNCTION_NAME - make build-and-deploy-single-function FUNCTION_NAME=dos-db-update-dlq-handler +ingest-change-event-build-and-deploy: ### Build and deploy ingest change event lambda docker image - mandatory: PROFILE, ENVIRONMENT + make build-and-deploy-single-function FUNCTION_NAME=ingest-change-event # ============================================================================== -# Event Replay lambda (event-replay) +# Send Email -event-replay-build-and-deploy: ### Build and deploy event replay lambda docker image - mandatory: PROFILE, ENVIRONMENT, FUNCTION_NAME - make build-and-deploy-single-function FUNCTION_NAME=event-replay +send-email-build-and-deploy: ### Build and deploy send email lambda docker image - mandatory: PROFILE, ENVIRONMENT + make build-and-deploy-single-function FUNCTION_NAME=send-email # ============================================================================== -# DoS DB Checker Handler (dos-db-handler) +# Service Matcher -dos-db-handler-build-and-deploy: ### Build and deploy test db checker handler lambda docker image - mandatory: PROFILE, ENVIRONMENT, FUNCTION_NAME - make build-and-deploy-single-function FUNCTION_NAME=dos-db-handler +service-matcher-build-and-deploy: ### Build and deploy service matcher lambda docker image - mandatory: PROFILE, ENVIRONMENT + make build-and-deploy-single-function FUNCTION_NAME=service-matcher # ============================================================================== -# Send Email +# Service Sync -send-email-build-and-deploy: ### Build and deploy send email lambda docker image - mandatory: PROFILE, ENVIRONMENT, FUNCTION_NAME - make build-and-deploy-single-function FUNCTION_NAME=send-email +service-sync-build-and-deploy: ### Build and deploy service sync lambda docker image - mandatory: PROFILE, ENVIRONMENT + make build-and-deploy-single-function FUNCTION_NAME=service-sync # ============================================================================== -# Ingest Change Event +# Slack Messenger -ingest-change-event-build-and-deploy: ### Build and deploy ingest change event lambda docker image - mandatory: PROFILE, ENVIRONMENT, FUNCTION_NAME - make build-and-deploy-single-function FUNCTION_NAME=ingest-change-event +slack-messenger-build-and-deploy: ### Build and deploy slack messenger lambda docker image - mandatory: PROFILE, ENVIRONMENT + make build-and-deploy-single-function FUNCTION_NAME=slack-messenger + +# ============================================================================== +# Quality Checker + +quality-checker-build-and-deploy: ### Build and deploy quality checker lambda docker image - mandatory: PROFILE, ENVIRONMENT + make build-and-deploy-single-function FUNCTION_NAME=quality-checker # ============================================================================== # Deployments @@ -250,15 +258,6 @@ push-images: # Use VERSION=[] to push a perticular version otherwise with defaul push-tester-image: make docker-push NAME=tester -# ============================================================================== -# SES (Simple Email Service) - -deploy-email: # Deploys SES resources - mandatory: PROFILE=[live/test] - make terraform-apply-auto-approve STACKS=email ENVIRONMENT=$(AWS_ACCOUNT_NAME) - -undeploy-email: # Deploys SES resources - mandatory: PROFILE=[live/test] - make terraform-destroy-auto-approve STACKS=email ENVIRONMENT=$(AWS_ACCOUNT_NAME) - # ============================================================================== # Development Tools @@ -399,29 +398,6 @@ performance-test-clean: # Clean up performance test results rm -f $(TMP_DIR)/*.zip rm -rf $(PROJECT_DIR)/test/performance/results/*.csv -stress-test-in-pipeline: # An all in one stress test make target - START_TIME=$$(date +%Y-%m-%d_%H-%M-%S) - AWS_START_TIME=$$(date +%FT%TZ) - CODE_VERSION=$$($(AWSCLI) lambda get-function --function-name $(TF_VAR_service_matcher_lambda_name) | jq --raw-output '.Configuration.Environment.Variables.CODE_VERSION') - make stress-test START_TIME=$$START_TIME PIPELINE=true - sleep 4.5h - END_TIME=$$(date +%Y-%m-%d_%H-%M-%S) - AWS_END_TIME=$$(date +%FT%TZ) - make send-performance-dashboard-slack-message START_DATE_TIME=$$AWS_START_TIME END_DATE_TIME=$$AWS_END_TIME - -load-test-in-pipeline: # An all in one load test make target - START_TIME=$$(date +%Y-%m-%d_%H-%M-%S) - AWS_START_TIME=$$(date +%FT%TZ) - CODE_VERSION=$$($(AWSCLI) lambda get-function --function-name $(TF_VAR_service_matcher_lambda_name) | jq --raw-output '.Configuration.Environment.Variables.CODE_VERSION') - make load-test START_TIME=$$START_TIME - sleep 10m - END_TIME=$$(date +%Y-%m-%d_%H-%M-%S) - AWS_END_TIME=$$(date +%FT%TZ) - make send-performance-dashboard-slack-message START_DATE_TIME=$$AWS_START_TIME END_DATE_TIME=$$AWS_END_TIME - -send-performance-dashboard-slack-message: - make slack-codebuild-notification PROFILE=$(PROFILE) ENVIRONMENT=$(ENVIRONMENT) PIPELINE_NAME="$(PERF_TEST_TITLE) Tests Codebuild Stage" CODEBUILD_PROJECT_NAME=$(CB_PROJECT_NAME) CODEBUILD_BUILD_ID=$(CODEBUILD_BUILD_ID) SLACK_MESSAGE="Performance Dashboard Here - https://$(AWS_REGION).console.aws.amazon.com/cloudwatch/home?region=$(AWS_REGION)#dashboards:name=$(TF_VAR_cloudwatch_monitoring_dashboard_name);start=$(START_DATE_TIME);end=$(END_DATE_TIME)" - # ----------------------------- # Other diff --git a/application/change_event_dlq_handler/requirements.txt b/application/change_event_dlq_handler/requirements.txt index 53279d4a2..99d5a7726 100644 --- a/application/change_event_dlq_handler/requirements.txt +++ b/application/change_event_dlq_handler/requirements.txt @@ -1,2 +1,2 @@ aws-embedded-metrics -aws-lambda-powertools[tracer] ~= 2.2.0 +aws-lambda-powertools[tracer] ~= 2.24.0 diff --git a/application/common/service_type.py b/application/common/service_type.py index 7954ba6c4..74687a7ba 100644 --- a/application/common/service_type.py +++ b/application/common/service_type.py @@ -9,8 +9,13 @@ DOS_CONTRACEPTION_SYMPTOM_DISCRIMINATOR, DOS_CONTRACEPTION_SYMPTOM_GROUP, DOS_CONTRACEPTION_TYPE_ID, + DOS_PALLIATIVE_CARE_SGSDID, + DOS_PALLIATIVE_CARE_SYMPTOM_DISCRIMINATOR, + DOS_PALLIATIVE_CARE_SYMPTOM_GROUP, + DOS_PALLIATIVE_CARE_TYPE_ID, NHS_UK_BLOOD_PRESSURE_SERVICE_CODE, NHS_UK_CONTRACEPTION_SERVICE_CODE, + NHS_UK_PALLIATIVE_CARE_SERVICE_CODE, ) @@ -25,6 +30,29 @@ class ServiceType: DOS_SYMPTOM_DISCRIMINATOR: int DOS_SG_SD_ID: str + def __eq__(self, __value: object) -> bool: + """Check if the ServiceType is equal to another ServiceType.""" + try: + return ( + self.TYPE_NAME == __value.TYPE_NAME + and self.NHS_UK_SERVICE_CODE == __value.NHS_UK_SERVICE_CODE + and self.DOS_TYPE_ID == __value.DOS_TYPE_ID + and self.DOS_SYMPTOM_GROUP == __value.DOS_SYMPTOM_GROUP + and self.DOS_SYMPTOM_DISCRIMINATOR == __value.DOS_SYMPTOM_DISCRIMINATOR + and self.DOS_SG_SD_ID == __value.DOS_SG_SD_ID + ) + except AttributeError: + return False + + +PALLIATIVE_CARE = ServiceType( + TYPE_NAME="Palliative Care", + NHS_UK_SERVICE_CODE=NHS_UK_PALLIATIVE_CARE_SERVICE_CODE, + DOS_TYPE_ID=DOS_PALLIATIVE_CARE_TYPE_ID, + DOS_SYMPTOM_GROUP=DOS_PALLIATIVE_CARE_SYMPTOM_GROUP, + DOS_SYMPTOM_DISCRIMINATOR=DOS_PALLIATIVE_CARE_SYMPTOM_DISCRIMINATOR, + DOS_SG_SD_ID=DOS_PALLIATIVE_CARE_SGSDID, +) BLOOD_PRESSURE = ServiceType( TYPE_NAME="Blood Pressure", diff --git a/application/common/tests/test_service_type.py b/application/common/tests/test_service_type.py index ffd251052..523cd98df 100644 --- a/application/common/tests/test_service_type.py +++ b/application/common/tests/test_service_type.py @@ -11,6 +11,11 @@ from application.common.service_type import BLOOD_PRESSURE, CONTRACEPTION +def test_service_type__eq__(): + assert BLOOD_PRESSURE == BLOOD_PRESSURE # noqa: PLR0124 + assert BLOOD_PRESSURE != CONTRACEPTION + + def test_blood_pressure_service_type(): assert BLOOD_PRESSURE.TYPE_NAME == "Blood Pressure" assert BLOOD_PRESSURE.NHS_UK_SERVICE_CODE == "SRV0560" diff --git a/application/dos_db_handler/requirements.txt b/application/dos_db_handler/requirements.txt index f70e38b6b..ed7afe662 100644 --- a/application/dos_db_handler/requirements.txt +++ b/application/dos_db_handler/requirements.txt @@ -1,3 +1,3 @@ aws-embedded-metrics -aws-lambda-powertools[tracer] ~= 2.2.0 +aws-lambda-powertools[tracer] ~= 2.24.0 psycopg[binary] diff --git a/application/dos_db_update_dlq_handler/requirements.txt b/application/dos_db_update_dlq_handler/requirements.txt index 53279d4a2..99d5a7726 100644 --- a/application/dos_db_update_dlq_handler/requirements.txt +++ b/application/dos_db_update_dlq_handler/requirements.txt @@ -1,2 +1,2 @@ aws-embedded-metrics -aws-lambda-powertools[tracer] ~= 2.2.0 +aws-lambda-powertools[tracer] ~= 2.24.0 diff --git a/application/event_replay/requirements.txt b/application/event_replay/requirements.txt index 2a609bff6..a0972f81f 100644 --- a/application/event_replay/requirements.txt +++ b/application/event_replay/requirements.txt @@ -1,3 +1,3 @@ aws-embedded-metrics -aws-lambda-powertools[tracer] ~= 2.2.0 +aws-lambda-powertools[tracer] ~= 2.24.0 simplejson diff --git a/application/ingest_change_event/requirements.txt b/application/ingest_change_event/requirements.txt index a0492145a..d22c93c74 100644 --- a/application/ingest_change_event/requirements.txt +++ b/application/ingest_change_event/requirements.txt @@ -1,2 +1,2 @@ aws-embedded-metrics -aws-lambda-powertools[tracer, validation] ~= 2.2.0 +aws-lambda-powertools[tracer, validation] ~= 2.24.0 diff --git a/application/pyproject.toml b/application/pyproject.toml index 428453983..a44b9ea9f 100644 --- a/application/pyproject.toml +++ b/application/pyproject.toml @@ -1,9 +1,7 @@ [tool.vulture] make_whitelist = true -paths=["."] -exclude = [ - "/tests", - ] +paths = ["."] +exclude = ["/tests"] sort_by_size = true min_confidence = 100 ignore_names = [ @@ -16,4 +14,4 @@ ignore_names = [ "metadata", "recipient_email_address", "recipient_id", - ] +] diff --git a/application/quality_checker/__init__.py b/application/quality_checker/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/application/quality_checker/check_dos.py b/application/quality_checker/check_dos.py new file mode 100644 index 000000000..bf00ff951 --- /dev/null +++ b/application/quality_checker/check_dos.py @@ -0,0 +1,61 @@ +from aws_lambda_powertools.logging import Logger +from psycopg import Connection + +from .reporting import log_to_quality_check_report +from .search_dos import ( + search_for_incorrectly_profiled_z_code, + search_for_matching_services, + search_for_pharmacy_ods_codes, +) +from common.dos import DoSService +from common.service_type import BLOOD_PRESSURE, CONTRACEPTION, ServiceType + +logger = Logger(child=True) + + +def check_pharmacy_profiling(connection: Connection) -> None: + """Check the pharmacy profiling data quality of the dos database. + + Args: + connection (Connection): Connection to the DoS DB. + """ + odscodes = search_for_pharmacy_ods_codes(connection) + for odscode in odscodes: + matched_services = search_for_matching_services(connection, odscode) + check_for_multiple_of_service_type(matched_services, BLOOD_PRESSURE) + check_for_multiple_of_service_type(matched_services, CONTRACEPTION) + + +def check_incorrect_zcode_profiling(connection: Connection, service_type: ServiceType) -> None: + """Check the palliative care profiling data quality of the dos database. + + Args: + connection (Connection): Connection to the DoS DB. + service_type (ServiceType): Service type to check for. + """ + if incorrectly_profiled_services := search_for_incorrectly_profiled_z_code(connection, service_type): + logger.info( + f"Found {len(incorrectly_profiled_services)} incorrectly " + f"profiled {service_type.TYPE_NAME.lower()} services.", + services=incorrectly_profiled_services, + ) + log_to_quality_check_report( + incorrectly_profiled_services, + f"{service_type.TYPE_NAME} ZCode is on invalid service type", + service_type.DOS_SG_SD_ID, + ) + + +def check_for_multiple_of_service_type(matched_services: list[DoSService], service_type: ServiceType) -> None: + """Check for multiple of service type. + + Args: + matched_services (list[DoSService]): List of matched services. + service_type (ServiceType): Service type to check for. + """ + matched_service_types = [service for service in matched_services if service.typeid == service_type.DOS_TYPE_ID] + if len(matched_service_types) > 1: + log_to_quality_check_report( + matched_service_types, + f"Multiple 'Pharmacy' type services found (type {service_type.DOS_TYPE_ID})", + ) diff --git a/application/quality_checker/quality_checker.py b/application/quality_checker/quality_checker.py new file mode 100644 index 000000000..6e7ed098d --- /dev/null +++ b/application/quality_checker/quality_checker.py @@ -0,0 +1,75 @@ +from os import environ +from typing import Any + +from aws_embedded_metrics import metric_scope +from aws_lambda_powertools.logging import Logger +from aws_lambda_powertools.tracing import Tracer +from aws_lambda_powertools.utilities.data_classes import EventBridgeEvent, event_source +from aws_lambda_powertools.utilities.typing.lambda_context import LambdaContext + +from .check_dos import ( + check_incorrect_zcode_profiling, + check_pharmacy_profiling, +) +from common.dos_db_connection import connect_to_dos_db_replica +from common.middlewares import unhandled_exception_logging +from common.service_type import BLOOD_PRESSURE, CONTRACEPTION, PALLIATIVE_CARE + +logger = Logger() +tracer = Tracer() + + +@tracer.capture_lambda_handler() +@logger.inject_lambda_context(clear_state=True) +@unhandled_exception_logging +@event_source(data_class=EventBridgeEvent) +def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> None: # noqa: ARG001 + """Lambda handler for quality checker.""" + try: + logger.debug("Quality checker started.") + check_dos_data_quality() + logger.debug("Quality checker finished.") + send_finished_metric() + except Exception: + send_errored_metric() + raise + + +def check_dos_data_quality() -> None: + """Check the data quality of the dos database.""" + with connect_to_dos_db_replica() as db_connection: + # Checks matched odscode services for pharmacy profiling + check_pharmacy_profiling(db_connection) + + # Checks matched odscode services for incorrectly profiled palliative care + check_incorrect_zcode_profiling(db_connection, PALLIATIVE_CARE) + + # Checks matched odscode services for incorrectly profiled blood pressure + check_incorrect_zcode_profiling(db_connection, BLOOD_PRESSURE) + + # Checks matched odscode services for incorrectly profiled contraception + check_incorrect_zcode_profiling(db_connection, CONTRACEPTION) + + +@metric_scope +def send_finished_metric(metrics: Any) -> None: # noqa: ANN401 + """Send a metric to indicate that the quality checker has finished. + + Args: + metrics (Metrics): CloudWatch embedded metrics object + """ + metrics.set_namespace("UEC-DOS-INT") + metrics.set_dimensions({"ENV": environ["ENV"]}) + metrics.put_metric("QualityCheckerFinished", 1, "Count") + + +@metric_scope +def send_errored_metric(metrics: Any) -> None: # noqa: ANN401 + """Send a metric to indicate that the quality checker has errored. + + Args: + metrics (Metrics): CloudWatch embedded metrics object + """ + metrics.set_namespace("UEC-DOS-INT") + metrics.set_dimensions({"ENV": environ["ENV"]}) + metrics.put_metric("QualityCheckerErrored", 1, "Count") diff --git a/application/quality_checker/reporting.py b/application/quality_checker/reporting.py new file mode 100644 index 000000000..d1950d10e --- /dev/null +++ b/application/quality_checker/reporting.py @@ -0,0 +1,36 @@ +from aws_lambda_powertools.logging import Logger + +from common.dos import DoSService + +QUALITY_CHECK_REPORT_KEY = "QUALITY_CHECK_REPORT_KEY" + +logger = Logger(child=True) + + +def log_to_quality_check_report( + matched_services: list[DoSService], + reason: str, + z_code: str = "", +) -> None: + """Log a service to the quality check report. + + Args: + matched_services (list[DoSService]): The DoS service to report + reason (str): The reason for the report + z_code (str): The z-code for the report + """ + for service in matched_services: + logger.warning( + reason, + extra={ + "report_key": QUALITY_CHECK_REPORT_KEY, + "dos_service_uid": service.uid, + "dos_service_odscode": service.odscode, + "dos_service_name": service.name, + "dos_service_type_name": service.service_type_name, + "dos_service_type_id": service.typeid, + "dos_region": service.get_region(), + "z-code": z_code, + "reason": reason, + }, + ) diff --git a/application/quality_checker/requirements.txt b/application/quality_checker/requirements.txt new file mode 100644 index 000000000..854595d4e --- /dev/null +++ b/application/quality_checker/requirements.txt @@ -0,0 +1,3 @@ +aws-embedded-metrics +aws-lambda-powertools[tracer, validation] ~= 2.24.0 +psycopg[binary] diff --git a/application/quality_checker/search_dos.py b/application/quality_checker/search_dos.py new file mode 100644 index 000000000..89d677b75 --- /dev/null +++ b/application/quality_checker/search_dos.py @@ -0,0 +1,89 @@ +from aws_lambda_powertools.logging import Logger +from psycopg import Connection + +from common.constants import DOS_ACTIVE_STATUS_ID, PHARMACY_SERVICE_TYPE_IDS +from common.dos import DoSService +from common.dos_db_connection import query_dos_db +from common.service_type import ServiceType + +logger = Logger(child=True) + + +def search_for_pharmacy_ods_codes(connection: Connection) -> list[str]: + """Search for pharmacy ODS codes in DoS DB. + + Args: + connection (Connection): Connection to the DoS DB. + + Returns: + list[str]: List of pharmacy ODS codes. + """ + cursor = query_dos_db( + connection, + "SELECT LEFT(odscode, 5) FROM services s WHERE s.typeid = ANY(%(PHARMACY_SERVICE_TYPE_IDS)s) " + "AND s.statusid = %(ACTIVE_STATUS_ID)s AND LEFT(REPLACE(TRIM(odscode), CHR(9), ''), 1) IN ('F', 'f')", + {"PHARMACY_SERVICE_TYPE_IDS": PHARMACY_SERVICE_TYPE_IDS, "ACTIVE_STATUS_ID": DOS_ACTIVE_STATUS_ID}, + ) + odscodes = [odscode_row["left"] for odscode_row in cursor.fetchall()] + cursor.close() + logger.debug(f"Found {len(odscodes)} pharmacy ODS codes.", odscodes=odscodes) + return odscodes + + +def search_for_matching_services(connection: Connection, odscode: str) -> list[DoSService]: + """Search for matching services in DoS DB using odscode. + + Args: + connection (Connection): Connection to the DoS DB. + odscode (str): Search for matching services using this odscode. + + Returns: + list[DoSService]: List of matching services. + """ + cursor = query_dos_db( + connection, + "SELECT s.id, uid, s.name, odscode, address, postcode, web, typeid," + "statusid, ss.name status_name, publicphone, publicname, st.name service_type_name " + "FROM services s LEFT JOIN servicetypes st ON s.typeid = st.id " + "LEFT JOIN servicestatuses ss on s.statusid = ss.id " + "WHERE s.odscode LIKE %(ODSCODE)s AND s.statusid = %(ACTIVE_STATUS_ID)s", + {"ODSCODE": odscode, "ACTIVE_STATUS_ID": DOS_ACTIVE_STATUS_ID}, + ) + services = [DoSService(row) for row in cursor.fetchall()] + cursor.close() + logger.info(f"Found {len(services)} active matching services.", services=services) + return services + + +def search_for_incorrectly_profiled_z_code(connection: Connection, service_type: ServiceType) -> list[DoSService]: + """Search for matching services in DoS DB using odscode. + + Args: + connection (Connection): Connection to the DoS DB. + service_type (ServiceType): Service type to check for. + + Returns: + list[DoSService]: List of matching services. + """ + matchable_service_types = PHARMACY_SERVICE_TYPE_IDS.copy() + matchable_service_types.remove(service_type.DOS_TYPE_ID) + cursor = query_dos_db( + connection, + "SELECT s.id, uid, s.name, odscode, address, postcode, web, typeid, statusid, ss.name status_name, " + "publicphone, publicname, st.name service_type_name " + "FROM services s LEFT JOIN servicetypes st ON s.typeid = st.id " + "LEFT JOIN servicestatuses ss on s.statusid = ss.id " + "LEFT JOIN servicesgsds sgsds on s.id = sgsds.serviceid " + "WHERE sgsds.sgid = %(SYMPTOM_GROUP)s AND sgsds.sdid = %(SYMPTOM_DISCRIMINATOR)s " + "AND s.statusid = %(ACTIVE_STATUS_ID)s AND s.typeid = ANY(%(SERVICE_TYPE_IDS)s)", + { + "ACTIVE_STATUS_ID": DOS_ACTIVE_STATUS_ID, + "SERVICE_TYPE_IDS": matchable_service_types, + "SYMPTOM_GROUP": service_type.DOS_SYMPTOM_GROUP, + "SYMPTOM_DISCRIMINATOR": service_type.DOS_SYMPTOM_DISCRIMINATOR, + }, + ) + services = [DoSService(row) for row in cursor.fetchall()] + cursor.close() + logger.info(f"Found {len(services)} active offending services.", services=services) + return services diff --git a/application/quality_checker/tests/__init__.py b/application/quality_checker/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/application/quality_checker/tests/test_check_dos.py b/application/quality_checker/tests/test_check_dos.py new file mode 100644 index 000000000..7cdbd138c --- /dev/null +++ b/application/quality_checker/tests/test_check_dos.py @@ -0,0 +1,106 @@ +from unittest.mock import MagicMock, call, patch + +from application.common.service_type import BLOOD_PRESSURE, CONTRACEPTION +from application.quality_checker.check_dos import ( + check_for_multiple_of_service_type, + check_incorrect_zcode_profiling, + check_pharmacy_profiling, +) + +FILE_PATH = "application.quality_checker.check_dos" + + +@patch(f"{FILE_PATH}.check_for_multiple_of_service_type") +@patch(f"{FILE_PATH}.search_for_matching_services") +@patch(f"{FILE_PATH}.search_for_pharmacy_ods_codes") +def test_check_pharmacy_profiling( + mock_search_for_pharmacy_ods_codes: MagicMock, + mock_search_for_matching_services: MagicMock, + mock_check_for_multiple_of_service_type: MagicMock, +) -> None: + # Arrange + connection = MagicMock() + odscode = "ABC123" + mock_search_for_pharmacy_ods_codes.return_value = [odscode] + # Act + check_pharmacy_profiling(connection) + # Assert + mock_search_for_pharmacy_ods_codes.assert_called_once_with(connection) + mock_search_for_matching_services.assert_called_once_with(connection, odscode) + mock_check_for_multiple_of_service_type.assert_has_calls( + calls=[ + call(mock_search_for_matching_services.return_value, BLOOD_PRESSURE), + call(mock_search_for_matching_services.return_value, CONTRACEPTION), + ], + ) + + +@patch(f"{FILE_PATH}.log_to_quality_check_report") +@patch(f"{FILE_PATH}.search_for_incorrectly_profiled_z_code") +def test_check_incorrect_zcode_profiling( + mock_search_for_incorrectly_profiled_z_code: MagicMock, + mock_log_to_quality_check_report: MagicMock, +) -> None: + # Arrange + connection = MagicMock() + service = MagicMock() + matched_services = [service] + mock_search_for_incorrectly_profiled_z_code.return_value = matched_services + # Act + check_incorrect_zcode_profiling(connection, BLOOD_PRESSURE) + # Assert + mock_search_for_incorrectly_profiled_z_code.assert_called_once_with(connection, BLOOD_PRESSURE) + mock_log_to_quality_check_report.assert_called_once_with( + matched_services, + "Blood Pressure ZCode is on invalid service type", + BLOOD_PRESSURE.DOS_SG_SD_ID, + ) + + +@patch(f"{FILE_PATH}.log_to_quality_check_report") +@patch(f"{FILE_PATH}.search_for_incorrectly_profiled_z_code") +def test_check_incorrect_zcode_profiling_no_matches( + mock_search_for_incorrectly_profiled_z_code: MagicMock, + mock_log_to_quality_check_report: MagicMock, +) -> None: + # Arrange + connection = MagicMock() + matched_services = [] + mock_search_for_incorrectly_profiled_z_code.return_value = matched_services + # Act + check_incorrect_zcode_profiling(connection, BLOOD_PRESSURE) + # Assert + mock_search_for_incorrectly_profiled_z_code.assert_called_once_with(connection, BLOOD_PRESSURE) + mock_log_to_quality_check_report.assert_not_called() + + +@patch(f"{FILE_PATH}.log_to_quality_check_report") +def test_check_for_multiple_of_service_type(mock_log_to_quality_check_report: MagicMock) -> None: + # Arrange + to_be_matched_services = [ + MagicMock(typeid=BLOOD_PRESSURE.DOS_TYPE_ID), + MagicMock(typeid=BLOOD_PRESSURE.DOS_TYPE_ID), + ] + not_to_be_matched_services = [ + MagicMock(typeid=CONTRACEPTION.DOS_TYPE_ID), + ] + matched_services = to_be_matched_services + not_to_be_matched_services + # Act + check_for_multiple_of_service_type(matched_services, BLOOD_PRESSURE) + # Assert + mock_log_to_quality_check_report.assert_called_once_with( + to_be_matched_services, + "Multiple 'Pharmacy' type services found (type 148)", + ) + + +@patch(f"{FILE_PATH}.log_to_quality_check_report") +def test_check_for_multiple_of_service_type_no_matches(mock_log_to_quality_check_report: MagicMock) -> None: + # Arrange + not_to_be_matched_services = [ + MagicMock(typeid=CONTRACEPTION.DOS_TYPE_ID), + ] + # Act + check_for_multiple_of_service_type(not_to_be_matched_services, BLOOD_PRESSURE) + # Assert + mock_log_to_quality_check_report.assert_not_called() diff --git a/application/quality_checker/tests/test_quality_checker.py b/application/quality_checker/tests/test_quality_checker.py new file mode 100644 index 000000000..1656e7b36 --- /dev/null +++ b/application/quality_checker/tests/test_quality_checker.py @@ -0,0 +1,62 @@ +from dataclasses import dataclass +from unittest.mock import MagicMock, call, patch + +import pytest +from aws_lambda_powertools.utilities.typing import LambdaContext + +from application.common.service_type import BLOOD_PRESSURE, CONTRACEPTION, PALLIATIVE_CARE +from application.quality_checker.quality_checker import check_dos_data_quality, lambda_handler + +FILE_PATH = "application.quality_checker.quality_checker" + + +@pytest.fixture() +def lambda_context(): + @dataclass + class LambdaContext: + """Mock LambdaContext - All dummy values.""" + + function_name: str = "quality-checker" + memory_limit_in_mb: int = 128 + invoked_function_arn: str = "arn:aws:lambda:eu-west-1:000000000:function:quality-checker" + aws_request_id: str = "52fdfc07-2182-154f-163f-5f0f9a621d72" + + return LambdaContext() + + +@patch(f"{FILE_PATH}.check_dos_data_quality") +def test_lambda_handler( + mock_check_dos_data_quality: MagicMock, + lambda_context: LambdaContext, +) -> None: + # Arrange + event = {} + # Act + lambda_handler(event, lambda_context) + # Assert + mock_check_dos_data_quality.assert_called_once_with() + + +@patch(f"{FILE_PATH}.check_incorrect_zcode_profiling") +@patch(f"{FILE_PATH}.check_pharmacy_profiling") +@patch(f"{FILE_PATH}.connect_to_dos_db_replica") +def test_check_dos_data_quality( + mock_connect_to_dos_db_replica: MagicMock, + mock_check_pharmacy_profiling: MagicMock, + mock_check_incorrect_zcode_profiling: MagicMock, +) -> None: + # Arrange + # Act + check_dos_data_quality() + # Assert + mock_connect_to_dos_db_replica.assert_called_once_with() + mock_check_pharmacy_profiling.assert_called_once_with( + mock_connect_to_dos_db_replica().__enter__(), + ) + mock_check_incorrect_zcode_profiling.assert_has_calls( + calls=[ + call(mock_connect_to_dos_db_replica().__enter__(), PALLIATIVE_CARE), + call(mock_connect_to_dos_db_replica().__enter__(), BLOOD_PRESSURE), + call(mock_connect_to_dos_db_replica().__enter__(), CONTRACEPTION), + ], + ) diff --git a/application/quality_checker/tests/test_reporting.py b/application/quality_checker/tests/test_reporting.py new file mode 100644 index 000000000..dfc2822c0 --- /dev/null +++ b/application/quality_checker/tests/test_reporting.py @@ -0,0 +1,34 @@ +from unittest.mock import MagicMock, patch + +from aws_lambda_powertools.logging import Logger + +from application.quality_checker.reporting import log_to_quality_check_report + +FILE_PATH = "application.quality_checker.reporting" + + +@patch.object(Logger, "warning") +def test_log_to_quality_check_report(mock_warning_logger: MagicMock): + # Arrange + dos_service = MagicMock() + matched_services = [ + dos_service, + ] + reason = "reason" + # Act + log_to_quality_check_report(matched_services, reason) + # Assert + mock_warning_logger.assert_called_once_with( + reason, + extra={ + "report_key": "QUALITY_CHECK_REPORT_KEY", + "dos_service_uid": dos_service.uid, + "dos_service_odscode": dos_service.odscode, + "dos_service_name": dos_service.name, + "dos_service_type_name": dos_service.service_type_name, + "dos_service_type_id": dos_service.typeid, + "dos_region": dos_service.get_region(), + "z-code": "", + "reason": reason, + }, + ) diff --git a/application/quality_checker/tests/test_search_dos.py b/application/quality_checker/tests/test_search_dos.py new file mode 100644 index 000000000..8e5804231 --- /dev/null +++ b/application/quality_checker/tests/test_search_dos.py @@ -0,0 +1,114 @@ +from datetime import UTC, datetime +from typing import Any +from unittest.mock import MagicMock, patch + +from application.quality_checker.search_dos import ( + search_for_incorrectly_profiled_z_code, + search_for_matching_services, + search_for_pharmacy_ods_codes, +) +from common.constants import DOS_ACTIVE_STATUS_ID, PHARMACY_SERVICE_TYPE_IDS +from common.dos import DoSService +from common.service_type import BLOOD_PRESSURE + +FILE_PATH = "application.quality_checker.search_dos" + + +@patch(f"{FILE_PATH}.query_dos_db") +def test_search_for_pharmacy_ods_codes(mock_query_dos_db: MagicMock) -> None: + # Arrange + connection = MagicMock() + odscode = "ABC123" + mock_query_dos_db.return_value.fetchall.return_value = [{"left": odscode}] + # Act + response = search_for_pharmacy_ods_codes(connection) + # Assert + assert response == [odscode] + mock_query_dos_db.assert_called_once_with( + connection, + "SELECT LEFT(odscode, 5) FROM services s WHERE s.typeid = ANY(%(PHARMACY_SERVICE_TYPE_IDS)s) " + "AND s.statusid = %(ACTIVE_STATUS_ID)s AND LEFT(REPLACE(TRIM(odscode), CHR(9), ''), 1) IN ('F', 'f')", + {"PHARMACY_SERVICE_TYPE_IDS": PHARMACY_SERVICE_TYPE_IDS, "ACTIVE_STATUS_ID": DOS_ACTIVE_STATUS_ID}, + ) + + +def get_service_data() -> dict[str, Any]: + return { + "id": 9999, + "uid": "159514725", + "name": "fake name", + "odscode": "FA9321", + "address": "80 Street$Town", + "town": "Town", + "postcode": "TES T12", + "web": None, + "email": None, + "fax": None, + "nonpublicphone": None, + "typeid": 13, + "parentid": 123486, + "subregionid": 21813557, + "statusid": 1, + "createdtime": datetime(2011, 8, 24, 9, 17, 24, tzinfo=UTC), + "modifiedtime": datetime(2019, 3, 13, 0, 37, 7, tzinfo=UTC), + "publicphone": "0123 012 012", + "publicname": None, + "service_type_name": "my service", + "status_name": "Active", + "easting": "123456", + "northing": "123456", + "latitude": "123456", + "longitude": "123456", + } + + +@patch(f"{FILE_PATH}.query_dos_db") +def test_search_for_matching_services(mock_query_dos_db: MagicMock) -> None: + # Arrange + connection = MagicMock() + odscode = "ABC12" + service = get_service_data() + dos_service = DoSService(service) + mock_query_dos_db.return_value.fetchall.return_value = [service] + # Act + response = search_for_matching_services(connection, odscode) + # Assert + assert response == [dos_service] + mock_query_dos_db.assert_called_once_with( + connection, + "SELECT s.id, uid, s.name, odscode, address, postcode, web, typeid," + "statusid, ss.name status_name, publicphone, publicname, st.name service_type_name " + "FROM services s LEFT JOIN servicetypes st ON s.typeid = st.id " + "LEFT JOIN servicestatuses ss on s.statusid = ss.id " + "WHERE s.odscode LIKE %(ODSCODE)s AND s.statusid = %(ACTIVE_STATUS_ID)s", + {"ODSCODE": odscode, "ACTIVE_STATUS_ID": DOS_ACTIVE_STATUS_ID}, + ) + + +@patch(f"{FILE_PATH}.query_dos_db") +def test_search_for_incorrectly_profiled_z_code(mock_query_dos_db: MagicMock) -> None: + # Arrange + connection = MagicMock() + service = get_service_data() + dos_service = DoSService(service) + mock_query_dos_db.return_value.fetchall.return_value = [service] + # Act + response = search_for_incorrectly_profiled_z_code(connection, BLOOD_PRESSURE) + # Assert + assert response == [dos_service] + mock_query_dos_db.assert_called_once_with( + connection, + "SELECT s.id, uid, s.name, odscode, address, postcode, web, typeid, statusid, ss.name status_name, " + "publicphone, publicname, st.name service_type_name " + "FROM services s LEFT JOIN servicetypes st ON s.typeid = st.id " + "LEFT JOIN servicestatuses ss on s.statusid = ss.id " + "LEFT JOIN servicesgsds sgsds on s.id = sgsds.serviceid " + "WHERE sgsds.sgid = %(SYMPTOM_GROUP)s AND sgsds.sdid = %(SYMPTOM_DISCRIMINATOR)s " + "AND s.statusid = %(ACTIVE_STATUS_ID)s AND s.typeid = ANY(%(SERVICE_TYPE_IDS)s)", + { + "ACTIVE_STATUS_ID": DOS_ACTIVE_STATUS_ID, + "SERVICE_TYPE_IDS": [13, 131, 132, 134, 137, 149], + "SYMPTOM_GROUP": BLOOD_PRESSURE.DOS_SYMPTOM_GROUP, + "SYMPTOM_DISCRIMINATOR": BLOOD_PRESSURE.DOS_SYMPTOM_DISCRIMINATOR, + }, + ) diff --git a/application/requirements-dev.txt b/application/requirements-dev.txt index c87f50313..4cc4afda9 100644 --- a/application/requirements-dev.txt +++ b/application/requirements-dev.txt @@ -16,6 +16,6 @@ pytest-sugar pytest-xdist requests response -ruff == 0.0.286 +ruff == 0.0.289 testfixtures vulture diff --git a/application/send_email/requirements.txt b/application/send_email/requirements.txt index baf1293c7..0c96a567e 100644 --- a/application/send_email/requirements.txt +++ b/application/send_email/requirements.txt @@ -1,2 +1,2 @@ aws_embedded_metrics -aws-lambda-powertools[tracer] ~= 2.2.0 +aws-lambda-powertools[tracer] ~= 2.24.0 diff --git a/application/service_matcher/requirements.txt b/application/service_matcher/requirements.txt index ad1f33b71..74b15c649 100644 --- a/application/service_matcher/requirements.txt +++ b/application/service_matcher/requirements.txt @@ -1,4 +1,4 @@ aws-embedded-metrics -aws-lambda-powertools[tracer] ~= 2.2.0 +aws-lambda-powertools[tracer] ~= 2.24.0 psycopg[binary] pytz diff --git a/application/service_sync/reject_pending_changes/pending_changes.py b/application/service_sync/reject_pending_changes/pending_changes.py index 711965d51..fb79dd841 100644 --- a/application/service_sync/reject_pending_changes/pending_changes.py +++ b/application/service_sync/reject_pending_changes/pending_changes.py @@ -206,7 +206,7 @@ def send_rejection_emails(pending_changes: list[PendingChange]) -> None: ) logger.debug("Email message created") client("lambda").invoke( - FunctionName=environ["SEND_EMAIL_LAMBDA_NAME"], + FunctionName=environ["SEND_EMAIL_LAMBDA"], InvocationType="Event", Payload=dumps(message), ) diff --git a/application/service_sync/reject_pending_changes/tests/test_pending_changes.py b/application/service_sync/reject_pending_changes/tests/test_pending_changes.py index a02225cd3..c0d267167 100644 --- a/application/service_sync/reject_pending_changes/tests/test_pending_changes.py +++ b/application/service_sync/reject_pending_changes/tests/test_pending_changes.py @@ -345,7 +345,7 @@ def test_send_rejection_emails( mock_client: MagicMock, ): # Arrange - environ["SEND_EMAIL_LAMBDA_NAME"] = send_email_lambda_name = "test" + environ["SEND_EMAIL_LAMBDA"] = send_email_lambda_name = "test" pending_change = PendingChange(ROW) pending_changes = [pending_change] mock_build_change_rejection_email_contents.return_value = file_contents = "test" @@ -387,7 +387,7 @@ def test_send_rejection_emails( Payload=mock_dumps.return_value, ) # Cleanup - del environ["SEND_EMAIL_LAMBDA_NAME"] + del environ["SEND_EMAIL_LAMBDA"] @patch("builtins.open") diff --git a/application/service_sync/requirements.txt b/application/service_sync/requirements.txt index ad1f33b71..74b15c649 100644 --- a/application/service_sync/requirements.txt +++ b/application/service_sync/requirements.txt @@ -1,4 +1,4 @@ aws-embedded-metrics -aws-lambda-powertools[tracer] ~= 2.2.0 +aws-lambda-powertools[tracer] ~= 2.24.0 psycopg[binary] pytz diff --git a/application/slack_messenger/requirements.txt b/application/slack_messenger/requirements.txt index 99a275cef..8f9b0f7ef 100644 --- a/application/slack_messenger/requirements.txt +++ b/application/slack_messenger/requirements.txt @@ -1,3 +1,3 @@ aws-embedded-metrics -aws-lambda-powertools[tracer] ~= 2.2.0 +aws-lambda-powertools[tracer] ~= 2.24.0 requests diff --git a/build/automation/var/platform-texas/v1/account-live-k8s-nonprod.mk b/build/automation/var/platform-texas/v1/account-live-k8s-nonprod.mk index edae2eb8b..cb6714fc9 100644 --- a/build/automation/var/platform-texas/v1/account-live-k8s-nonprod.mk +++ b/build/automation/var/platform-texas/v1/account-live-k8s-nonprod.mk @@ -6,7 +6,7 @@ TEXAS_WAF_ACL_ID = dfae6ec3-aa05-428f-a022-5fd85f646009 TF_VAR_terraform_platform_state_store = nhsd-texasplatform-terraform-state-store-live-lk8s-$(AWS_ACCOUNT_NAME) -TF_VAR_developer_role_name = UECDoSINTServiceDeveloper +TF_VAR_developer_role = UECDoSINTServiceDeveloper SYSTEM_EMAIL_KEY := DI_SYSTEM_MAILBOX_ADDRESS diff --git a/build/automation/var/platform-texas/v1/account-live-k8s-prod.mk b/build/automation/var/platform-texas/v1/account-live-k8s-prod.mk index 2d0e9696c..8a5332e5d 100644 --- a/build/automation/var/platform-texas/v1/account-live-k8s-prod.mk +++ b/build/automation/var/platform-texas/v1/account-live-k8s-prod.mk @@ -6,7 +6,7 @@ TEXAS_WAF_ACL_ID = ff530a4e-689d-4d90-b3ab-ac2160b5863d TF_VAR_terraform_platform_state_store = nhsd-texasplatform-terraform-state-store-lk8s-$(AWS_ACCOUNT_NAME) -TF_VAR_developer_role_name = UECDoSINTSupportServiceDeveloper +TF_VAR_developer_role = UECDoSINTSupportServiceDeveloper SYSTEM_EMAIL_KEY := DI_SYSTEM_MAILBOX_ADDRESS TEAM_EMAIL_KEY := DI_TEAM_MAILBOX_ADDRESS diff --git a/build/automation/var/profile/tools.mk b/build/automation/var/profile/tools.mk index f3538cc1a..53f0f1e88 100644 --- a/build/automation/var/profile/tools.mk +++ b/build/automation/var/profile/tools.mk @@ -20,4 +20,4 @@ TERRAFORM_NHSD_IDENTITIES_ACCOUNT_ID = $(AWS_ACCOUNT_ID_IDENTITIES) TF_VAR_service_state_bucket = $(TERRAFORM_STATE_STORE) TF_VAR_development_pipeline_state = $(PROJECT_GROUP_SHORT)-$(PROJECT_NAME_SHORT)/dev/development-pipeline/terraform.state TF_VAR_mgmt_vpc_name := mgmt.texasplatform.uk -TF_VAR_developer_role_name = UECDoSINTServiceDeveloper +TF_VAR_developer_role = UECDoSINTServiceDeveloper diff --git a/build/automation/var/project.mk b/build/automation/var/project.mk index 9cd9e6791..f036fbf1c 100644 --- a/build/automation/var/project.mk +++ b/build/automation/var/project.mk @@ -14,8 +14,7 @@ SERVICE_TAG = $(PROJECT_GROUP_SHORT) SERVICE_TAG_COMMON = texas PROJECT_TECH_STACK_LIST = python,terraform -PROJECT_LAMBDAS_LIST = $(CHANGE_EVENT_DLQ_HANDLER),$(DOS_DB_UPDATE_DLQ_HANDLER),$(EVENT_REPLAY),$(SEND_EMAIL),$(SERVICE_MATCHER),$(SERVICE_SYNC),$(SLACK_MESSENGER),$(DOS_DB_HANDLER),$(INGEST_CHANGE_EVENT) -PROJECT_DEPLOYMENT_SECRETS = $(DEPLOYMENT_SECRETS) +PROJECT_LAMBDAS_LIST = $(CHANGE_EVENT_DLQ_HANDLER),$(DOS_DB_HANDLER),$(DOS_DB_UPDATE_DLQ_HANDLER),$(EVENT_REPLAY),$(INGEST_CHANGE_EVENT),$(SEND_EMAIL),$(SERVICE_MATCHER),$(SERVICE_SYNC),$(SLACK_MESSENGER),$(QUALITY_CHECKER) AWS_VPC_NAME = lk8s-$(AWS_ACCOUNT_NAME).texasplatform.uk TF_VAR_aws_vpc_name = $(AWS_VPC_NAME) @@ -26,6 +25,7 @@ TF_VAR_programme = $(PROGRAMME) TF_VAR_environment = $(ENVIRONMENT) TF_VAR_aws_account_name = $(AWS_ACCOUNT_NAME) TF_VAR_deployment_secrets = $(DEPLOYMENT_SECRETS) +PROJECT_DEPLOYMENT_SECRETS = $(DEPLOYMENT_SECRETS) TF_VAR_github_owner = nhsd-exeter TF_VAR_github_repo = dos-integration PARALLEL_TEST_COUNT := $(or $(PARALLEL_TEST_COUNT), auto) @@ -92,6 +92,7 @@ SEND_EMAIL := send-email SERVICE_MATCHER := service-matcher SERVICE_SYNC := service-sync SLACK_MESSENGER := slack-messenger +QUALITY_CHECKER := quality-checker # ------------------------------- # SHARED ENVIRONMENT VARIABLES @@ -110,7 +111,7 @@ TF_VAR_di_endpoint_api_gateway_name := $(PROJECT_ID)-$(SHARED_ENVIRONMENT)-di-en TF_VAR_di_endpoint_api_gateway_stage := $(SHARED_ENVIRONMENT) # SQS Queues -TF_VAR_change_event_queue_name := $(PROJECT_ID)-$(SHARED_ENVIRONMENT)-change-event-queue.fifo +TF_VAR_change_event_queue := $(PROJECT_ID)-$(SHARED_ENVIRONMENT)-change-event-queue.fifo TF_VAR_change_event_dlq := $(PROJECT_ID)-$(SHARED_ENVIRONMENT)-change-event-dead-letter-queue.fifo # Dynamodb @@ -172,56 +173,70 @@ TF_VAR_dos_db_sg_name := $(DOS_DB_SG_NAME) TF_VAR_dos_db_replica_sg_name := $(DOS_DB_REPLICA_SG_NAME) # SQS Queues -TF_VAR_holding_queue_name := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-holding-queue.fifo -TF_VAR_update_request_queue_name := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-update-request-queue.fifo -update_request_queue_url := https://sqs.$(AWS_REGION).amazonaws.com/$(AWS_ACCOUNT_ID)/$(TF_VAR_update_request_queue_name) -holding_queue_url := https://sqs.$(AWS_REGION).amazonaws.com/$(AWS_ACCOUNT_ID)/$(TF_VAR_holding_queue_name) -update_request_dlq_url := https://sqs.$(AWS_REGION).amazonaws.com/$(AWS_ACCOUNT_ID)/$(TF_VAR_update_request_dlq) +TF_VAR_holding_queue := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-holding-queue.fifo +TF_VAR_update_request_queue := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-update-request-queue.fifo +UPDATE_REQUEST_QUEUE_URL := https://sqs.$(AWS_REGION).amazonaws.com/$(AWS_ACCOUNT_ID)/$(TF_VAR_update_request_queue) +HOLDING_QUEUE_URL := https://sqs.$(AWS_REGION).amazonaws.com/$(AWS_ACCOUNT_ID)/$(TF_VAR_holding_queue) TF_VAR_holding_queue_dlq := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-holding-queue-dead-letter-queue.fifo TF_VAR_update_request_dlq := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-update-request-dead-letter-queue.fifo # Lambda names -CHANGE_EVENT_DLQ_HANDLER_LAMBDA_NAME := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(CHANGE_EVENT_DLQ_HANDLER) -DOS_DB_HANDLER_LAMBDA_NAME := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(DOS_DB_HANDLER) -DOS_DB_UPDATE_DLQ_HANDLER_LAMBDA_NAME := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(DOS_DB_UPDATE_DLQ_HANDLER) -EVENT_REPLAY_LAMBDA_NAME := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(EVENT_REPLAY) -INGEST_CHANGE_EVENT_LAMBDA_NAME := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(INGEST_CHANGE_EVENT) -SEND_EMAIL_LAMBDA_NAME := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(SEND_EMAIL) -SERVICE_MATCHER_LAMBDA_NAME := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(SERVICE_MATCHER) -SERVICE_SYNC_LAMBDA_NAME := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(SERVICE_SYNC) -SLACK_MESSENGER_LAMBDA_NAME := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(SLACK_MESSENGER) - -TF_VAR_change_event_dlq_handler_lambda_name := $(CHANGE_EVENT_DLQ_HANDLER_LAMBDA_NAME) -TF_VAR_dos_db_handler_lambda_name := $(DOS_DB_HANDLER_LAMBDA_NAME) -TF_VAR_dos_db_update_dlq_handler_lambda_name := $(DOS_DB_UPDATE_DLQ_HANDLER_LAMBDA_NAME) -TF_VAR_event_replay_lambda_name := $(EVENT_REPLAY_LAMBDA_NAME) -TF_VAR_ingest_change_event_lambda_name := $(INGEST_CHANGE_EVENT_LAMBDA_NAME) -TF_VAR_send_email_lambda_name := $(SEND_EMAIL_LAMBDA_NAME) -TF_VAR_service_matcher_lambda_name := $(SERVICE_MATCHER_LAMBDA_NAME) -TF_VAR_service_sync_lambda_name := $(SERVICE_SYNC_LAMBDA_NAME) -TF_VAR_slack_messenger_lambda_name := $(SLACK_MESSENGER_LAMBDA_NAME) +CHANGE_EVENT_DLQ_HANDLER_LAMBDA := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(CHANGE_EVENT_DLQ_HANDLER) +DOS_DB_HANDLER_LAMBDA := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(DOS_DB_HANDLER) +DOS_DB_UPDATE_DLQ_HANDLER_LAMBDA := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(DOS_DB_UPDATE_DLQ_HANDLER) +EVENT_REPLAY_LAMBDA := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(EVENT_REPLAY) +INGEST_CHANGE_EVENT_LAMBDA := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(INGEST_CHANGE_EVENT) +SEND_EMAIL_LAMBDA := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(SEND_EMAIL) +SERVICE_MATCHER_LAMBDA := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(SERVICE_MATCHER) +SERVICE_SYNC_LAMBDA := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(SERVICE_SYNC) +SLACK_MESSENGER_LAMBDA := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(SLACK_MESSENGER) +QUALITY_CHECKER_LAMBDA := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-$(QUALITY_CHECKER) + +TF_VAR_change_event_dlq_handler_lambda := $(CHANGE_EVENT_DLQ_HANDLER_LAMBDA) +TF_VAR_dos_db_handler_lambda := $(DOS_DB_HANDLER_LAMBDA) +TF_VAR_dos_db_update_dlq_handler_lambda := $(DOS_DB_UPDATE_DLQ_HANDLER_LAMBDA) +TF_VAR_event_replay_lambda := $(EVENT_REPLAY_LAMBDA) +TF_VAR_ingest_change_event_lambda := $(INGEST_CHANGE_EVENT_LAMBDA) +TF_VAR_send_email_lambda := $(SEND_EMAIL_LAMBDA) +TF_VAR_service_matcher_lambda := $(SERVICE_MATCHER_LAMBDA) +TF_VAR_service_sync_lambda := $(SERVICE_SYNC_LAMBDA) +TF_VAR_slack_messenger_lambda := $(SLACK_MESSENGER_LAMBDA) +TF_VAR_quality_checker_lambda := $(QUALITY_CHECKER_LAMBDA) # Lambda IAM Roles -TF_VAR_change_event_dlq_handler_role_name := $(CHANGE_EVENT_DLQ_HANDLER_LAMBDA_NAME)-role -TF_VAR_dos_db_handler_role_name := $(DOS_DB_HANDLER_LAMBDA_NAME)-role -TF_VAR_dos_db_update_dlq_handler_role_name := $(DOS_DB_UPDATE_DLQ_HANDLER_LAMBDA_NAME)-role -TF_VAR_event_replay_role_name := $(EVENT_REPLAY_LAMBDA_NAME)-role -TF_VAR_ingest_change_event_role_name := $(INGEST_CHANGE_EVENT_LAMBDA_NAME)-role -TF_VAR_send_email_role_name := $(SEND_EMAIL_LAMBDA_NAME)-role -TF_VAR_service_matcher_role_name := $(SERVICE_MATCHER_LAMBDA_NAME)-role -TF_VAR_service_sync_role_name := $(SERVICE_SYNC_LAMBDA_NAME)-role -TF_VAR_slack_messenger_role_name := $(SLACK_MESSENGER_LAMBDA_NAME)-role +CHANGE_EVENT_DLQ_HANDLER_LAMBDA_ROLE_NAME := $(CHANGE_EVENT_DLQ_HANDLER_LAMBDA)-role +DOS_DB_HANDLER_LAMBDA_ROLE_NAME := $(DOS_DB_HANDLER_LAMBDA)-role +DOS_DB_UPDATE_DLQ_HANDLER_LAMBDA_ROLE_NAME := $(DOS_DB_UPDATE_DLQ_HANDLER_LAMBDA)-role +EVENT_REPLAY_LAMBDA_ROLE_NAME := $(EVENT_REPLAY_LAMBDA)-role +INGEST_CHANGE_EVENT_LAMBDA_ROLE_NAME := $(INGEST_CHANGE_EVENT_LAMBDA)-role +SEND_EMAIL_LAMBDA_ROLE_NAME := $(SEND_EMAIL_LAMBDA)-role +SERVICE_MATCHER_LAMBDA_ROLE_NAME := $(SERVICE_MATCHER_LAMBDA)-role +SERVICE_SYNC_LAMBDA_ROLE_NAME := $(SERVICE_SYNC_LAMBDA)-role +SLACK_MESSENGER_LAMBDA_ROLE_NAME := $(SLACK_MESSENGER_LAMBDA)-role +QUALITY_CHECKER_LAMBDA_ROLE_NAME := $(QUALITY_CHECKER_LAMBDA)-role + +TF_VAR_change_event_dlq_handler_role := $(CHANGE_EVENT_DLQ_HANDLER_LAMBDA_ROLE_NAME) +TF_VAR_dos_db_handler_role := $(DOS_DB_HANDLER_LAMBDA_ROLE_NAME) +TF_VAR_dos_db_update_dlq_handler_role := $(DOS_DB_UPDATE_DLQ_HANDLER_LAMBDA_ROLE_NAME) +TF_VAR_event_replay_role := $(EVENT_REPLAY_LAMBDA_ROLE_NAME) +TF_VAR_ingest_change_event_role := $(INGEST_CHANGE_EVENT_LAMBDA_ROLE_NAME) +TF_VAR_send_email_role := $(SEND_EMAIL_LAMBDA_ROLE_NAME) +TF_VAR_service_matcher_role := $(SERVICE_MATCHER_LAMBDA_ROLE_NAME) +TF_VAR_service_sync_role := $(SERVICE_SYNC_LAMBDA_ROLE_NAME) +TF_VAR_slack_messenger_role := $(SLACK_MESSENGER_LAMBDA_ROLE_NAME) +TF_VAR_quality_checker_role := $(QUALITY_CHECKER_LAMBDA_ROLE_NAME) # Log Group Filters for Firehose -TF_VAR_change_event_dlq_handler_subscription_filter_name := $(CHANGE_EVENT_DLQ_HANDLER_LAMBDA_NAME)-cw-logs-firehose-subscription -TF_VAR_dos_db_update_dlq_handler_subscription_filter_name := $(DOS_DB_HANDLER_LAMBDA_NAME)-cw-logs-firehose-subscription -TF_VAR_event_replay_subscription_filter_name := $(EVENT_REPLAY_LAMBDA_NAME)-cw-logs-firehose-subscription -TF_VAR_ingest_change_event_subscription_filter_name := $(INGEST_CHANGE_EVENT_LAMBDA_NAME)-cw-logs-firehose-subscription -TF_VAR_send_email_subscription_filter_name := $(SEND_EMAIL_LAMBDA_NAME)-cw-logs-firehose-subscription -TF_VAR_service_matcher_subscription_filter_name := $(SERVICE_MATCHER_LAMBDA_NAME)-cw-logs-firehose-subscription -TF_VAR_service_sync_di_subscription_filter_name := $(SERVICE_SYNC_LAMBDA_NAME)-di-cw-logs-firehose-subscription -TF_VAR_service_sync_dos_subscription_filter_name := $(SERVICE_SYNC_LAMBDA_NAME)-dos-cw-logs-firehose-subscription -TF_VAR_slack_messenger_subscription_filter_name := $(SLACK_MESSENGER_LAMBDA_NAME)-cw-logs-firehose-subscription +TF_VAR_change_event_dlq_handler_subscription_filter_name := $(CHANGE_EVENT_DLQ_HANDLER_LAMBDA)-cw-logs-firehose-subscription +TF_VAR_dos_db_update_dlq_handler_subscription_filter_name := $(DOS_DB_HANDLER_LAMBDA)-cw-logs-firehose-subscription +TF_VAR_event_replay_subscription_filter_name := $(EVENT_REPLAY_LAMBDA)-cw-logs-firehose-subscription +TF_VAR_ingest_change_event_subscription_filter_name := $(INGEST_CHANGE_EVENT_LAMBDA)-cw-logs-firehose-subscription +TF_VAR_send_email_subscription_filter_name := $(SEND_EMAIL_LAMBDA)-cw-logs-firehose-subscription +TF_VAR_service_matcher_subscription_filter_name := $(SERVICE_MATCHER_LAMBDA)-cw-logs-firehose-subscription +TF_VAR_service_sync_di_subscription_filter_name := $(SERVICE_SYNC_LAMBDA)-di-cw-logs-firehose-subscription +TF_VAR_service_sync_dos_subscription_filter_name := $(SERVICE_SYNC_LAMBDA)-dos-cw-logs-firehose-subscription +TF_VAR_slack_messenger_subscription_filter_name := $(SLACK_MESSENGER_LAMBDA)-cw-logs-firehose-subscription +TF_VAR_quality_checker_subscription_filter_name := $(QUALITY_CHECKER_LAMBDA)-cw-logs-firehose-subscription # Cloudwatch dashboards TF_VAR_cloudwatch_monitoring_dashboard_name := $(PROJECT_ID)-$(SHARED_ENVIRONMENT)-monitoring-dashboard @@ -229,4 +244,4 @@ TF_VAR_cloudwatch_data_dashboard_name := $(PROJECT_ID)-$(SHARED_ENVIRONMENT)-dat TF_VAR_sqs_dlq_recieved_msg_alert_name := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-sqs-dlq-recieved-msg-alert TF_VAR_sns_topic_app_alerts_for_slack_default_region := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-topic-app-alerts-for-slack-default-region TF_VAR_sns_topic_app_alerts_for_slack_route53_health_check_alarm_region := $(PROJECT_ID)-$(BLUE_GREEN_ENVIRONMENT)-topic-app-alerts-for-slack-route53-health-check-alarm-region -SQS_QUEUE_URL:= https://sqs.$(AWS_REGION).amazonaws.com/$(AWS_ACCOUNT_ID)/$(TF_VAR_change_event_queue_name) +SQS_QUEUE_URL:= https://sqs.$(AWS_REGION).amazonaws.com/$(AWS_ACCOUNT_ID)/$(TF_VAR_change_event_queue) diff --git a/deployment/serverless.yml b/deployment/serverless.yml index 6608244ad..dc651b4a8 100644 --- a/deployment/serverless.yml +++ b/deployment/serverless.yml @@ -84,22 +84,22 @@ custom: functions: change-event-dlq-handler: image: ${env:DOCKER_REGISTRY}/${env:CHANGE_EVENT_DLQ_HANDLER}:${env:VERSION} - name: ${env:CHANGE_EVENT_DLQ_HANDLER_LAMBDA_NAME} - description: ${sls:stage} Change Event DLQ Handler lambda + name: ${env:CHANGE_EVENT_DLQ_HANDLER_LAMBDA} + description: ${sls:stage} Change Event DLQ Handler memorySize: 128 timeout: 30 - role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_change_event_dlq_handler_role_name} + role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_change_event_dlq_handler_role} environment: CHANGE_EVENTS_TABLE_NAME: ${env:TF_VAR_change_events_table_name} maximumRetryAttempts: 0 dos-db-handler: image: ${env:DOCKER_REGISTRY}/${env:DOS_DB_HANDLER}:${env:VERSION} - name: ${env:DOS_DB_HANDLER_LAMBDA_NAME} - description: ${sls:stage} DoS DB Handler lambda for accessing DoS DB in Non-Live environments + name: ${env:DOS_DB_HANDLER_LAMBDA} + description: ${sls:stage} DoS DB Handler for accessing DoS DB in Non-Live environments memorySize: 128 timeout: 30 - role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_dos_db_handler_role_name} + role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_dos_db_handler_role} environment: DB_NAME: ${env:DB_NAME} DB_PORT: ${env:DB_PORT} @@ -128,44 +128,44 @@ functions: dos-db-update-dlq-handler: image: ${env:DOCKER_REGISTRY}/${env:DOS_DB_UPDATE_DLQ_HANDLER}:${env:VERSION} - name: ${env:DOS_DB_UPDATE_DLQ_HANDLER_LAMBDA_NAME} - description: ${sls:stage} DoS DB Update DLQ Handler lambda + name: ${env:DOS_DB_UPDATE_DLQ_HANDLER_LAMBDA} + description: ${sls:stage} DoS DB Update DLQ Handler memorySize: 128 timeout: 30 - role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_dos_db_update_dlq_handler_role_name} + role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_dos_db_update_dlq_handler_role} maximumRetryAttempts: 0 event-replay: image: ${env:DOCKER_REGISTRY}/${env:EVENT_REPLAY}:${env:VERSION} - name: ${env:EVENT_REPLAY_LAMBDA_NAME} - description: ${sls:stage} Event Replay lambda + name: ${env:EVENT_REPLAY_LAMBDA} + description: ${sls:stage} Event Replay memorySize: 128 timeout: 30 - role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_event_replay_role_name} + role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_event_replay_role} environment: CHANGE_EVENTS_TABLE_NAME: ${env:TF_VAR_change_events_table_name} - CHANGE_EVENT_SQS_NAME: ${env:TF_VAR_change_event_queue_name} + CHANGE_EVENT_SQS_NAME: ${env:TF_VAR_change_event_queue} maximumRetryAttempts: 0 ingest-change-event: image: ${env:DOCKER_REGISTRY}/${env:INGEST_CHANGE_EVENT}:${env:VERSION} - name: ${env:INGEST_CHANGE_EVENT_LAMBDA_NAME} - description: ${sls:stage} Ingest Change Event lambda + name: ${env:INGEST_CHANGE_EVENT_LAMBDA} + description: ${sls:stage} Ingest Change Event memorySize: 128 timeout: 30 - role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_ingest_change_event_role_name} + role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_ingest_change_event_role} environment: - HOLDING_QUEUE_URL: ${env:holding_queue_url} + HOLDING_QUEUE_URL: ${env:HOLDING_QUEUE_URL} CHANGE_EVENTS_TABLE_NAME: ${env:TF_VAR_change_events_table_name} maximumRetryAttempts: 2 send-email: image: ${env:DOCKER_REGISTRY}/${env:SEND_EMAIL}:${env:VERSION} - name: ${env:SEND_EMAIL_LAMBDA_NAME} - description: ${sls:stage} Send Email lambda + name: ${env:SEND_EMAIL_LAMBDA} + description: ${sls:stage} Send Email memorySize: 128 timeout: 30 - role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_send_email_role_name} + role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_send_email_role} environment: AWS_ACCOUNT_NAME: ${env:AWS_ACCOUNT_NAME} SYSTEM_EMAIL_ADDRESS: ${env:PROJECT_SYSTEM_EMAIL_ADDRESS} @@ -174,16 +174,16 @@ functions: service-matcher: image: ${env:DOCKER_REGISTRY}/${env:SERVICE_MATCHER}:${env:VERSION} - name: ${env:SERVICE_MATCHER_LAMBDA_NAME} - description: ${sls:stage} Service Matcher lambda + name: ${env:SERVICE_MATCHER_LAMBDA} + description: ${sls:stage} Service Matcher memorySize: 192 timeout: 10 - role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_service_matcher_role_name} + role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_service_matcher_role} maximumRetryAttempts: 0 reservedConcurrency: ${env:SERVICE_MATCHER_MAX_CONCURRENCY} environment: CHANGE_EVENTS_TABLE_NAME: ${env:TF_VAR_change_events_table_name} - UPDATE_REQUEST_QUEUE_URL: ${env:update_request_queue_url} + UPDATE_REQUEST_QUEUE_URL: ${env:UPDATE_REQUEST_QUEUE_URL} DB_NAME: ${env:DB_NAME} DB_PORT: ${env:DB_PORT} DB_READ_ONLY_USER_NAME: ${env:DB_READ_ONLY_USER_NAME} @@ -207,14 +207,14 @@ functions: service-sync: image: ${env:DOCKER_REGISTRY}/${env:SERVICE_SYNC}:${env:VERSION} - name: ${env:SERVICE_SYNC_LAMBDA_NAME} - description: ${sls:stage} Service Sync lambda + name: ${env:SERVICE_SYNC_LAMBDA} + description: ${sls:stage} Service Sync memorySize: 512 timeout: 20 - role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_service_sync_role_name} + role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_service_sync_role} environment: CHANGE_EVENTS_TABLE_NAME: ${env:TF_VAR_change_events_table_name} - UPDATE_REQUEST_QUEUE_URL: ${env:update_request_queue_url} + UPDATE_REQUEST_QUEUE_URL: ${env:UPDATE_REQUEST_QUEUE_URL} DB_NAME: ${env:DB_NAME} DB_PORT: ${env:DB_PORT} DB_READ_ONLY_USER_NAME: ${env:DB_READ_ONLY_USER_NAME} @@ -229,7 +229,7 @@ functions: SEND_EMAIL_BUCKET_NAME: ${env:SEND_EMAIL_BUCKET_NAME} TEAM_EMAIL_ADDRESS: ${env:PROJECT_TEAM_EMAIL_ADDRESS} SYSTEM_EMAIL_ADDRESS: ${env:PROJECT_SYSTEM_EMAIL_ADDRESS} - SEND_EMAIL_LAMBDA_NAME: ${env:TF_VAR_send_email_lambda_name} + SEND_EMAIL_LAMBDA: ${env:TF_VAR_send_email_lambda} reservedConcurrency: ${env:SERVICE_SYNC_MAX_CONCURRENCY} maximumRetryAttempts: 0 vpcDiscovery: @@ -247,11 +247,11 @@ functions: slack-messenger: image: ${env:DOCKER_REGISTRY}/${env:SLACK_MESSENGER}:${env:VERSION} - name: ${env:SLACK_MESSENGER_LAMBDA_NAME} - description: ${sls:stage} Slack Messenger lambda + name: ${env:SLACK_MESSENGER_LAMBDA} + description: ${sls:stage} Slack Messenger memorySize: 128 timeout: 10 - role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_slack_messenger_role_name} + role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_slack_messenger_role} environment: SLACK_ALERT_CHANNEL: ${env:SLACK_ALERT_CHANNEL} SLACK_WEBHOOK_URL: ${env:SLACK_WEBHOOK_URL} @@ -260,3 +260,41 @@ functions: arn: arn:aws:sns:${env:AWS_REGION}:${env:AWS_ACCOUNT_ID}:${env:TF_VAR_sns_topic_app_alerts_for_slack_default_region} - sns: arn: arn:aws:sns:${env:TF_VAR_route53_health_check_alarm_region}:${env:AWS_ACCOUNT_ID}:${env:TF_VAR_sns_topic_app_alerts_for_slack_route53_health_check_alarm_region} + + quality-checker: + image: ${env:DOCKER_REGISTRY}/${env:QUALITY_CHECKER}:${env:VERSION} + name: ${env:QUALITY_CHECKER_LAMBDA} + description: ${sls:stage} Quality Checker + memorySize: 512 + timeout: 900 + role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/${env:TF_VAR_quality_checker_role} + environment: + DB_NAME: ${env:DB_NAME} + DB_PORT: ${env:DB_PORT} + DB_READ_ONLY_USER_NAME: ${env:DB_READ_ONLY_USER_NAME} + DB_REPLICA_SECRET_KEY: ${env:DB_REPLICA_SECRET_KEY} + DB_REPLICA_SECRET_NAME: ${env:DB_REPLICA_SECRET_NAME} + DB_REPLICA_SERVER: ${env:DB_REPLICA_SERVER} + DB_SERVER: ${env:DB_SERVER} + DB_SCHEMA: ${env:DB_SCHEMA} + DB_SECRET_KEY: ${env:DB_SECRET_KEY} + DB_SECRET_NAME: ${env:DB_SECRET_NAME} + DB_READ_AND_WRITE_USER_NAME: ${env:DB_READ_AND_WRITE_USER_NAME} + maximumRetryAttempts: 0 + events: + - schedule: + name: ${env:QUALITY_CHECKER_LAMBDA}-schedule + description: Quality Checker Schedule for triggering a DoS quality check + rate: cron(30 4 ? * MON *) + vpcDiscovery: + vpcName: "${env:AWS_VPC_NAME}" + subnets: + - tagKey: Name + tagValues: + - "${env:AWS_VPC_NAME}-private-${env:AWS_REGION}a" + - "${env:AWS_VPC_NAME}-private-${env:AWS_REGION}b" + - "${env:AWS_VPC_NAME}-private-${env:AWS_REGION}c" + securityGroups: + - tagKey: Name + tagValues: + - "${env:TF_VAR_lambda_security_group_name}" diff --git a/infrastructure/stacks/after-lambda-deployment/data.tf b/infrastructure/stacks/after-lambda-deployment/data.tf index ac141c3a6..60ab0abf7 100644 --- a/infrastructure/stacks/after-lambda-deployment/data.tf +++ b/infrastructure/stacks/after-lambda-deployment/data.tf @@ -3,27 +3,27 @@ # ############## data "aws_lambda_function" "service_matcher" { - function_name = var.service_matcher_lambda_name + function_name = var.service_matcher_lambda } data "aws_lambda_function" "service_sync" { - function_name = var.service_sync_lambda_name + function_name = var.service_sync_lambda } data "aws_lambda_function" "ingest_change_event" { - function_name = var.ingest_change_event_lambda_name + function_name = var.ingest_change_event_lambda } data "aws_lambda_function" "change_event_dlq_handler" { - function_name = var.change_event_dlq_handler_lambda_name + function_name = var.change_event_dlq_handler_lambda } data "aws_lambda_function" "dos_db_update_dlq_handler" { - function_name = var.dos_db_update_dlq_handler_lambda_name + function_name = var.dos_db_update_dlq_handler_lambda } data "aws_lambda_function" "send_email" { - function_name = var.send_email_lambda_name + function_name = var.send_email_lambda } # ############## diff --git a/infrastructure/stacks/after-lambda-deployment/splunk.tf b/infrastructure/stacks/after-lambda-deployment/splunk.tf index 73ffa4ce2..83b1fdcf8 100644 --- a/infrastructure/stacks/after-lambda-deployment/splunk.tf +++ b/infrastructure/stacks/after-lambda-deployment/splunk.tf @@ -1,83 +1,95 @@ -resource "aws_cloudwatch_log_subscription_filter" "service_matcher_logs_subscription_filter" { - name = var.service_matcher_subscription_filter_name +resource "aws_cloudwatch_log_subscription_filter" "change_event_dlq_handler_logs_subscription_filter" { + name = var.change_event_dlq_handler_subscription_filter_name role_arn = data.aws_iam_role.di_firehose_role.arn - log_group_name = "/aws/lambda/${var.service_matcher_lambda_name}" + log_group_name = "/aws/lambda/${var.change_event_dlq_handler_lambda}" filter_pattern = "" destination_arn = data.aws_kinesis_firehose_delivery_stream.dos_integration_firehose.arn depends_on = [time_sleep.wait_a_minute] } -resource "aws_cloudwatch_log_subscription_filter" "service_sync_di_logs_subscription_filter" { - name = var.service_sync_di_subscription_filter_name +resource "aws_cloudwatch_log_subscription_filter" "dos_db_update_dlq_handler_logs_subscription_filter" { + name = var.dos_db_update_dlq_handler_subscription_filter_name role_arn = data.aws_iam_role.di_firehose_role.arn - log_group_name = "/aws/lambda/${var.service_sync_lambda_name}" + log_group_name = "/aws/lambda/${var.dos_db_update_dlq_handler_lambda}" filter_pattern = "" destination_arn = data.aws_kinesis_firehose_delivery_stream.dos_integration_firehose.arn - depends_on = [time_sleep.wait_a_minute, aws_cloudwatch_log_subscription_filter.service_sync_dos_logs_subscription_filter] + depends_on = [time_sleep.wait_a_minute] } -resource "aws_cloudwatch_log_subscription_filter" "service_sync_dos_logs_subscription_filter" { - count = var.profile == "demo" ? 0 : 1 - name = var.service_sync_dos_subscription_filter_name - role_arn = data.aws_iam_role.dos_firehose_role.arn - log_group_name = "/aws/lambda/${var.service_sync_lambda_name}" - filter_pattern = "elapsedTime=NULL" - destination_arn = data.aws_kinesis_firehose_delivery_stream.dos_firehose.arn +resource "aws_cloudwatch_log_subscription_filter" "event_replay_logs_subscription_filter" { + name = var.event_replay_subscription_filter_name + role_arn = data.aws_iam_role.di_firehose_role.arn + log_group_name = "/aws/lambda/${var.event_replay_lambda}" + filter_pattern = "" + destination_arn = data.aws_kinesis_firehose_delivery_stream.dos_integration_firehose.arn depends_on = [time_sleep.wait_a_minute] } -resource "aws_cloudwatch_log_subscription_filter" "change_event_dlq_handler_logs_subscription_filter" { - name = var.change_event_dlq_handler_subscription_filter_name +resource "aws_cloudwatch_log_subscription_filter" "ingest_change_event_logs_subscription_filter" { + name = var.ingest_change_event_subscription_filter_name role_arn = data.aws_iam_role.di_firehose_role.arn - log_group_name = "/aws/lambda/${var.change_event_dlq_handler_lambda_name}" + log_group_name = "/aws/lambda/${var.ingest_change_event_lambda}" filter_pattern = "" destination_arn = data.aws_kinesis_firehose_delivery_stream.dos_integration_firehose.arn depends_on = [time_sleep.wait_a_minute] } -resource "aws_cloudwatch_log_subscription_filter" "dos_db_update_dlq_handler_logs_subscription_filter" { - name = var.dos_db_update_dlq_handler_subscription_filter_name +resource "aws_cloudwatch_log_subscription_filter" "send_email_logs_subscription_filter" { + name = var.send_email_subscription_filter_name role_arn = data.aws_iam_role.di_firehose_role.arn - log_group_name = "/aws/lambda/${var.dos_db_update_dlq_handler_lambda_name}" + log_group_name = "/aws/lambda/${var.send_email_lambda}" filter_pattern = "" destination_arn = data.aws_kinesis_firehose_delivery_stream.dos_integration_firehose.arn depends_on = [time_sleep.wait_a_minute] } -resource "aws_cloudwatch_log_subscription_filter" "event_replay_logs_subscription_filter" { - name = var.event_replay_subscription_filter_name +resource "aws_cloudwatch_log_subscription_filter" "service_matcher_logs_subscription_filter" { + name = var.service_matcher_subscription_filter_name role_arn = data.aws_iam_role.di_firehose_role.arn - log_group_name = "/aws/lambda/${var.event_replay_lambda_name}" + log_group_name = "/aws/lambda/${var.service_matcher_lambda}" filter_pattern = "" destination_arn = data.aws_kinesis_firehose_delivery_stream.dos_integration_firehose.arn depends_on = [time_sleep.wait_a_minute] } -resource "aws_cloudwatch_log_subscription_filter" "slack_messenger_logs_subscription_filter" { - name = var.slack_messenger_subscription_filter_name + +resource "aws_cloudwatch_log_subscription_filter" "service_sync_di_logs_subscription_filter" { + name = var.service_sync_di_subscription_filter_name role_arn = data.aws_iam_role.di_firehose_role.arn - log_group_name = "/aws/lambda/${var.slack_messenger_lambda_name}" + log_group_name = "/aws/lambda/${var.service_sync_lambda}" filter_pattern = "" destination_arn = data.aws_kinesis_firehose_delivery_stream.dos_integration_firehose.arn + depends_on = [time_sleep.wait_a_minute, aws_cloudwatch_log_subscription_filter.service_sync_dos_logs_subscription_filter] +} + +resource "aws_cloudwatch_log_subscription_filter" "service_sync_dos_logs_subscription_filter" { + count = var.profile == "demo" ? 0 : 1 + name = var.service_sync_dos_subscription_filter_name + role_arn = data.aws_iam_role.dos_firehose_role.arn + log_group_name = "/aws/lambda/${var.service_sync_lambda}" + filter_pattern = "elapsedTime=NULL" + destination_arn = data.aws_kinesis_firehose_delivery_stream.dos_firehose.arn depends_on = [time_sleep.wait_a_minute] } -resource "aws_cloudwatch_log_subscription_filter" "send_email_logs_subscription_filter" { - name = var.send_email_subscription_filter_name + +resource "aws_cloudwatch_log_subscription_filter" "slack_messenger_logs_subscription_filter" { + name = var.slack_messenger_subscription_filter_name role_arn = data.aws_iam_role.di_firehose_role.arn - log_group_name = "/aws/lambda/${var.send_email_lambda_name}" + log_group_name = "/aws/lambda/${var.slack_messenger_lambda}" filter_pattern = "" destination_arn = data.aws_kinesis_firehose_delivery_stream.dos_integration_firehose.arn depends_on = [time_sleep.wait_a_minute] } -resource "aws_cloudwatch_log_subscription_filter" "ingest_change_event_logs_subscription_filter" { - name = var.ingest_change_event_subscription_filter_name +resource "aws_cloudwatch_log_subscription_filter" "quality_checker_logs_subscription_filter" { + name = var.quality_checker_subscription_filter_name role_arn = data.aws_iam_role.di_firehose_role.arn - log_group_name = "/aws/lambda/${var.ingest_change_event_lambda_name}" + log_group_name = "/aws/lambda/${var.quality_checker_lambda}" filter_pattern = "" destination_arn = data.aws_kinesis_firehose_delivery_stream.dos_integration_firehose.arn depends_on = [time_sleep.wait_a_minute] } + resource "time_sleep" "wait_a_minute" { create_duration = "1m" } diff --git a/infrastructure/stacks/after-lambda-deployment/sqs.tf b/infrastructure/stacks/after-lambda-deployment/sqs.tf index c1b1aa5f9..37d61ea62 100644 --- a/infrastructure/stacks/after-lambda-deployment/sqs.tf +++ b/infrastructure/stacks/after-lambda-deployment/sqs.tf @@ -1,5 +1,5 @@ resource "aws_sqs_queue" "holding_queue" { - name = var.holding_queue_name + name = var.holding_queue fifo_queue = true content_based_deduplication = true deduplication_scope = "messageGroup" @@ -15,7 +15,7 @@ resource "aws_sqs_queue" "holding_queue" { } resource "aws_sqs_queue" "update_request_queue" { - name = var.update_request_queue_name + name = var.update_request_queue fifo_queue = true content_based_deduplication = true deduplication_scope = "messageGroup" diff --git a/infrastructure/stacks/after-lambda-deployment/variables.tf b/infrastructure/stacks/after-lambda-deployment/variables.tf index a635aca08..c4572e405 100755 --- a/infrastructure/stacks/after-lambda-deployment/variables.tf +++ b/infrastructure/stacks/after-lambda-deployment/variables.tf @@ -2,17 +2,17 @@ # SQS FIFO QUEUE # ############################ -variable "change_event_queue_name" { +variable "change_event_queue" { type = string description = "Change event queue name" } -variable "holding_queue_name" { +variable "holding_queue" { type = string description = "Holding queue name" } -variable "update_request_queue_name" { +variable "update_request_queue" { type = string description = "Update request queue name" } @@ -101,6 +101,11 @@ variable "ingest_change_event_subscription_filter_name" { description = "Log filter name for ingest change event lambda" } +variable "quality_checker_subscription_filter_name" { + type = string + description = "Log filter name for quality checker lambda" +} + variable "dos_integration_firehose" { type = string description = "The firehose delivery stream name" @@ -124,42 +129,47 @@ variable "dos_firehose_role" { # # LAMBDAS # ############## -variable "service_matcher_lambda_name" { +variable "change_event_dlq_handler_lambda" { type = string - description = "Name of event processor lambda" + description = "Name of fifo dlq handler lambda" } -variable "service_sync_lambda_name" { +variable "dos_db_update_dlq_handler_lambda" { type = string - description = "Name of event sender lambda" + description = "Name of cr_fifo dlq handler lambda" } -variable "change_event_dlq_handler_lambda_name" { +variable "event_replay_lambda" { type = string - description = "Name of fifo dlq handler lambda" + description = "Name of event replay lambda" } -variable "dos_db_update_dlq_handler_lambda_name" { +variable "ingest_change_event_lambda" { type = string - description = "Name of cr_fifo dlq handler lambda" + description = "Name of ingest change event lambda" } -variable "event_replay_lambda_name" { +variable "send_email_lambda" { type = string - description = "Name of event replay lambda" + description = "Name of send email lambda" } -variable "slack_messenger_lambda_name" { +variable "service_matcher_lambda" { type = string - description = "Name of slack messenger lambda" + description = "Name of event processor lambda" } -variable "send_email_lambda_name" { +variable "service_sync_lambda" { type = string - description = "Name of send email lambda" + description = "Name of event sender lambda" } -variable "ingest_change_event_lambda_name" { +variable "slack_messenger_lambda" { type = string - description = "Name of ingest change event lambda" + description = "Name of slack messenger lambda" +} + +variable "quality_checker_lambda" { + type = string + description = "Name of quality checker lambda" } diff --git a/infrastructure/stacks/before-lambda-deployment/lambda_iam_roles.tf b/infrastructure/stacks/before-lambda-deployment/lambda_iam_roles.tf index 82c65bc64..334dcefee 100644 --- a/infrastructure/stacks/before-lambda-deployment/lambda_iam_roles.tf +++ b/infrastructure/stacks/before-lambda-deployment/lambda_iam_roles.tf @@ -1,466 +1,487 @@ resource "aws_iam_role" "event_replay_role" { - name = var.event_replay_role_name - path = "/" - description = "" - assume_role_policy = < Above 0 is bad", + "title" : "Lambda Error Rates", "period" : 60 "yAxis" : { "left" : { @@ -283,7 +286,7 @@ resource "aws_cloudwatch_dashboard" "cloudwatch_monitoring_dashboard" { "view" : "timeSeries", "stacked" : false, "metrics" : [ - ["AWS/Lambda", "ConcurrentExecutions", "FunctionName", var.ingest_change_event_lambda_name], + ["AWS/Lambda", "ConcurrentExecutions", "FunctionName", var.ingest_change_event_lambda], [".", "Duration", ".", "."], [".", "Errors", ".", ".", { "visible" : false }], ["...", { "id" : "errors", stat : "Sum", "color" : "#d62728" }], @@ -311,7 +314,7 @@ resource "aws_cloudwatch_dashboard" "cloudwatch_monitoring_dashboard" { "view" : "timeSeries", "stacked" : false, "metrics" : [ - ["AWS/Lambda", "ConcurrentExecutions", "FunctionName", var.service_matcher_lambda_name], + ["AWS/Lambda", "ConcurrentExecutions", "FunctionName", var.service_matcher_lambda], [".", "Duration", ".", "."], [".", "Errors", ".", ".", { "visible" : false }], ["...", { "id" : "errors", stat : "Sum", "color" : "#d62728" }], @@ -339,7 +342,7 @@ resource "aws_cloudwatch_dashboard" "cloudwatch_monitoring_dashboard" { "view" : "timeSeries", "stacked" : false, "metrics" : [ - ["AWS/Lambda", "ConcurrentExecutions", "FunctionName", var.service_sync_lambda_name], + ["AWS/Lambda", "ConcurrentExecutions", "FunctionName", var.service_sync_lambda], [".", "Duration", ".", "."], [".", "Errors", ".", ".", { "visible" : false }], ["...", { "id" : "errors", stat : "Sum", "color" : "#d62728" }], @@ -388,7 +391,7 @@ resource "aws_cloudwatch_dashboard" "cloudwatch_monitoring_dashboard" { "view" : "timeSeries", "stacked" : false, "metrics" : [ - ["AWS/SQS", "NumberOfMessagesSent", "QueueName", var.change_event_queue_name], + ["AWS/SQS", "NumberOfMessagesSent", "QueueName", var.change_event_queue], [".", "NumberOfMessagesReceived", ".", "."], [".", "ApproximateNumberOfMessagesVisible", ".", "."] ], @@ -409,7 +412,7 @@ resource "aws_cloudwatch_dashboard" "cloudwatch_monitoring_dashboard" { "view" : "timeSeries", "stacked" : false, "metrics" : [ - ["AWS/SQS", "NumberOfMessagesSent", "QueueName", var.holding_queue_name], + ["AWS/SQS", "NumberOfMessagesSent", "QueueName", var.holding_queue], [".", "NumberOfMessagesReceived", ".", "."], [".", "ApproximateNumberOfMessagesVisible", ".", "."], ], @@ -430,7 +433,7 @@ resource "aws_cloudwatch_dashboard" "cloudwatch_monitoring_dashboard" { "view" : "timeSeries", "stacked" : false, "metrics" : [ - ["AWS/SQS", "NumberOfMessagesSent", "QueueName", var.update_request_queue_name], + ["AWS/SQS", "NumberOfMessagesSent", "QueueName", var.update_request_queue], [".", "NumberOfMessagesReceived", ".", "."], [".", "ApproximateNumberOfMessagesVisible", ".", "."], ], diff --git a/infrastructure/stacks/blue-green-link/cloudwatch-queries.tf b/infrastructure/stacks/blue-green-link/cloudwatch-queries.tf index 78d7f4fa5..26c6ccda1 100644 --- a/infrastructure/stacks/blue-green-link/cloudwatch-queries.tf +++ b/infrastructure/stacks/blue-green-link/cloudwatch-queries.tf @@ -2,13 +2,13 @@ resource "aws_cloudwatch_query_definition" "search_for_errors" { name = "${var.project_id}/${var.blue_green_environment}/search-for-errors" log_group_names = [ - "/aws/lambda/${var.change_event_dlq_handler_lambda_name}", - "/aws/lambda/${var.dos_db_update_dlq_handler_lambda_name}", - "/aws/lambda/${var.event_replay_lambda_name}", - "/aws/lambda/${var.ingest_change_event_lambda_name}", - "/aws/lambda/${var.send_email_lambda_name}", - "/aws/lambda/${var.service_matcher_lambda_name}", - "/aws/lambda/${var.service_sync_lambda_name}" + "/aws/lambda/${var.change_event_dlq_handler_lambda}", + "/aws/lambda/${var.dos_db_update_dlq_handler_lambda}", + "/aws/lambda/${var.event_replay_lambda}", + "/aws/lambda/${var.ingest_change_event_lambda}", + "/aws/lambda/${var.send_email_lambda}", + "/aws/lambda/${var.service_matcher_lambda}", + "/aws/lambda/${var.service_sync_lambda}" ] query_string = < Any: retries = 0 while not response_status: response: Any = LAMBDA_CLIENT_FUNCTIONS.invoke( - FunctionName=getenv("DOS_DB_HANDLER_LAMBDA_NAME"), + FunctionName=getenv("DOS_DB_HANDLER_LAMBDA"), InvocationType="RequestResponse", Payload=dumps(lambda_payload), ) @@ -50,7 +50,7 @@ def re_process_payload(odscode: str, seq_number: str) -> str: """ lambda_payload = {"odscode": odscode, "sequence_number": seq_number} response = LAMBDA_CLIENT_FUNCTIONS.invoke( - FunctionName=getenv("EVENT_REPLAY_LAMBDA_NAME"), + FunctionName=getenv("EVENT_REPLAY_LAMBDA"), InvocationType="RequestResponse", Payload=dumps(lambda_payload), ) diff --git a/test/smoke/functions/aws.py b/test/smoke/functions/aws.py index df037f7aa..7277cbbd6 100644 --- a/test/smoke/functions/aws.py +++ b/test/smoke/functions/aws.py @@ -69,7 +69,7 @@ def invoke_dos_db_handler_lambda(lambda_payload: dict) -> str: retries = 0 while not response_status: response = lambda_client.invoke( - FunctionName=getenv("DOS_DB_HANDLER_LAMBDA_NAME"), + FunctionName=getenv("DOS_DB_HANDLER_LAMBDA"), InvocationType="RequestResponse", Payload=dumps(lambda_payload), )