"""Amazon SQS connector. ======================== """ import boto3 from ddtrace import tracer from salessheets.connectors.loggly import get_current_logger from salessheets.connectors.sentry import sentry_capture_exception from salessheets.utils.misc import DotDict CORRELATION_ID_ATTRIBUTE = 'Correlation-Id' FEATURE_FLAG_USER_CONTEXT_ATTRIBUTE = 'feature_flag_user_context' APPROXIMATE_RECEIVE_COUNT_ATTRIBUTE = 'ApproximateReceiveCount' class JSONMessageExt(): """Wrapper for SQS Messages for a logger with Correlation-Id.""" def __init__(self, message=None): """Create new instance of JSONMessageExt """ self._message = message self._context = DotDict() @property def context(self): """Store an additional context for message (e.g. logging adapter). Returns: DotDict: an object that holds message context """ return self._context @property def correlation_id(self): """Get Correlation-Id extracted from message attributes. Returns: str: correlation Id """ correlation_attribute = self._message['MessageAttributes']['Correlation-Id']['StringValue'] # noqa return correlation_attribute @property def feature_flag_user_context(self): """Get feature_flag_user_context extracted from message attributes. Returns: str: feature flag user context """ feature_flag_user_context_attribute = self._message['MessageAttributes']['feature_flag_user_context']['StringValue'] # noqa return feature_flag_user_context_attribute @property def logger(self): """Get logging adapter for current message. Returns: OwsLoggingAdapter: Logging adapter with Correlation-Id, extracted from SQS message attributes. """ if not self.context.logger: self.context.logger = get_current_logger(self.correlation_id) return self.context.logger @property def receive_count(self): """Get approximate message receive count. Returns: int: approximate number of times the message has been received """ count = self._message['ApproximateReceiveCount'] return int(count) @tracer.wrap() def get_connection( region='us-east-1', access_key_id=None, secret_access_key=None): """Get connection to Amazon SQS services. Args: region (str): AWS Region access_key_id (str): AWS Access key ID secret_access_key (str): Corresponding AWS Secret Access Key Returns: SQSConnection: instance of SQSConnection class """ connection = boto3.client( 'sqs', region_name=region) return connection @tracer.wrap() def get_queue(queue_name, message_class=JSONMessageExt, sqs_connection=None): """Get Amazon SQS queue. Args: queue_name (str): Name of the SQS queue to get message_class (class): Optional message class to wrap the received messages sqs_connection (boto.sqs.connection.SQSConnection): Optional existing SQS connection object Returns: Queue: Instance of Amazon SQS queue """ try: connection = sqs_connection if sqs_connection else get_connection() queue = connection.get_queue_url( QueueName=queue_name).get('QueueUrl') return queue except: if sentry_capture_exception: sentry_capture_exception() return None