Completed
Pull Request — master (#70)
by Yo
02:40
created

JsonRpcEndpoint::getJsonRpcCallResponse()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 5
nop 1
dl 0
loc 19
ccs 12
cts 12
cp 1
crap 4
rs 9.9
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 12
    public function __construct(
36
        JsonRpcCallSerializer $jsonRpcCallSerializer,
37
        JsonRpcRequestHandler $jsonRpcRequestHandler,
38
        ExceptionHandler $exceptionHandler
39
    ) {
40 12
        $this->jsonRpcCallSerializer = $jsonRpcCallSerializer;
41 12
        $this->jsonRpcRequestHandler = $jsonRpcRequestHandler;
42 12
        $this->exceptionHandler = $exceptionHandler;
43 12
    }
44
45
    /**
46
     * @param string $request
47
     *
48
     * @return string The response
49
     */
50 12
    public function index(string $request) : string
51
    {
52 12
        $jsonRpcCall = null;
53
        try {
54 12
            $jsonRpcCall = $this->getJsonRpcCall($request);
55
56 10
            $jsonRpcCallResponse = $this->getJsonRpcCallResponse($jsonRpcCall);
57
58 10
            return $this->getResponseString($jsonRpcCallResponse, $jsonRpcCall);
59 4
        } catch (\Exception $exception) {
60
            // Try to create a valid json-rpc error
61 4
            $jsonRpcCallResponse = (new JsonRpcCallResponse())->addResponse(
62 4
                $this->exceptionHandler->getJsonRpcResponseFromException($exception)
63
            );
64
65 4
            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 12
    protected function getJsonRpcCall(string $request) : JsonRpcCall
78
    {
79 12
        $jsonRpcCall = $this->jsonRpcCallSerializer->deserialize($request);
80
81 10
        $event = new AcknowledgeEvent\OnRequestReceivedEvent($request, $jsonRpcCall);
82 10
        $this->dispatchJsonRpcEvent($event::EVENT_NAME, $event);
83
84 10
        return $jsonRpcCall;
85
    }
86
87
    /**
88
     * @param JsonRpcCallResponse     $jsonRpcCallResponse
89
     * @param JsonRpcCall|null        $jsonRpcCall
90
     *
91
     * @return string
92
     */
93 12
    protected function getResponseString(
94
        JsonRpcCallResponse $jsonRpcCallResponse,
95
        JsonRpcCall $jsonRpcCall = null
96
    ) : string {
97 12
        $response = $this->jsonRpcCallSerializer->serialize($jsonRpcCallResponse);
98
99 12
        $event = new AcknowledgeEvent\OnResponseSendingEvent($response, $jsonRpcCallResponse, $jsonRpcCall);
100 12
        $this->dispatchJsonRpcEvent($event::EVENT_NAME, $event);
101
102 12
        return $response;
103
    }
104
105
    /**
106
     * @param JsonRpcCall $jsonRpcCall
107
     *
108
     * @return JsonRpcCallResponse
109
     */
110 10
    protected function getJsonRpcCallResponse(JsonRpcCall $jsonRpcCall) : JsonRpcCallResponse
111
    {
112 10
        $jsonRpcCallResponse = new JsonRpcCallResponse($jsonRpcCall->isBatch());
113
114 10
        foreach ($jsonRpcCall->getItemList() as $itemPosition => $item) {
115 10
            if ($jsonRpcCall->isBatch()) {
116 3
                $event = new AcknowledgeEvent\OnBatchSubRequestProcessingEvent($itemPosition);
117 3
                $this->dispatchJsonRpcEvent($event::EVENT_NAME, $event);
118
            }
119 10
            $jsonRpcCallResponse->addResponse(
120 10
                $this->processItem($item)
121
            );
122 10
            if ($jsonRpcCall->isBatch()) {
123 3
                $event = new AcknowledgeEvent\OnBatchSubRequestProcessedEvent($itemPosition);
124 10
                $this->dispatchJsonRpcEvent($event::EVENT_NAME, $event);
125
            }
126
        }
127
128 10
        return $jsonRpcCallResponse;
129
    }
130
131
    /**
132
     * @param JsonRpcRequest|\Exception $item
133
     *
134
     * @return JsonRpcResponse
135
     */
136 10
    private function processItem($item) : JsonRpcResponse
137
    {
138
        try {
139 10
            if ($item instanceof \Exception) {
140
                // Exception will be caught just below and converted to response
141 2
                throw $item;
142
            }
143
144 9
            return $this->jsonRpcRequestHandler->processJsonRpcRequest($item);
145 4
        } catch (\Exception $exception) {
146 4
            return $this->exceptionHandler->getJsonRpcResponseFromException(
147 4
                $exception,
148 4
                $item instanceof JsonRpcRequest ? $item : null
149
            );
150
        }
151
    }
152
}
153