def _try_update_with_unexpected_context( self, integration_record: IntegrationRecord ): epoch = datetime.datetime.utcnow().timestamp() item = { "TableName": self.table_name, "Key": {"trace_id": serialize(integration_record.trace_id)}, "UpdateExpression": "SET " " contexts_resolutions_unexpected.#context = :context_resolution, " # noqa: E501 " integrations = list_append(integrations, :new_integrations)", "ExpressionAttributeNames": { "#context": integration_record.context }, "ExpressionAttributeValues": { ":context_resolution": serialize( { "context": integration_record.context, "resolution": integration_record.resolve, "error": integration_record.error, "timestamp": epoch, } ), ":new_integrations": serialize( [record_asdict(integration_record)] ), }, # "ConditionExpression": """ # attribute_exists(trace_id) # """ } self.client.update_item(**item)
def start_trace_segment( self, request: InfrastructureMessage ) -> TraceSegmentRecorder: record = self.mapper.serialize(request) subject = record.topic if isinstance(record, EventRecord): subject = f"{record.context}:{record.topic}" epoch = datetime.datetime.utcnow().timestamp() item = { "TableName": self.table_name, "Item": { "trace_id": serialize(record.trace_id), "subject": serialize(subject), "timestamp": serialize(epoch), "timestamp_resolution": serialize(None), "request": serialize(record_asdict(record)), "resolution": serialize(TraceResolution.Resolutions.pending), "error": serialize(None), }, "ConditionExpression": "(attribute_not_exists(trace_id) " "and attribute_not_exists(topic)) " "or resolution = :failure", "ExpressionAttributeValues": { ":failure": serialize(TraceResolution.Resolutions.failure) }, } try: self.client.put_item(**item) except self.client.exceptions.ConditionalCheckFailedException as error: raise IdempotencyItemError() from error return TraceSegmentRecorder(request, self)
def record(): return record_asdict( CommandRecord(trace_id='tid', topic='ApplicationCommand', version=1, timestamp=0.0, message=MessageType.APPLICATION_COMMAND.value, payload={}))
def start_trace( self, request: typing.Union[ ApplicationCommand, ApplicationQuery, IntegrationEvent ], ) -> None: try: resolvers = getattr(request, "__resolvers__") except AttributeError as error: raise DefinitionError( "request should have __resolvers__: " f"{request.__class__.__name__}" ) from error record = self.mapper.serialize(request) epoch = datetime.datetime.utcnow().timestamp() epoch_resolution = None resolution = TraceResolution.Resolutions.pending if len(resolvers) == 0: epoch_resolution = epoch resolution = TraceResolution.Resolutions.success item = { "TableName": self.table_name, "Item": { "trace_id": serialize(record.trace_id), "topic": serialize(record.topic), "message": serialize(record.message), "request": serialize(record_asdict(record)), "resolution": serialize(resolution), "version": serialize(1), "timestamp": serialize(epoch), "timestamp_resolution": serialize(epoch_resolution), "contexts_resolutions": serialize( { context: { "context": context, "resolution": TraceResolution.Resolutions.pending, "error": None, "timestamp": None, } for context in resolvers } ), "contexts_resolutions_unexpected": serialize({}), "integrations": serialize([]), }, "ConditionExpression": "attribute_not_exists(trace_id)", } try: self.client.put_item(**item) except self.client.exceptions.ConditionalCheckFailedException as error: raise IdempotencyItemError() from error
def _publish_with_partition_key(self, messages: SequenceOfInfrastructureMessage): entries = [{ "TableName": self.table_name, "Item": { "trace_id": serialize(m.__trace_id__), "body": serialize(record_asdict(self.mapper.serialize(m))), }, } for m in messages] for entry in entries: self.client.put_item(**entry)
def _publish( self, messages: typing.Sequence[InfrastructureMessage], ): entries = [{ "stateMachineArn": self.state_machine_arn, "input": json.dumps({ "publish_at": getattr(m, m.__publish_at_field__), "payload": record_asdict(self.mapper.serialize(m)), }), } for m in messages if isinstance(m, ScheduleIntegartionEvent)] for entry in entries: self.client.start_execution(**entry)
def _publish_with_partition_key_and_sort_key( self, messages: SequenceOfInfrastructureMessage): _sort_key = self.sort_key if _sort_key is None: raise ValueError("sort_key should not be NoneType") entries = [{ "TableName": self.table_name, "Item": { "trace_id": serialize(m.__trace_id__), _sort_key: serialize(getattr(messages, _sort_key)), "body": serialize(record_asdict(self.mapper.serialize(m))), }, } for m in messages] for entry in entries: self.client.put_item(**entry)
def _publish( self, messages: typing.Sequence[InfrastructureMessage], ): entries = [{ "QueueUrl": self.queue_url, "MessageBody": json.dumps(record_asdict(self.mapper.serialize(m))), } for m in messages] errors = [] for i, entry in enumerate(entries): try: self.client.send_message(**entry) except Exception as error: # pylint: disable=broad-except errors.append( PublisherError.EntryError(messages[i], str(error))) if len(errors) > 0: raise PublisherError(errors)
def _publish( self, messages: typing.Sequence[InfrastructureMessage], ): entries = [{ "Source": self.context, "Detail": json.dumps(record_asdict(self.mapper.serialize(m))), "DetailType": m.__class__.__name__, "EventBusName": self.bus_name, } for m in messages] response = self.client.put_events(Entries=entries) if response["FailedEntryCount"] > 0: errors = [ PublisherError.EntryError(messages[i], e["ErrorCode"]) for i, e in enumerate(response["Entries"]) if "EventId" not in e # Failed ] raise PublisherError(errors)
def _publish( self, messages: typing.Sequence[InfrastructureMessage], ): entries = [ { "TopicArn": self.topic_arn, "MessageAttributes": { "subject": { "DataType": "String", "StringValue": ( f"{self.context}:{m.__class__.__name__}" ), }, "context": { "DataType": "String", "StringValue": self.context, }, "topic": { "DataType": "String", "StringValue": m.__class__.__name__, }, }, "Message": json.dumps(record_asdict(self.mapper.serialize(m))), } for m in messages ] errors = [] for i, entry in enumerate(entries): try: self.client.publish(**entry) except Exception as error: # pylint: disable=broad-except errors.append(PublisherError.EntryError(entries[i], error)) if len(errors) > 0: raise PublisherError(errors)