Passed
Push — master ( 9705cd...545ffe )
by JHONATAN
02:45
created

WebserviceClient::cGet()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3.009

Importance

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