|
| 1 | +import uuid |
| 2 | + |
| 3 | +import boto3 |
| 4 | +from botocore.exceptions import ClientError |
| 5 | +from cachetools import TTLCache, cached |
| 6 | +from mypy_boto3_dynamodb import DynamoDBServiceResource |
| 7 | +from mypy_boto3_dynamodb.service_resource import Table |
| 8 | +from pydantic import ValidationError |
| 9 | + |
| 10 | +from service.dal.db_handler import DalHandler |
| 11 | +from service.dal.schemas.db import OrderEntry |
| 12 | +from service.handlers.utils.observability import logger, tracer |
| 13 | +from service.schemas.exceptions import InternalServerException |
| 14 | + |
| 15 | + |
| 16 | +class DynamoDalHandler(DalHandler): |
| 17 | + |
| 18 | + def __init__(self, table_name: str): |
| 19 | + self.table_name = table_name |
| 20 | + |
| 21 | + # cache dynamodb connection data for no longer than 5 minutes |
| 22 | + @cached(cache=TTLCache(maxsize=1, ttl=300)) |
| 23 | + def _get_db_handler(self) -> Table: |
| 24 | + dynamodb: DynamoDBServiceResource = boto3.resource('dynamodb') |
| 25 | + return dynamodb.Table(self.table_name) |
| 26 | + |
| 27 | + @tracer.capture_method(capture_response=False) |
| 28 | + def create_order_in_db(self, customer_name: str, order_item_count: int) -> OrderEntry: |
| 29 | + order_id = str(uuid.uuid4()) |
| 30 | + logger.info('trying to save order', extra={'order_id': order_id}) |
| 31 | + try: |
| 32 | + entry = OrderEntry(order_id=order_id, customer_name=customer_name, order_item_count=order_item_count) |
| 33 | + logger.info('opening connection to dynamodb table', extra={'table_name': self.table_name}) |
| 34 | + table: Table = self._get_db_handler() |
| 35 | + table.put_item(Item=entry.dict()) |
| 36 | + except (ClientError, ValidationError) as exc: |
| 37 | + error_msg = 'failed to create order' |
| 38 | + logger.exception(error_msg, extra={'exception': str(exc), 'customer_name': customer_name}) |
| 39 | + raise InternalServerException(error_msg) from exc |
| 40 | + |
| 41 | + logger.info('finished create order', extra={'order_id': order_id, 'order_item_count': order_item_count, 'customer_name': customer_name}) |
| 42 | + return entry |
0 commit comments