DeserializeLogicalMessageConnector::invoke()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 7
cts 7
cp 1
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 2
1
<?php
2
namespace PSB\Core\Serialization\Pipeline;
3
4
5
use PSB\Core\Exception\MessageDeserializationException;
6
use PSB\Core\HeaderTypeEnum;
7
use PSB\Core\Pipeline\Incoming\IncomingContextFactory;
8
use PSB\Core\Pipeline\Incoming\IncomingLogicalMessage;
9
use PSB\Core\Pipeline\Incoming\IncomingLogicalMessageFactory;
10
use PSB\Core\Pipeline\Incoming\StageContext\IncomingLogicalMessageContext;
11
use PSB\Core\Pipeline\Incoming\StageContext\IncomingPhysicalMessageContext;
12
use PSB\Core\Pipeline\StageConnectorInterface;
13
use PSB\Core\Serialization\MessageDeserializerResolver;
14
use PSB\Core\Transport\IncomingPhysicalMessage;
15
16
class DeserializeLogicalMessageConnector implements StageConnectorInterface
17
{
18
    /**
19
     * @var MessageDeserializerResolver
20
     */
21
    private $deserializerResolver;
22
23
    /**
24
     * @var IncomingLogicalMessageFactory
25
     */
26
    private $logicalMessageFactory;
27
28
    /**
29
     * @var IncomingContextFactory
30
     */
31
    private $incomingContextFactory;
32
33
    /**
34
     * @param MessageDeserializerResolver   $deserializerResolver
35
     * @param IncomingLogicalMessageFactory $logicalMessageFactory
36
     * @param IncomingContextFactory        $incomingContextFactory
37
     */
38 7
    public function __construct(
39
        MessageDeserializerResolver $deserializerResolver,
40
        IncomingLogicalMessageFactory $logicalMessageFactory,
41
        IncomingContextFactory $incomingContextFactory
42
    ) {
43
44 7
        $this->deserializerResolver = $deserializerResolver;
45 7
        $this->logicalMessageFactory = $logicalMessageFactory;
46 7
        $this->incomingContextFactory = $incomingContextFactory;
47 7
    }
48
49
    /**
50
     * @param IncomingPhysicalMessageContext $context
51
     * @param callable                       $next
52
     */
53 4
    public function invoke($context, callable $next)
54
    {
55 4
        $physicalMessage = $context->getMessage();
56
57 4
        $logicalMessage = $this->extractWithExceptionHandling($physicalMessage);
58
59 3
        if (!$logicalMessage) {
60 2
            throw new MessageDeserializationException($physicalMessage->getMessageId());
61
        }
62
63 1
        $next($this->incomingContextFactory->createLogicalMessageContext($logicalMessage, $context));
64 1
    }
65
66
    /**
67
     * @param IncomingPhysicalMessage $physicalMessage
68
     *
69
     * @return IncomingLogicalMessage|null
70
     */
71 4
    private function extractWithExceptionHandling(IncomingPhysicalMessage $physicalMessage)
72
    {
73
        try {
74 4
            return $this->extractMessage($physicalMessage);
75 1
        } catch (\Throwable $t) {
76 1
            throw new MessageDeserializationException($physicalMessage->getMessageId(), $t);
77
        }
78
    }
79
80
    /**
81
     * @param IncomingPhysicalMessage $physicalMessage
82
     *
83
     * @return IncomingLogicalMessage|null
84
     */
85 4
    private function extractMessage(IncomingPhysicalMessage $physicalMessage)
86
    {
87 4
        $body = $physicalMessage->getBody();
88 4
        if ($body === null || $body === '') {
89 1
            return null;
90
        }
91
92 3
        if (!isset($physicalMessage->getHeaders()[HeaderTypeEnum::ENCLOSED_CLASS])) {
93 1
            return null;
94
        }
95
96 2
        $messageClass = $physicalMessage->getHeaders()[HeaderTypeEnum::ENCLOSED_CLASS];
97 2
        $serializer = $this->deserializerResolver->resolve($physicalMessage->getHeaders());
98 2
        $instanceMessage = $serializer->deserialize($body, $messageClass);
99
100 1
        return $this->logicalMessageFactory->createFromObject($instanceMessage);
101
    }
102
103
    /**
104
     * @return string
105
     */
106 1
    public static function getStageContextClass()
107
    {
108 1
        return IncomingPhysicalMessageContext::class;
109
    }
110
111
    /**
112
     * @return string
113
     */
114 1
    public static function getNextStageContextClass()
115
    {
116 1
        return IncomingLogicalMessageContext::class;
117
    }
118
}
119