Issues (12)

src/Envelope.php (1 issue)

Severity
1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the daikon-cqrs/message-bus project.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Daikon\MessageBus;
10
11
use DateTimeImmutable;
12
use Daikon\MessageBus\Exception\EnvelopeNotAcceptable;
13
use Daikon\MessageBus\MessageInterface;
14
use Daikon\Metadata\Metadata;
15
use Daikon\Metadata\MetadataInterface;
16
use Ramsey\Uuid\UuidInterface;
17
use Ramsey\Uuid\Uuid;
18
19
final class Envelope implements EnvelopeInterface
20
{
21
    private UuidInterface $uuid;
22
23
    private DateTimeImmutable $timestamp;
24
25
    private MessageInterface $message;
26
27
    private MetadataInterface $metadata;
28
29 21
    public static function wrap(MessageInterface $message, MetadataInterface $metadata = null): self
30
    {
31 21
        return new self($message, $metadata);
32
    }
33
34 21
    private function __construct(
35
        MessageInterface $message,
36
        MetadataInterface $metadata = null,
37
        UuidInterface $uuid = null,
38
        DateTimeImmutable $timestamp = null
39
    ) {
40 21
        $this->message = $message;
41 21
        $this->metadata = $metadata ?? Metadata::makeEmpty();
42 21
        $this->uuid = $uuid ?? Uuid::uuid4();
43 21
        $this->timestamp = $timestamp ?? new DateTimeImmutable;
44 21
    }
45
46 1
    public function getTimestamp(): DateTimeImmutable
47
    {
48 1
        return $this->timestamp;
49
    }
50
51 12
    public function getUuid(): UuidInterface
52
    {
53 12
        return $this->uuid;
54
    }
55
56 18
    public function getMetadata(): MetadataInterface
57
    {
58 18
        return $this->metadata;
59
    }
60
61 6
    public function withMetadata(MetadataInterface $metadata): self
62
    {
63 6
        $copy = clone $this;
64 6
        $copy->metadata = $metadata;
65 6
        return $copy;
66
    }
67
68 2
    public function getMessage(): MessageInterface
69
    {
70 2
        return $this->message;
71
    }
72
73 1
    public function toNative(): array
74
    {
75
        return [
76 1
            'uuid' => $this->uuid->toString(),
77 1
            'timestamp' => $this->timestamp->format(self::TIMESTAMP_FORMAT),
78 1
            'metadata' => $this->metadata->toNative(),
79 1
            'message' => $this->message->toNative(),
80 1
            '@message_type' => get_class($this->message),
81 1
            '@metadata_type' => get_class($this->metadata)
82
        ];
83
    }
84
85
    /** @param array $state */
86 1
    public static function fromNative($state): self
87
    {
88 1
        $uuid = isset($state['uuid']) ? Uuid::fromString($state['uuid']) : null;
89
90 1
        $timestamp = isset($state['timestamp'])
91 1
            ? DateTimeImmutable::createFromFormat(self::TIMESTAMP_FORMAT, $state['timestamp'])
92 1
            : null;
93 1
        if (false === $timestamp) {
0 ignored issues
show
The condition false === $timestamp is always false.
Loading history...
94
            throw new EnvelopeNotAcceptable('Unable to parse given timestamp.', EnvelopeNotAcceptable::UNPARSEABLE);
95
        }
96
97 1
        $messageType = $state['@message_type'] ?? null;
98 1
        if (is_null($messageType) || !is_subclass_of($messageType, MessageInterface::class)) {
99
            throw new EnvelopeNotAcceptable(
100
                sprintf("Message type '%s' given must be an instance of MessageInterface.", $messageType ?? 'null'),
101
                EnvelopeNotAcceptable::UNPARSEABLE
102
            );
103
        }
104
105 1
        $metadataType = $state['@metadata_type'] ?? null;
106
        /** @var MetadataInterface $metadata */
107 1
        $metadata = $metadataType instanceof MetadataInterface
108
            ? $metadataType::fromNative($state['metadata'])
109 1
            : Metadata::fromNative($state['metadata'] ?? []);
110
111
        /** @var MessageInterface $message */
112 1
        $message = $messageType::fromNative($state['message'] ?? null);
113
114 1
        return new self($message, $metadata, $uuid, $timestamp);
115
    }
116
}
117