Subscription::publish()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 10
cc 2
nc 2
nop 2
crap 2
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\Channel\Subscription;
10
11
use Closure;
12
use Daikon\MessageBus\Channel\Subscription\MessageHandler\MessageHandlerList;
13
use Daikon\MessageBus\Channel\Subscription\Transport\TransportInterface;
14
use Daikon\MessageBus\EnvelopeInterface;
15
use Daikon\MessageBus\Exception\EnvelopeNotAcceptable;
16
use Daikon\MessageBus\MessageBusInterface;
17
use Daikon\Metadata\MetadataInterface;
18
use Daikon\Metadata\MetadataEnricherInterface;
19
use Daikon\Metadata\MetadataEnricherList;
20
21
final class Subscription implements SubscriptionInterface
22
{
23
    private string $key;
24
25
    private TransportInterface $transport;
26
27
    private MessageHandlerList $messageHandlers;
28
29
    private Closure $guard;
30
31
    private MetadataEnricherList $metadataEnrichers;
32
33 7
    public function __construct(
34
        string $key,
35
        TransportInterface $transport,
36
        MessageHandlerList $messageHandlers,
37
        Closure $guard = null,
38
        MetadataEnricherList $metadataEnrichers = null
39
    ) {
40 7
        $this->key = $key;
41 7
        $this->transport = $transport;
42 7
        $this->messageHandlers = $messageHandlers;
43 7
        $this->guard = $guard ?? fn(): bool => true;
44 7
        $metadataEnrichers = $metadataEnrichers ?? new MetadataEnricherList;
45 7
        $this->metadataEnrichers = $metadataEnrichers->enrichWith(self::METADATA_KEY, $this->key);
46 7
    }
47
48 3
    public function publish(EnvelopeInterface $envelope, MessageBusInterface $messageBus): void
49
    {
50 3
        $envelope = $this->enrichMetadata($envelope);
51 3
        if ($this->accepts($envelope)) {
52 2
            $this->transport->send($envelope, $messageBus);
53
        }
54 3
    }
55
56 3
    public function receive(EnvelopeInterface $envelope): void
57
    {
58 3
        $this->verify($envelope);
59 1
        foreach ($this->messageHandlers as $messageHandler) {
60 1
            $messageHandler->handle($envelope);
61
        }
62 1
    }
63
64 1
    public function getKey(): string
65
    {
66 1
        return $this->key;
67
    }
68
69 3
    private function enrichMetadata(EnvelopeInterface $envelope): EnvelopeInterface
70
    {
71 3
        return $envelope->withMetadata(array_reduce(
72 3
            $this->metadataEnrichers->unwrap(),
73 3
            function (MetadataInterface $metadata, MetadataEnricherInterface $metadataEnricher): MetadataInterface {
74 3
                return $metadataEnricher->enrich($metadata);
75 3
            },
76 3
            $envelope->getMetadata()
77
        ));
78
    }
79
80 3
    private function accepts(EnvelopeInterface $envelope): bool
81
    {
82 3
        return (bool)($this->guard)($envelope);
83
    }
84
85 3
    private function verify(EnvelopeInterface $envelope): void
86
    {
87 3
        $metadata = $envelope->getMetadata();
88 3
        if (!$metadata->has(self::METADATA_KEY)) {
89 1
            throw new EnvelopeNotAcceptable(
90 1
                "Subscription key '".self::METADATA_KEY."' missing in metadata of Envelope ".
91 1
                "'{$envelope->getUuid()->toString()}' received by subscription '{$this->key}'.",
92 1
                EnvelopeNotAcceptable::SUBSCRIPTION_KEY_MISSING
93
            );
94
        }
95 2
        $subscriptionKey = $metadata->get(self::METADATA_KEY);
96 2
        if ($subscriptionKey !== $this->key) {
97 1
            throw new EnvelopeNotAcceptable(
98 1
                "Subscription '{$this->key}' inadvertently received Envelope ".
99 1
                "'{$envelope->getUuid()->toString()}' for subscription '$subscriptionKey'.",
100 1
                EnvelopeNotAcceptable::SUBSCRIPTION_KEY_UNEXPECTED
101
            );
102
        }
103 1
    }
104
}
105