Passed
Push — master ( 905821...42a403 )
by Mr
07:23
created

MessageBus::publish()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 12
rs 10
c 0
b 0
f 0
ccs 8
cts 8
cp 1
cc 2
nc 2
nop 3
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;
10
11
use Daikon\MessageBus\Channel\ChannelInterface;
12
use Daikon\MessageBus\Channel\ChannelMap;
13
use Daikon\MessageBus\Error\ChannelUnknown;
14
use Daikon\MessageBus\Error\EnvelopeNotAcceptable;
15
use Daikon\Metadata\MetadataInterface;
16
use Daikon\Metadata\Metadata;
17
use Daikon\Metadata\MetadataEnricherInterface;
18
use Daikon\Metadata\MetadataEnricherList;
19
20
final class MessageBus implements MessageBusInterface
21
{
22
    private ChannelMap $channelMap;
23
24
    private MetadataEnricherList $metadataEnrichers;
25
26
    private string $envelopeType;
27
28 5
    public function __construct(
29
        ChannelMap $channelMap,
30
        MetadataEnricherList $metadataEnrichers = null,
31
        string $envelopeType = null
32
    ) {
33 5
        $this->channelMap = $channelMap;
34 5
        $this->metadataEnrichers = $metadataEnrichers ?? new MetadataEnricherList;
35 5
        $this->envelopeType = $envelopeType ?? Envelope::class;
36 5
    }
37
38 2
    public function publish(MessageInterface $message, string $channelKey, MetadataInterface $metadata = null): void
39
    {
40 2
        if (!$this->channelMap->has($channelKey)) {
41 1
            throw new ChannelUnknown("Channel '$channelKey' has not been registered on message bus.");
42
        }
43 1
        $metadata = $this->enrichMetadata($metadata ?? Metadata::makeEmpty());
44 1
        $envelopeType = $this->envelopeType;
45
        /** @var EnvelopeInterface $envelope */
46 1
        $envelope = $envelopeType::wrap($message, $metadata);
47
        /** @var ChannelInterface $channel */
48 1
        $channel = $this->channelMap->get($channelKey);
49 1
        $channel->publish($envelope, $this);
50 1
    }
51
52 3
    public function receive(EnvelopeInterface $envelope): void
53
    {
54 3
        $this->verify($envelope);
55 2
        $channelKey = (string)$envelope->getMetadata()->get(ChannelInterface::METADATA_KEY);
56 2
        if (!$this->channelMap->has($channelKey)) {
57 1
            throw new ChannelUnknown("Channel '$channelKey' has not been registered on message bus.");
58
        }
59
        /** @var ChannelInterface $channel */
60 1
        $channel = $this->channelMap->get($channelKey);
61 1
        $channel->receive($envelope);
62 1
    }
63
64 1
    private function enrichMetadata(MetadataInterface $metadata): MetadataInterface
65
    {
66 1
        return array_reduce(
67 1
            $this->metadataEnrichers->unwrap(),
68
            function (MetadataInterface $metadata, MetadataEnricherInterface $metadataEnricher): MetadataInterface {
69
                return $metadataEnricher->enrich($metadata);
70 1
            },
71
            $metadata
72
        );
73
    }
74
75 3
    private function verify(EnvelopeInterface $envelope): void
76
    {
77 3
        $metadata = $envelope->getMetadata();
78 3
        if (!$metadata->has(ChannelInterface::METADATA_KEY)) {
79 1
            throw new EnvelopeNotAcceptable(
80
                "Channel key '".ChannelInterface::METADATA_KEY."' missing in metadata of ".
81 1
                "Envelope '{$envelope->getUuid()->toString()}' received on message bus.",
82 1
                EnvelopeNotAcceptable::CHANNEL_KEY_MISSING
83
            );
84
        }
85 2
    }
86
}
87