Completed
Push — master ( bd2805...cafee2 )
by JHONATAN
02:26
created

WebserviceClient::get()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3.009

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 9
cts 10
cp 0.9
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 9
nc 3
nop 2
crap 3.009
1
<?php
2
3
namespace Vox\Webservice;
4
5
use GuzzleHttp\ClientInterface;
6
use GuzzleHttp\Psr7\Request;
7
use GuzzleHttp\Psr7\Response;
8
use function GuzzleHttp\Psr7\stream_for;
9
use Metadata\MetadataFactoryInterface;
10
use RuntimeException;
11
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
12
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
13
use Vox\Webservice\Exception\WebserviceResponseException;
14
use Vox\Webservice\Mapping\Resource;
15
use Vox\Webservice\Metadata\TransferMetadata;
16
17
/**
18
 * the webservice client does the actual work of consuming and publishing data to the external webservices
19
 *
20
 * @author Jhonatan Teixeira <[email protected]>
21
 */
22
class WebserviceClient implements WebserviceClientInterface
23
{
24
    /**
25
     * @var ClientRegistryInterface
26
     */
27
    private $clientRegistry;
28
29
    /**
30
     * @var MetadataFactoryInterface
31
     */
32
    private $metadataFactory;
33
34
    /**
35
     * @var DenormalizerInterface
36
     */
37
    private $denormalizer;
38
39
    /**
40
     * @var NormalizerInterface
41
     */
42
    private $normalizer;
43
44 30
    public function __construct(
45
        ClientRegistryInterface $clientRegistry,
46
        MetadataFactoryInterface $metadataFactory,
47
        DenormalizerInterface $denormalizer,
48
        NormalizerInterface $normalizer
49
    ) {
50 30
        $this->clientRegistry  = $clientRegistry;
51 30
        $this->metadataFactory = $metadataFactory;
52 30
        $this->denormalizer    = $denormalizer;
53 30
        $this->normalizer      = $normalizer;
54 30
    }
55
56 10
    public function cGet(string $transferName, array $filters = []): TransferCollection
57
    {
58 10
        $resource = $this->getResource($transferName);
59 10
        $client   = $this->getClient($transferName);
60 10
        $options  = ['headers' => ['Content-Type' => 'application/json']];
61
62 10
        if (!empty($filters)) {
63 6
            $options['query'] = $filters;
64
        }
65
66 10
        $response = $client->request('GET', $resource->route, $options);
67
68 10
        if ($response->getStatusCode() >= 300) {
69 3
            throw new WebserviceResponseException($response, new Request('GET', $resource->route, $options));
70
        }
71
72 7
        return new TransferCollection($transferName, $this->denormalizer, $response);
73
    }
74
75 1
    public function delete(string $transferName, $id)
76
    {
77 1
        $resource = $this->getResource($transferName);
78 1
        $client   = $this->getClient($transferName);
79 1
        $route    = sprintf('%s/%s', $resource->route, $id);
80 1
        $response = $client->request('DELETE', $route);
81
82 1
        if ($response->getStatusCode() >= 300) {
83
            throw new WebserviceResponseException($response, new Request('DELETE', $route));
84
        }
85 1
    }
86
87 10
    public function get(string $transferName, $id)
88
    {
89 10
        $resource = $this->getResource($transferName);
90 10
        $client   = $this->getClient($transferName);
91 10
        $route    = sprintf('%s/%s', $resource->route, $id);
92 10
        $response = $client->request('GET', $route, ['headers' => ['Content-Type' => 'application/json']]);
93
94 10
        if ($response->getStatusCode() >= 300) {
95
            throw new WebserviceResponseException($response, new Request('GET', $route));
96
        }
97
98 10
        $contents = $response->getBody()->getContents();
99
        
100 10
        if ($contents) {
101 10
            return $this->denormalizer->denormalize(json_decode($contents, true), $transferName);
102
        }
103
    }
104
105 6
    public function post($transfer)
106
    {
107 6
        $data = $this->normalizer->normalize($transfer, 'json');
108
109 6
        $resource = $this->getResource(get_class($transfer));
110 6
        $client   = $this->getClient(get_class($transfer));
111 6
        $response = $client->request('POST', $resource->route, ['json' => $data]);
112
113 6
        if ($response->getStatusCode() >= 300) {
114 1
            throw new WebserviceResponseException($response, new Request('POST', $resource->route, ['json' => $data]));
115
        }
116
117 5
        $contents = $response->getBody()->getContents();
118 5
        $this->denormalizer->denormalize(json_decode($contents, true), $transfer);
119 5
    }
120
121 2
    public function put($transfer)
122
    {
123 2
        $data     = $this->normalizer->normalize($transfer, 'json');
124 2
        $metadata = $this->getMetadata(get_class($transfer));
125 2
        $resource = $this->getResource(get_class($transfer));
126 2
        $client   = $this->getClient(get_class($transfer));
127
128 2
        if (empty($metadata->id)) {
129
            throw new RuntimeException('no id mapped for class ' . get_class($transfer));
130
        }
131
132 2
        $route    = sprintf('%s/%s', $resource->route, $metadata->id->getValue($transfer));
133 2
        $response = $client->request('PUT', $route, ['json' => $data]);
134
135 2
        if ($response->getStatusCode() >= 300) {
136
            throw new WebserviceResponseException($response, new Request('PUT', $route, ['json' => $data]));
137
        }
138
139 2
        $this->denormalizer->denormalize(json_decode($response->getBody()->getContents(), true), $transfer);
140 2
    }
141
142 4
    public function getByCriteria(CriteriaInterface $criteria, string $transferName)
143
    {
144 4
        $client   = $this->getClient($transferName);
145
146 4
        $request = $criteria->createRequest($this->getMetadata($transferName));
147
148 4
        $response = $client->send($request);
149
150 4
        if ($response->getStatusCode() >= 300) {
151 2
            throw new WebserviceResponseException($response, $request);
152
        }
153
154 2
        if ($criteria->getOperationType() == CriteriaInterface::OPERATION_TYPE_ITEM) {
155 1
            $contents = $response->getBody()->getContents();
156 1
            return $this->denormalizer->denormalize(json_decode($contents, true), $transferName);
157
        }
158
159 1
        if ($criteria->getOperationType() == CriteriaInterface::OPERATION_TYPE_COLLECTION) {
160 1
            return new TransferCollection($transferName, $this->denormalizer, $response);
161
        }
162
    }
163
164 25
    private function getClient(string $transferName, Resource $resource = null): ClientInterface
165
    {
166 25
        if (null === $resource) {
167 25
            $resource = $this->getResource($transferName);
168
        }
169
170 25
        return  $this->clientRegistry->get($resource->client);
171
    }
172
173 25
    private function getResource(string $transferName): Resource
174
    {
175 25
        return $this->getMetadata($transferName)->getAnnotation(Resource::class, true);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getMetadat...\Resource::class, true) could return the type null which is incompatible with the type-hinted return Vox\Webservice\Mapping\Resource. Consider adding an additional type-check to rule them out.
Loading history...
176
    }
177
178 25
    private function getMetadata(string $transferName): TransferMetadata
179
    {
180 25
        return $this->metadataFactory->getMetadataForClass($transferName);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->metadataFa...ForClass($transferName) returns the type null|Metadata\ClassHierarchyMetadata which is incompatible with the type-hinted return Vox\Webservice\Metadata\TransferMetadata.
Loading history...
181
    }
182
}
183