"""Lambda function module.""" import uuid from ddex_ingester_common.constants.country_codes import ALL_COUNTRY_CODES from ddex_ingester_common.lambda_exceptions import ( HandlePurgedReleaseException, OrchardProductNotFoundException) from ddex_ingester_common.logging import utils as logging_utils from ddex_ingester_common.schemas.state_machine_schema import \ StateMachineSchema from lambdacommon.graphql import graphql import config from config import graphql_gateway from constants import queries logger = logging_utils.get_logger(config.app_logger) def handler(event, context): """Handle purging releases.""" state_machine_data = StateMachineSchema().load(event) correlation_id = state_machine_data.correlation_id or str(uuid.uuid4()) state_machine_data.correlation_id = correlation_id logging_utils.update_logger_correlation_id(logger, correlation_id) logging_utils.update_logger_with_message_ids( logger, state_machine_data.message_id, state_machine_data.message_thread_id, state_machine_data.execution_name ) logger.info(f'Triggered handle_purged_release: {event}') if not state_machine_data.product.upc: logger.info('No UPC found, skipped handle_purged_release') return StateMachineSchema().dump(state_machine_data) graphql_gateway.set_headers( { 'Orchard-User-Id': config.OA_USER, 'Correlation-Id': correlation_id, } ) graphql_result = get_product_metadata(state_machine_data) if not graphql_result: raise_product_not_found_exception(state_machine_data) enrich_product_id(state_machine_data, graphql_result) upc = state_machine_data.product.upc if not graphql_result.get('productId'): raise ValueError(f'Product for {upc} not found.') carveout_data = format_carveout_data( state_machine_data.product.product_id, state_machine_data.product.upc ) if not carveout_data: raise HandlePurgedReleaseException( 'Product Deal includes a Takedown.' ) try: graphql_conn = graphql.GraphQLConnector( config.GRAPHQL_GATEWAY_URL, config.APPLICATION_NAME) graphql_conn.set_headers({'Orchard-User-Id': config.OA_USER}) # call ows-carveouts graphql_conn.execute( queries.set_carveouts, {'data': carveout_data}) except graphql.GraphQLError as err: raise HandlePurgedReleaseException('Graphql error') from err except Exception as exp: raise HandlePurgedReleaseException( f'Error processing carveout.\n{exp}') from exp return StateMachineSchema().dump(state_machine_data) def enrich_product_id(context: object, result: dict): """Enrich context product id. Args: context (object): Context object result (dict): GraphQL response """ product_id = result.get('productId') if not product_id: raise ValueError('Product ID not found.') logger.info(f'Found product id: {product_id}') context.product.product_id = product_id def raise_product_not_found_exception(context): """Encapsulate our raise call for testability.""" raise OrchardProductNotFoundException( f'Product id was not found for UPC: {context.product.upc}') def get_product_metadata(context: object) -> dict: """Get product metadata via GraphQL. Args: context (object): Context object Returns: result (dict): GraphQL response """ upc = context.product.upc result = graphql_gateway.execute( queries.get_product_by_upc, {'upc': upc} )['data']['productByUpc'] logger.info(f'Graphql result: {result}') return result def format_carveout_data(product_id, upc): """Format data for set_carveouts mutation. Args: product_id (int): Product ID upc (str): UPC Returns: dict """ return { 'productId': product_id, 'upc': upc, 'countryCodes': ALL_COUNTRY_CODES, }