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 | 36 | public function __construct( |
|
45 | ClientRegistryInterface $clientRegistry, |
||
46 | MetadataFactoryInterface $metadataFactory, |
||
47 | DenormalizerInterface $denormalizer, |
||
48 | NormalizerInterface $normalizer |
||
49 | ) { |
||
50 | 36 | $this->clientRegistry = $clientRegistry; |
|
51 | 36 | $this->metadataFactory = $metadataFactory; |
|
52 | 36 | $this->denormalizer = $denormalizer; |
|
53 | 36 | $this->normalizer = $normalizer; |
|
54 | 36 | } |
|
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 | 2 | public function delete(string $transferName, $id) |
|
76 | { |
||
77 | 2 | $resource = $this->getResource($transferName); |
|
78 | 2 | $client = $this->getClient($transferName); |
|
79 | 2 | $route = sprintf('%s/%s', $resource->route, $id); |
|
80 | 2 | $response = $client->request('DELETE', $route); |
|
81 | |||
82 | 2 | if ($response->getStatusCode() >= 300) { |
|
83 | throw new WebserviceResponseException($response, new Request('DELETE', $route)); |
||
84 | } |
||
85 | 2 | } |
|
86 | |||
87 | 16 | public function get(string $transferName, $id) |
|
88 | { |
||
89 | 16 | $resource = $this->getResource($transferName); |
|
90 | 16 | $client = $this->getClient($transferName); |
|
91 | 16 | $route = sprintf('%s/%s', $resource->route, $id); |
|
92 | 16 | $response = $client->request('GET', $route, ['headers' => ['Content-Type' => 'application/json']]); |
|
93 | |||
94 | 16 | if ($response->getStatusCode() >= 300) { |
|
95 | throw new WebserviceResponseException($response, new Request('GET', $route)); |
||
96 | } |
||
97 | |||
98 | 16 | $contents = $response->getBody()->getContents(); |
|
99 | |||
100 | 16 | if ($contents) { |
|
101 | 16 | return $this->denormalizer->denormalize(json_decode($contents, true), $transferName); |
|
102 | } |
||
103 | } |
||
104 | |||
105 | 9 | public function post($transfer) |
|
106 | { |
||
107 | 9 | $data = $this->normalizer->normalize($transfer, 'json'); |
|
108 | |||
109 | 9 | $resource = $this->getResource(get_class($transfer)); |
|
110 | 9 | $client = $this->getClient(get_class($transfer)); |
|
111 | 9 | $response = $client->request('POST', $resource->route, ['json' => $data]); |
|
112 | |||
113 | 9 | if ($response->getStatusCode() >= 300) { |
|
114 | 2 | throw new WebserviceResponseException($response, new Request('POST', $resource->route, ['json' => $data])); |
|
115 | } |
||
116 | |||
117 | 8 | $contents = $response->getBody()->getContents(); |
|
118 | 8 | $this->denormalizer->denormalize(json_decode($contents, true), $transfer); |
|
119 | 8 | } |
|
120 | |||
121 | 4 | public function put($transfer) |
|
122 | { |
||
123 | 4 | $data = $this->normalizer->normalize($transfer, 'json'); |
|
124 | 4 | $metadata = $this->getMetadata(get_class($transfer)); |
|
125 | 4 | $resource = $this->getResource(get_class($transfer)); |
|
126 | 4 | $client = $this->getClient(get_class($transfer)); |
|
127 | |||
128 | 4 | if (empty($metadata->id)) { |
|
129 | throw new RuntimeException('no id mapped for class ' . get_class($transfer)); |
||
130 | } |
||
131 | |||
132 | 4 | $route = sprintf('%s/%s', $resource->route, $metadata->id->getValue($transfer)); |
|
133 | 4 | $response = $client->request('PUT', $route, ['json' => $data]); |
|
134 | |||
135 | 4 | if ($response->getStatusCode() >= 300) { |
|
136 | throw new WebserviceResponseException($response, new Request('PUT', $route, ['json' => $data])); |
||
137 | } |
||
138 | |||
139 | 4 | $this->denormalizer->denormalize(json_decode($response->getBody()->getContents(), true), $transfer); |
|
140 | 4 | } |
|
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 | 31 | private function getClient(string $transferName, Resource $resource = null): ClientInterface |
|
165 | { |
||
166 | 31 | if (null === $resource) { |
|
167 | 31 | $resource = $this->getResource($transferName); |
|
168 | } |
||
169 | |||
170 | 31 | return $this->clientRegistry->get($resource->client); |
|
171 | } |
||
172 | |||
173 | 31 | private function getResource(string $transferName): Resource |
|
174 | { |
||
175 | 31 | return $this->getMetadata($transferName)->getAnnotation(Resource::class, true); |
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
![]() |
|||
176 | } |
||
177 | |||
178 | 31 | private function getMetadata(string $transferName): TransferMetadata |
|
179 | { |
||
180 | 31 | return $this->metadataFactory->getMetadataForClass($transferName); |
|
0 ignored issues
–
show
|
|||
181 | } |
||
182 | } |
||
183 |