"""Lambda signup function module.""" import hashlib import json import uuid from kafka import KafkaProducer from lambdacommon.common_config import logger from marshmallow import ValidationError from . import config from . import consts from .schema import ArtistSignupSchema producer = KafkaProducer(**{ 'bootstrap_servers': config.BOOTSTRAP_SERVERS, 'security_protocol': 'SSL', 'client_id': config.CLIENT_ID, 'linger_ms': config.LINGER_MS, 'api_version': config.KAFKA_API_VERSION }) def generate_salesforce_id(email: str, artist_name: str) -> str: """Generate salesforce Lead id. Create a salted hash of the fields to generate a unique lead id. This will give us the same id for multiple form submissions with the same email, artist name and the data will be upserted into Salesforce. """ data = ''.join(s.lower() for s in [email, artist_name]) data += consts.SALT email_hash = hashlib.sha256(data.encode()) return email_hash.hexdigest() def handler(event: dict, context: dict) -> dict: """Lambda entry point.""" try: status_code = 200 response_str = 'ok' data = event.get('body') if not data: raise ValueError(consts.ERROR_EMPTY_BODY) correlation_id = event.get( 'headers', {}).get('correlation-id', str(uuid.uuid4())) if config.LOG_REQUEST_PAYLOAD: logger.info(data) json_data = ArtistSignupSchema().loads(data) lead_id = generate_salesforce_id( json_data['email'], json_data['company']) json_data['record_type_id'] = config.SALESFORCE_RECORD_TYPE_ID json_data['correlation_id'] = correlation_id json_data['kafka_message_headers'] = { consts.ID_HEADER: lead_id, consts.CORRELATION_ID_HEADER: correlation_id } producer.send( config.TOPIC_NAME, ArtistSignupSchema().dumps(json_data).encode(), headers=[ (consts.ID_HEADER, lead_id.encode()), (consts.CORRELATION_ID_HEADER, correlation_id.encode()), ]) producer.flush() except ValueError as e: error_msg = str(e) logger.error(error_msg) status_code = 400 response_str = str(error_msg) except ValidationError as e: error_msg = e.messages logger.error(error_msg) status_code = 400 response_str = error_msg except Exception as e: logger.exception(consts.ERROR_LAMBDA_FAILURE, exc_info=e) status_code = 500 response_str = str(e) finally: return { 'statusCode': status_code, 'headers': {'content-type': 'application/json'}, 'body': json.dumps({'response': response_str}) }