|
| 1 | +"""Batch processor filter service module""" |
| 2 | +import boto3 |
| 3 | +import json |
| 4 | +import logging |
| 5 | + |
| 6 | +from batch_audit_repository import BatchAuditRepository |
| 7 | +from batch_file_created_event import BatchFileCreatedEvent |
| 8 | +from constants import REGION_NAME, FileStatus, QUEUE_URL |
| 9 | +from exceptions import EventAlreadyProcessingForSupplierAndVaccTypeError |
| 10 | +from send_log_to_firehose import send_log_to_firehose |
| 11 | + |
| 12 | +logging.basicConfig(level="INFO") |
| 13 | +logger = logging.getLogger() |
| 14 | +logger.setLevel("INFO") |
| 15 | + |
| 16 | + |
| 17 | +class BatchProcessorFilterService: |
| 18 | + """Batch processor filter service class. Provides the business logic for the Lambda function""" |
| 19 | + def __init__(self, audit_repo: BatchAuditRepository = BatchAuditRepository()): |
| 20 | + self._batch_audit_repository = audit_repo |
| 21 | + self._queue_client = boto3.client('sqs', region_name=REGION_NAME) |
| 22 | + |
| 23 | + def _is_duplicate_file(self, file_key: str) -> bool: |
| 24 | + """Checks if a file with the same name has already been processed or marked for processing""" |
| 25 | + return self._batch_audit_repository.is_duplicate_file(file_key) |
| 26 | + |
| 27 | + def apply_filter(self, batch_file_created_event: BatchFileCreatedEvent) -> None: |
| 28 | + filename = batch_file_created_event["filename"] |
| 29 | + message_id = batch_file_created_event["message_id"] |
| 30 | + supplier = batch_file_created_event["supplier"] |
| 31 | + vaccine_type = batch_file_created_event["vaccine_type"] |
| 32 | + |
| 33 | + if self._is_duplicate_file(filename): |
| 34 | + # Mark as processed and return without error so next event will be picked up from queue |
| 35 | + logger.info("A duplicate file has already been processed. Filename: %s", filename) |
| 36 | + self._batch_audit_repository.update_status(message_id, FileStatus.DUPLICATE) |
| 37 | + return |
| 38 | + |
| 39 | + if self._batch_audit_repository.is_event_processing_for_supplier_and_vacc_type(supplier, vaccine_type): |
| 40 | + # Raise error so event is returned to queue and retried again later |
| 41 | + logger.info("Batch event already being processed for supplier and vacc type. Filename: %s", filename) |
| 42 | + raise EventAlreadyProcessingForSupplierAndVaccTypeError(f"Batch event already processing for supplier: " |
| 43 | + f"{supplier} and vacc type: {vaccine_type}") |
| 44 | + |
| 45 | + self._queue_client.send_message( |
| 46 | + QueueUrl=QUEUE_URL, |
| 47 | + MessageBody=json.dumps(batch_file_created_event), |
| 48 | + MessageGroupId=f"{supplier}_{vaccine_type}" |
| 49 | + ) |
| 50 | + self._batch_audit_repository.update_status(message_id, FileStatus.PROCESSING) |
| 51 | + |
| 52 | + successful_log_message = "File forwarded for processing by ECS" |
| 53 | + logger.info(successful_log_message) |
| 54 | + send_log_to_firehose({**batch_file_created_event, "message": successful_log_message}) |
0 commit comments