-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAbstractClient.php
More file actions
170 lines (152 loc) · 4.9 KB
/
AbstractClient.php
File metadata and controls
170 lines (152 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<?php
declare(strict_types=1);
namespace DigipolisGent\API\Client;
use DigipolisGent\API\Client\Configuration\ConfigurationInterface;
use DigipolisGent\API\Client\Exception\HandlerNotFound;
use DigipolisGent\API\Client\Handler\HandlerInterface;
use DigipolisGent\API\Client\Response\ResponseInterface;
use DigipolisGent\API\Client\Token\OidcTokenProvider;
use DigipolisGent\API\Client\Token\TokenProviderInterface;
use DigipolisGent\API\Logger\LoggableInterface;
use DigipolisGent\API\Logger\LoggableTrait;
use DigipolisGent\API\Logger\RequestLog;
use GuzzleHttp\ClientInterface as GuzzleClientInterface;
use GuzzleHttp\Exception\ClientException;
use Psr\Http\Message\RequestInterface;
use Psr\SimpleCache\CacheInterface;
/**
* Abstract implementation of the service client.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
abstract class AbstractClient implements ClientInterface, LoggableInterface
{
use LoggableTrait;
/**
* Handlers this client has to handle the requests.
*
* @var \DigipolisGent\API\Client\Handler\HandlerInterface[]
*/
protected array $handlers = [];
/**
* Guzzle HTTP client.
*
* @var \GuzzleHttp\ClientInterface
*/
protected GuzzleClientInterface $guzzle;
/**
* The client configuration.
*
* @var \DigipolisGent\API\Client\Configuration\ConfigurationInterface
*/
protected ConfigurationInterface $configuration;
/**
* The OIDC token provider.
*
* @var \DigipolisGent\API\Client\Token\TokenProviderInterface
*/
protected TokenProviderInterface $tokenProvider;
/**
* Client constructor.
*
* @param \GuzzleHttp\ClientInterface $guzzle
* The Guzzle HTTP client.
* @param \DigipolisGent\API\Client\Configuration\ConfigurationInterface $configuration
* The client configuration object.
* @param \Psr\SimpleCache\CacheInterface $cache
* Cache used for auth Bearer tokens. Not that this is not for API responses.
*/
public function __construct(
GuzzleClientInterface $guzzle,
ConfigurationInterface $configuration,
CacheInterface $cache,
) {
$this->guzzle = $guzzle;
$this->configuration = $configuration;
$this->tokenProvider = new OidcTokenProvider(
$configuration->getAuthUri(),
$configuration->getClientId(),
$configuration->getClientSecret(),
$configuration->getScope(),
$cache,
);
}
/**
* Sends a Request and returns the appropriate Response.
*
* @param \Psr\Http\Message\RequestInterface $request
*
* @return \DigipolisGent\API\Client\Response\ResponseInterface
*
* @throws \DigipolisGent\API\Client\Exception\HandlerNotFound
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function send(RequestInterface $request): ResponseInterface
{
$psrRequest = $this->injectHeaders($request);
$this->log(new RequestLog($request));
$handler = $this->getHandler($request);
try {
$psrResponse = $this->guzzle->send($psrRequest);
} catch (ClientException $e) {
$psrResponse = $e->getResponse();
}
return $handler->toResponse($psrResponse);
}
/**
* Adds headers to a Request object
*
* @param \Psr\Http\Message\RequestInterface $request
*
* @return \Psr\Http\Message\RequestInterface
*/
protected function injectHeaders(RequestInterface $request): RequestInterface
{
return $request
->withHeader(
'Content-Length',
(string) strlen((string) $request->getBody())
)
->withHeader(
'Authorization',
'Bearer ' . $this->tokenProvider->getAccessToken()
);
}
/**
* Returns the correct handler for the given Request-object
*
* @param \Psr\Http\Message\RequestInterface $request
*
* @return \DigipolisGent\API\Client\Handler\HandlerInterface
*
* @throws \DigipolisGent\API\Client\Exception\HandlerNotFound
*/
protected function getHandler(RequestInterface $request): HandlerInterface
{
if (array_key_exists(get_class($request), $this->handlers)) {
return $this->handlers[get_class($request)];
}
throw HandlerNotFound::fromRequest($request);
}
/**
* Registers a single handler.
*
* @param \DigipolisGent\API\Client\Handler\HandlerInterface $handler
*/
public function addHandler(HandlerInterface $handler): void
{
$requestTypes = $handler->handles();
foreach ($requestTypes as $requestType) {
$this->handlers[$requestType] = $handler;
}
}
/**
* Get handlers.
*
* @return Handler\HandlerInterface[]
*/
public function getHandlers(): array
{
return $this->handlers;
}
}