Esempio n. 1
0
    def resolve_context(
        self, integration: typing.Union[IntegrationEvent,
                                        IntegrationRecord]) -> None:
        if isinstance(integration, IntegrationEvent):
            record = typing.cast(IntegrationRecord,
                                 self.mapper.serialize(integration))
        elif isinstance(integration, IntegrationRecord):
            record = integration

        if record.trace_id not in self.traces:
            raise TraceNotFound()

        trace = self.traces[record.trace_id]
        if record.context in trace.contexts_resolutions:
            trace.contexts_resolutions[
                record.context].resolution = record.resolve
        else:
            trace.contexts_resolutions_unexpected[
                record.context] = ContextResolution(
                    context=record.context,
                    resolution=record.resolve,
                    error=record.error,
                    timestamp=None,
                )
        trace.integrations.append(record)

        self._safe_try_to_resolve_trace(record.trace_id)
Esempio n. 2
0
    def get_resolution(self, trace_id: str) -> TraceResolution:
        item = {
            "TableName": self.table_name,
            "Key": {"trace_id": serialize(trace_id)},
            "ProjectionExpression": "resolution, contexts_resolutions",
            "ConsistentRead": True,
        }
        result = self.client.get_item(**item)

        if "Item" not in result:
            raise TraceNotFound()

        resolution = deserialize(result["Item"]["resolution"])
        contexts_resolutions = deserialize(
            result["Item"]["contexts_resolutions"]
        )

        return TraceResolution(
            resolution=resolution,
            expected=len(contexts_resolutions),
            completed=sum(
                1
                for rc in contexts_resolutions.values()
                if rc["resolution"] != TraceResolution.Resolutions.pending
            ),
            errors=tuple(
                [
                    cr["error"]
                    for cr in contexts_resolutions.values()
                    if cr["error"] is not None
                ]
            ),
        )
Esempio n. 3
0
    def get_integrations(
            self,
            trace_id: str) -> typing.Generator[IntegrationEvent, None, None]:
        if trace_id not in self.traces:
            raise TraceNotFound()

        trace = self.traces[trace_id]
        return (typing.cast(IntegrationEvent, self.mapper.deserialize(i))
                for i in trace.integrations)
Esempio n. 4
0
    def get_resolution(self, trace_id: str) -> TraceResolution:
        if trace_id not in self.traces:
            raise TraceNotFound()

        trace = self.traces[trace_id]
        return TraceResolution(
            resolution=trace.resolution,
            expected=len(trace.contexts_resolutions),
            completed=sum(
                1 for rc in trace.contexts_resolutions.values()
                if rc.resolution != TraceResolution.Resolutions.pending),
            errors=tuple([
                rc.error for rc in trace.contexts_resolutions.values()
                if rc.error is not None
            ]),
        )
Esempio n. 5
0
    def get_resolution(
            self,
            trace_id: str,
            topic: str,
            context: typing.Optional[str] = None) -> typing.Optional[str]:
        subject = topic
        if context is not None:
            subject = f"{context}:{topic}"

        trace_segment_id = self._get_trace_segment_id(trace_id, subject)

        if trace_segment_id not in self.segments:
            raise TraceNotFound()

        trace_segment = self.segments[trace_segment_id]
        return trace_segment.resolution
Esempio n. 6
0
    def resolve_trace_segment_failure(self, request: InfrastructureMessage,
                                      exc: typing.Type[Exception]) -> None:
        record = self.mapper.serialize(request)

        subject = record.topic
        if isinstance(record, EventRecord):
            subject = f"{record.context}:{record.topic}"

        trace_segment_id = self._get_trace_segment_id(record.trace_id, subject)

        if trace_segment_id not in self.segments:
            raise TraceNotFound()

        epoch = datetime.datetime.utcnow().timestamp()

        trace_segment = self.segments[trace_segment_id]
        trace_segment.resolution = TraceResolution.Resolutions.failure
        trace_segment.error = str(exc)
        trace_segment.timestamp_resolution = epoch
Esempio n. 7
0
    def resolve_context(
        self, integration: typing.Union[IntegrationEvent, IntegrationRecord]
    ) -> None:
        if isinstance(integration, IntegrationEvent):
            integration_record = typing.cast(
                IntegrationRecord, self.mapper.serialize(integration)
            )
        elif isinstance(integration, IntegrationRecord):
            integration_record = integration

        try:
            self._try_update_with_expected_context(integration_record)
        except self.client.exceptions.ConditionalCheckFailedException:
            try:
                # Unexpected context
                self._try_update_with_unexpected_context(integration_record)
            except (
                self.client.exceptions.ConditionalCheckFailedException
            ) as error:
                raise TraceNotFound() from error

        self._safe_try_to_resolve_trace(integration_record.trace_id)
Esempio n. 8
0
    def get_integrations(
        self, trace_id: str
    ) -> typing.Generator[IntegrationEvent, None, None]:
        item = {
            "TableName": self.table_name,
            "Key": {"trace_id": serialize(trace_id)},
            "ProjectionExpression": "integrations",
            "ConsistentRead": True,
        }
        result = self.client.get_item(**item)

        if "Item" not in result:
            raise TraceNotFound()

        integrations = deserialize(result["Item"]["integrations"])

        return typing.cast(
            typing.Generator[IntegrationEvent, None, None],
            (
                self.mapper.deserialize(record_fromdict(i))
                for i in integrations
            ),
        )