Completed
Push — master ( a45336...73efce )
by JHONATAN
03:03
created

WebserviceClient   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Test Coverage

Coverage 90.91%

Importance

Changes 0
Metric Value
wmc 18
dl 0
loc 137
ccs 60
cts 66
cp 0.9091
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A cGet() 0 17 3
A get() 0 15 3
A getClient() 0 7 2
A getResource() 0 3 1
A getMetadata() 0 3 1
A put() 0 19 3
A __construct() 0 10 1
A post() 0 14 2
A delete() 0 9 2
1
<?php
2
3
namespace Vox\Webservice;
4
5
use GuzzleHttp\ClientInterface;
6
use GuzzleHttp\Psr7\Request;
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 22
    public function __construct(
43
        ClientRegistryInterface $clientRegistry,
44
        MetadataFactoryInterface $metadataFactory,
45
        DenormalizerInterface $denormalizer,
46
        NormalizerInterface $normalizer
47
    ) {
48 22
        $this->clientRegistry  = $clientRegistry;
49 22
        $this->metadataFactory = $metadataFactory;
50 22
        $this->denormalizer    = $denormalizer;
51 22
        $this->normalizer      = $normalizer;
52 22
    }
53
54 7
    public function cGet(string $transferName, array $filters = []): TransferCollection
55
    {
56 7
        $resource = $this->getResource($transferName);
57 7
        $client   = $this->getClient($transferName);
58 7
        $options  = ['headers' => ['Content-Type' => 'application/json']];
59
60 7
        if (!empty($filters)) {
61 4
            $options['query'] = $filters;
62
        }
63
64 7
        $response = $client->request('GET', $resource->route, $options);
65
66 7
        if ($response->getStatusCode() >= 300) {
67
            throw new WebserviceResponseException($response, new Request('GET', $response->route, $options));
0 ignored issues
show
Bug introduced by
Accessing route on the interface Psr\Http\Message\ResponseInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
68
        }
69
70 7
        return new TransferCollection($transferName, $this->denormalizer, $response);
71
    }
72
73 1
    public function delete(string $transferName, $id)
74
    {
75 1
        $resource = $this->getResource($transferName);
76 1
        $client   = $this->getClient($transferName);
77 1
        $route    = sprintf('%s/%s', $resource->route, $id);
78 1
        $response = $client->request('DELETE', $route);
79
80 1
        if ($response->getStatusCode() >= 300) {
81
            throw new WebserviceResponseException($response, new Request('DELETE', $route));
82
        }
83 1
    }
84
85 9
    public function get(string $transferName, $id)
86
    {
87 9
        $resource = $this->getResource($transferName);
88 9
        $client   = $this->getClient($transferName);
89 9
        $route    = sprintf('%s/%s', $resource->route, $id);
90 9
        $response = $client->request('GET', $route, ['headers' => ['Content-Type' => 'application/json']]);
91
        
92 9
        if ($response->getStatusCode() >= 300) {
93
            throw new WebserviceResponseException($response, new Request('GET', $route));
94
        }
95
96 9
        $contents = $response->getBody()->getContents();
97
        
98 9
        if ($contents) {
99 9
            return $this->denormalizer->denormalize(json_decode($contents, true), $transferName);
100
        }
101
    }
102
103 4
    public function post($transfer)
104
    {
105 4
        $data = $this->normalizer->normalize($transfer, 'json');
106
107 4
        $resource = $this->getResource(get_class($transfer));
108 4
        $client   = $this->getClient(get_class($transfer));
109 4
        $response = $client->request('POST', $resource->route, ['json' => $data]);
110
111 4
        if ($response->getStatusCode() >= 300) {
112 1
            throw new WebserviceResponseException($response, new Request('POST', $resource->route, ['json' => $data]));
113
        }
114
115 3
        $contents = $response->getBody()->getContents();
116 3
        $this->denormalizer->denormalize(json_decode($contents, true), $transfer);
117 3
    }
118
119 2
    public function put($transfer)
120
    {
121 2
        $data     = $this->normalizer->normalize($transfer, 'json');
122 2
        $metadata = $this->getMetadata(get_class($transfer));
123 2
        $resource = $this->getResource(get_class($transfer));
124 2
        $client   = $this->getClient(get_class($transfer));
125
126 2
        if (empty($metadata->id)) {
127
            throw new RuntimeException('no id mapped for class ' . get_class($transfer));
128
        }
129
130 2
        $route    = sprintf('%s/%s', $resource->route, $metadata->id->getValue($transfer));
131 2
        $response = $client->request('PUT', $route, ['json' => $data]);
132
133 2
        if ($response->getStatusCode() >= 300) {
134
            throw new WebserviceResponseException($response, new Request('PUT', $route, ['json' => $data]));
135
        }
136
137 2
        $this->denormalizer->denormalize(json_decode($response->getBody()->getContents(), true), $transfer);
138 2
    }
139
140 17
    private function getClient(string $transferName, Resource $resource = null): ClientInterface
141
    {
142 17
        if (null === $resource) {
143 17
            $resource = $this->getResource($transferName);
144
        }
145
146 17
        return  $this->clientRegistry->get($resource->client);
147
    }
148
149 17
    private function getResource(string $transferName): Resource
150
    {
151 17
        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 17
    private function getMetadata(string $transferName): TransferMetadata
155
    {
156 17
        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