JsonRpcEndpoint::getResponseString()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 10
ccs 5
cts 5
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Yoanm\JsonRpcServer\Infra\Endpoint;
3
4
use Yoanm\JsonRpcServer\App\Dispatcher\JsonRpcServerDispatcherAwareTrait;
5
use Yoanm\JsonRpcServer\App\Handler\ExceptionHandler;
6
use Yoanm\JsonRpcServer\App\Handler\JsonRpcRequestHandler;
7
use Yoanm\JsonRpcServer\App\Serialization\JsonRpcCallSerializer;
8
use Yoanm\JsonRpcServer\Domain\Event\Acknowledge as AcknowledgeEvent;
9
use Yoanm\JsonRpcServer\Domain\Exception\JsonRpcInvalidRequestException;
10
use Yoanm\JsonRpcServer\Domain\Exception\JsonRpcParseErrorException;
11
use Yoanm\JsonRpcServer\Domain\Model\JsonRpcCall;
12
use Yoanm\JsonRpcServer\Domain\Model\JsonRpcCallResponse;
13
use Yoanm\JsonRpcServer\Domain\Model\JsonRpcRequest;
14
use Yoanm\JsonRpcServer\Domain\Model\JsonRpcResponse;
15
16
/**
17
 * Class JsonRpcEndpoint
18
 */
19
class JsonRpcEndpoint
20
{
21
    use JsonRpcServerDispatcherAwareTrait;
22
23
    /** @var JsonRpcCallSerializer */
24
    private $jsonRpcCallSerializer;
25
    /** @var JsonRpcRequestHandler */
26
    private $jsonRpcRequestHandler;
27
    /** @var ExceptionHandler */
28
    private $exceptionHandler;
29
30
    /**
31
     * @param JsonRpcCallSerializer $jsonRpcCallSerializer
32
     * @param JsonRpcRequestHandler $jsonRpcRequestHandler
33
     * @param ExceptionHandler      $exceptionHandler
34
     */
35 55
    public function __construct(
36
        JsonRpcCallSerializer $jsonRpcCallSerializer,
37
        JsonRpcRequestHandler $jsonRpcRequestHandler,
38
        ExceptionHandler $exceptionHandler
39
    ) {
40 55
        $this->jsonRpcCallSerializer = $jsonRpcCallSerializer;
41 55
        $this->jsonRpcRequestHandler = $jsonRpcRequestHandler;
42 55
        $this->exceptionHandler = $exceptionHandler;
43
    }
44
45
    /**
46
     * @param string $request
47
     *
48
     * @return string The response
49
     */
50 55
    public function index(string $request) : string
51
    {
52 55
        $jsonRpcCall = null;
53
        try {
54 55
            $jsonRpcCall = $this->getJsonRpcCall($request);
55
56 34
            $jsonRpcCallResponse = $this->getJsonRpcCallResponse($jsonRpcCall);
57
58 34
            return $this->getResponseString($jsonRpcCallResponse, $jsonRpcCall);
59 23
        } catch (\Exception $exception) {
60
            // Try to create a valid json-rpc error
61 23
            $jsonRpcCallResponse = (new JsonRpcCallResponse())->addResponse(
62 23
                $this->exceptionHandler->getJsonRpcResponseFromException($exception)
63 23
            );
64
65 23
            return $this->getResponseString($jsonRpcCallResponse, $jsonRpcCall);
66
        }
67
    }
68
69
    /**
70
     * @param string $request
71
     *
72
     * @return JsonRpcCall
73
     *
74
     * @throws JsonRpcInvalidRequestException
75
     * @throws JsonRpcParseErrorException
76
     */
77 55
    protected function getJsonRpcCall(string $request) : JsonRpcCall
78
    {
79 55
        $jsonRpcCall = $this->jsonRpcCallSerializer->deserialize($request);
80
81 34
        $event = new AcknowledgeEvent\OnRequestReceivedEvent($request, $jsonRpcCall);
82 34
        $this->dispatchJsonRpcEvent($event::EVENT_NAME, $event);
83
84 34
        return $jsonRpcCall;
85
    }
86
87
    /**
88
     * @param JsonRpcCallResponse     $jsonRpcCallResponse
89
     * @param JsonRpcCall|null        $jsonRpcCall
90
     *
91
     * @return string
92
     */
93 55
    protected function getResponseString(
94
        JsonRpcCallResponse $jsonRpcCallResponse,
95
        JsonRpcCall $jsonRpcCall = null
96
    ) : string {
97 55
        $response = $this->jsonRpcCallSerializer->serialize($jsonRpcCallResponse);
98
99 55
        $event = new AcknowledgeEvent\OnResponseSendingEvent($response, $jsonRpcCallResponse, $jsonRpcCall);
100 55
        $this->dispatchJsonRpcEvent($event::EVENT_NAME, $event);
101
102 55
        return $response;
103
    }
104
105
    /**
106
     * @param JsonRpcCall $jsonRpcCall
107
     *
108
     * @return JsonRpcCallResponse
109
     */
110 34
    protected function getJsonRpcCallResponse(JsonRpcCall $jsonRpcCall) : JsonRpcCallResponse
111
    {
112 34
        $jsonRpcCallResponse = new JsonRpcCallResponse($jsonRpcCall->isBatch());
113
114 34
        foreach ($jsonRpcCall->getItemList() as $itemPosition => $item) {
115 34
            if ($jsonRpcCall->isBatch()) {
116 11
                $event = new AcknowledgeEvent\OnBatchSubRequestProcessingEvent($itemPosition);
117 11
                $this->dispatchJsonRpcEvent($event::EVENT_NAME, $event);
118
            }
119 34
            $jsonRpcCallResponse->addResponse(
120 34
                $this->processItem($item)
121 34
            );
122 34
            if ($jsonRpcCall->isBatch()) {
123 11
                $event = new AcknowledgeEvent\OnBatchSubRequestProcessedEvent($itemPosition);
124 11
                $this->dispatchJsonRpcEvent($event::EVENT_NAME, $event);
125
            }
126
        }
127
128 34
        return $jsonRpcCallResponse;
129
    }
130
131
    /**
132
     * @param JsonRpcRequest|\Exception $item
133
     *
134
     * @return JsonRpcResponse
135
     */
136 34
    private function processItem($item) : JsonRpcResponse
137
    {
138
        try {
139 34
            if ($item instanceof \Exception) {
140
                // Exception will be caught just below and converted to response
141 7
                throw $item;
142
            }
143
144 30
            return $this->jsonRpcRequestHandler->processJsonRpcRequest($item);
145 14
        } catch (\Exception $exception) {
146 14
            return $this->exceptionHandler->getJsonRpcResponseFromException(
147 14
                $exception,
148 14
                $item instanceof JsonRpcRequest ? $item : null
149 14
            );
150
        }
151
    }
152
}
153