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
introduced
by
![]() |
|||
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 |