Adapter.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. <?php
  2. /**
  3. * Refer to LICENSE.txt distributed with the Temando Shipping module for notice of license
  4. */
  5. namespace Temando\Shipping\Rest;
  6. use Psr\Log\LoggerInterface;
  7. use Psr\Log\LogLevel;
  8. use Temando\Shipping\Rest\Adapter\CarrierApiInterface;
  9. use Temando\Shipping\Rest\Adapter\CompletionApiInterface;
  10. use Temando\Shipping\Rest\Adapter\ContainerApiInterface;
  11. use Temando\Shipping\Rest\Adapter\EventStreamApiInterface;
  12. use Temando\Shipping\Rest\Adapter\LocationApiInterface;
  13. use Temando\Shipping\Rest\Exception\AdapterException;
  14. use Temando\Shipping\Rest\Exception\RestClientErrorException;
  15. use Temando\Shipping\Rest\Request\ItemRequestInterface;
  16. use Temando\Shipping\Rest\Request\ListRequestInterface;
  17. use Temando\Shipping\Rest\Request\RequestHeadersInterface;
  18. use Temando\Shipping\Rest\Request\StreamCreateRequestInterface;
  19. use Temando\Shipping\Rest\Request\StreamEventItemRequest;
  20. use Temando\Shipping\Rest\Response\DataObject\CarrierConfiguration;
  21. use Temando\Shipping\Rest\Response\DataObject\CarrierIntegration;
  22. use Temando\Shipping\Rest\Response\DataObject\Completion;
  23. use Temando\Shipping\Rest\Response\DataObject\Container;
  24. use Temando\Shipping\Rest\Response\DataObject\Location;
  25. use Temando\Shipping\Rest\Response\DataObject\StreamEvent;
  26. use Temando\Shipping\Rest\Response\Document\Errors;
  27. use Temando\Shipping\Rest\Response\Document\GetCarrierConfigurations;
  28. use Temando\Shipping\Rest\Response\Document\GetCarrierIntegrations;
  29. use Temando\Shipping\Rest\Response\Document\GetCompletion;
  30. use Temando\Shipping\Rest\Response\Document\GetCompletions;
  31. use Temando\Shipping\Rest\Response\Document\GetContainers;
  32. use Temando\Shipping\Rest\Response\Document\GetLocations;
  33. use Temando\Shipping\Rest\Response\Document\GetStreamEvents;
  34. use Temando\Shipping\Rest\SchemaMapper\ParserInterface;
  35. use Temando\Shipping\Webservice\Config\WsConfigInterface;
  36. /**
  37. * Temando REST API Adapter
  38. *
  39. * @package Temando\Shipping\Rest
  40. * @author Christoph Aßmann <christoph.assmann@netresearch.de>
  41. * @author Sebastian Ertner <sebastian.ertner@netresearch.de>
  42. * @license https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  43. * @link https://www.temando.com/
  44. */
  45. class Adapter implements
  46. CarrierApiInterface,
  47. CompletionApiInterface,
  48. ContainerApiInterface,
  49. LocationApiInterface,
  50. EventStreamApiInterface
  51. {
  52. /**
  53. * @var string
  54. */
  55. private $endpoint;
  56. /**
  57. * @var string
  58. */
  59. private $accountId;
  60. /**
  61. * @var string
  62. */
  63. private $bearerToken;
  64. /**
  65. * @var RequestHeadersInterface
  66. */
  67. private $requestHeaders;
  68. /**
  69. * @var AuthenticationInterface
  70. */
  71. private $auth;
  72. /**
  73. * @var RestClientInterface
  74. */
  75. private $restClient;
  76. /**
  77. * @var ParserInterface
  78. */
  79. private $responseParser;
  80. /**
  81. * @var LoggerInterface
  82. */
  83. private $logger;
  84. /**
  85. * Adapter constructor.
  86. * @param WsConfigInterface $config
  87. * @param RequestHeadersInterface $requestHeaders
  88. * @param AuthenticationInterface $auth
  89. * @param RestClientInterface $restClient
  90. * @param ParserInterface $responseParser
  91. * @param LoggerInterface $logger
  92. */
  93. public function __construct(
  94. WsConfigInterface $config,
  95. RequestHeadersInterface $requestHeaders,
  96. AuthenticationInterface $auth,
  97. RestClientInterface $restClient,
  98. ParserInterface $responseParser,
  99. LoggerInterface $logger
  100. ) {
  101. $this->endpoint = $config->getApiEndpoint();
  102. $this->accountId = $config->getAccountId();
  103. $this->bearerToken = $config->getBearerToken();
  104. $this->requestHeaders = $requestHeaders;
  105. $this->auth = $auth;
  106. $this->restClient = $restClient;
  107. $this->responseParser = $responseParser;
  108. $this->logger = $logger;
  109. }
  110. /**
  111. * @param ListRequestInterface $request
  112. * @return CarrierConfiguration[]
  113. * @throws AdapterException
  114. */
  115. public function getCarrierConfigurations(ListRequestInterface $request)
  116. {
  117. $uri = sprintf('%s/carriers/configuration', $this->endpoint);
  118. $queryParams = $request->getRequestParams();
  119. $this->logger->log(LogLevel::DEBUG, sprintf('%s?%s', $uri, http_build_query($queryParams)));
  120. try {
  121. $this->auth->connect($this->accountId, $this->bearerToken);
  122. $headers = $this->requestHeaders->getHeaders();
  123. $rawResponse = $this->restClient->get($uri, $queryParams, $headers);
  124. $this->logger->log(LogLevel::DEBUG, $rawResponse);
  125. /** @var GetCarrierConfigurations $response */
  126. $response = $this->responseParser->parse($rawResponse, GetCarrierConfigurations::class);
  127. $configurations = $response->getData();
  128. } catch (RestClientErrorException $e) {
  129. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  130. /** @var Errors $response */
  131. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  132. throw AdapterException::errorResponse($response, $e);
  133. } catch (\Exception $e) {
  134. $this->logger->critical($e->getMessage(), ['exception' => $e]);
  135. $configurations = [];
  136. }
  137. return $configurations;
  138. }
  139. /**
  140. * @param ListRequestInterface $request
  141. * @return CarrierIntegration[]
  142. * @throws AdapterException
  143. */
  144. public function getCarrierIntegrations(ListRequestInterface $request)
  145. {
  146. $uri = sprintf('%s/carriers', $this->endpoint);
  147. $queryParams = $request->getRequestParams();
  148. $this->logger->log(LogLevel::DEBUG, sprintf('%s?%s', $uri, http_build_query($queryParams)));
  149. try {
  150. $this->auth->connect($this->accountId, $this->bearerToken);
  151. $headers = $this->requestHeaders->getHeaders();
  152. $rawResponse = $this->restClient->get($uri, $queryParams, $headers);
  153. $this->logger->log(LogLevel::DEBUG, $rawResponse);
  154. /** @var GetCarrierIntegrations $response */
  155. $response = $this->responseParser->parse($rawResponse, GetCarrierIntegrations::class);
  156. $carriers = $response->getData();
  157. } catch (RestClientErrorException $e) {
  158. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  159. /** @var Errors $response */
  160. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  161. throw AdapterException::errorResponse($response, $e);
  162. } catch (\Exception $e) {
  163. $this->logger->critical($e->getMessage(), ['exception' => $e]);
  164. $carriers = [];
  165. }
  166. return $carriers;
  167. }
  168. /**
  169. * @param ItemRequestInterface $request
  170. * @return void
  171. * @throws AdapterException
  172. */
  173. public function deleteCarrierConfiguration(ItemRequestInterface $request)
  174. {
  175. $uri = sprintf('%s/carriers/configuration/%s', $this->endpoint, ...$request->getPathParams());
  176. $this->logger->log(LogLevel::DEBUG, $uri);
  177. try {
  178. $this->auth->connect($this->accountId, $this->bearerToken);
  179. $headers = $this->requestHeaders->getHeaders();
  180. $this->restClient->delete($uri, $headers);
  181. } catch (RestClientErrorException $e) {
  182. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  183. /** @var Errors $response */
  184. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  185. throw AdapterException::errorResponse($response, $e);
  186. } catch (\Exception $e) {
  187. throw AdapterException::create($e);
  188. }
  189. }
  190. /**
  191. * @param ListRequestInterface $request
  192. * @return Location[]
  193. * @throws AdapterException
  194. */
  195. public function getLocations(ListRequestInterface $request)
  196. {
  197. $uri = sprintf('%s/locations', $this->endpoint);
  198. $queryParams = $request->getRequestParams();
  199. $this->logger->log(LogLevel::DEBUG, sprintf('%s?%s', $uri, http_build_query($queryParams)));
  200. try {
  201. $this->auth->connect($this->accountId, $this->bearerToken);
  202. $headers = $this->requestHeaders->getHeaders();
  203. $rawResponse = $this->restClient->get($uri, $queryParams, $headers);
  204. $this->logger->log(LogLevel::DEBUG, $rawResponse);
  205. /** @var GetLocations $response */
  206. $response = $this->responseParser->parse($rawResponse, GetLocations::class);
  207. $locations = $response->getData();
  208. } catch (RestClientErrorException $e) {
  209. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  210. /** @var Errors $response */
  211. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  212. throw AdapterException::errorResponse($response, $e);
  213. } catch (\Exception $e) {
  214. $this->logger->critical($e->getMessage(), ['exception' => $e]);
  215. $locations = [];
  216. }
  217. return $locations;
  218. }
  219. /**
  220. * @param ItemRequestInterface $request
  221. *
  222. * @return void
  223. * @throws AdapterException
  224. */
  225. public function deleteLocation(ItemRequestInterface $request)
  226. {
  227. $uri = sprintf('%s/locations/%s', $this->endpoint, ...$request->getPathParams());
  228. $this->logger->log(LogLevel::DEBUG, $uri);
  229. try {
  230. $this->auth->connect($this->accountId, $this->bearerToken);
  231. $headers = $this->requestHeaders->getHeaders();
  232. $this->restClient->delete($uri, $headers);
  233. } catch (RestClientErrorException $e) {
  234. $this->logger->log(LogLevel::ERROR, $e->getMessage(), ['exception' => $e]);
  235. /** @var Errors $response */
  236. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  237. throw AdapterException::errorResponse($response, $e);
  238. } catch (\Exception $e) {
  239. throw AdapterException::create($e);
  240. }
  241. }
  242. /**
  243. * @param ListRequestInterface $request
  244. * @return Container[]
  245. * @throws AdapterException
  246. */
  247. public function getContainers(ListRequestInterface $request)
  248. {
  249. $uri = sprintf('%s/containers', $this->endpoint);
  250. $queryParams = $request->getRequestParams();
  251. $this->logger->log(LogLevel::DEBUG, sprintf('%s?%s', $uri, http_build_query($queryParams)));
  252. try {
  253. $this->auth->connect($this->accountId, $this->bearerToken);
  254. $headers = $this->requestHeaders->getHeaders();
  255. $rawResponse = $this->restClient->get($uri, $queryParams, $headers);
  256. $this->logger->log(LogLevel::DEBUG, $rawResponse);
  257. /** @var GetContainers $response */
  258. $response = $this->responseParser->parse($rawResponse, GetContainers::class);
  259. $containers = $response->getData();
  260. } catch (RestClientErrorException $e) {
  261. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  262. /** @var Errors $response */
  263. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  264. throw AdapterException::errorResponse($response, $e);
  265. } catch (\Exception $e) {
  266. $this->logger->critical($e->getMessage(), ['exception' => $e]);
  267. $containers = [];
  268. }
  269. return $containers;
  270. }
  271. /**
  272. * @param ItemRequestInterface $request
  273. *
  274. * @return void
  275. * @throws AdapterException
  276. */
  277. public function deleteContainer(ItemRequestInterface $request)
  278. {
  279. $uri = sprintf('%s/containers/%s', $this->endpoint, ...$request->getPathParams());
  280. $this->logger->log(LogLevel::DEBUG, $uri);
  281. try {
  282. $this->auth->connect($this->accountId, $this->bearerToken);
  283. $headers = $this->requestHeaders->getHeaders();
  284. $this->restClient->delete($uri, $headers);
  285. } catch (RestClientErrorException $e) {
  286. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  287. /** @var Errors $response */
  288. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  289. throw AdapterException::errorResponse($response, $e);
  290. } catch (\Exception $e) {
  291. throw AdapterException::create($e);
  292. }
  293. }
  294. /**
  295. * @param ListRequestInterface $request
  296. * @return Completion[]
  297. * @throws AdapterException
  298. */
  299. public function getCompletions(ListRequestInterface $request)
  300. {
  301. $uri = sprintf('%s/completions', $this->endpoint);
  302. $queryParams = $request->getRequestParams();
  303. $queryParams['filter'] = rawurlencode(json_encode($queryParams['filter']));
  304. $this->logger->log(LogLevel::DEBUG, sprintf('%s?%s', $uri, http_build_query($queryParams)));
  305. try {
  306. $this->auth->connect($this->accountId, $this->bearerToken);
  307. $headers = $this->requestHeaders->getHeaders();
  308. $rawResponse = $this->restClient->get($uri, $queryParams, $headers);
  309. $this->logger->log(LogLevel::DEBUG, $rawResponse);
  310. /** @var GetCompletions $response */
  311. $response = $this->responseParser->parse($rawResponse, GetCompletions::class);
  312. $completions = $response->getData();
  313. } catch (RestClientErrorException $e) {
  314. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  315. /** @var Errors $response */
  316. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  317. throw AdapterException::errorResponse($response, $e);
  318. } catch (\Exception $e) {
  319. $this->logger->critical($e->getMessage(), ['exception' => $e]);
  320. $completions = [];
  321. }
  322. return $completions;
  323. }
  324. /**
  325. * @param ItemRequestInterface $request
  326. * @return Completion
  327. * @throws AdapterException
  328. */
  329. public function getCompletion(ItemRequestInterface $request)
  330. {
  331. $uri = sprintf('%s/completions/%s', $this->endpoint, ...$request->getPathParams());
  332. $this->logger->log(LogLevel::DEBUG, $uri);
  333. try {
  334. $this->auth->connect($this->accountId, $this->bearerToken);
  335. $headers = $this->requestHeaders->getHeaders();
  336. $rawResponse = $this->restClient->get($uri, [], $headers);
  337. $this->logger->log(LogLevel::DEBUG, $rawResponse);
  338. /** @var GetCompletion $response */
  339. $response = $this->responseParser->parse($rawResponse, GetCompletion::class);
  340. $completion = $response->getData();
  341. } catch (RestClientErrorException $e) {
  342. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  343. /** @var Errors $response */
  344. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  345. throw AdapterException::errorResponse($response, $e);
  346. } catch (\Exception $e) {
  347. throw AdapterException::create($e);
  348. }
  349. return $completion;
  350. }
  351. /**
  352. * @param StreamCreateRequestInterface $request
  353. * @return void
  354. * @throws AdapterException
  355. */
  356. public function createStream(StreamCreateRequestInterface $request)
  357. {
  358. $uri = sprintf('%s/streams', $this->endpoint);
  359. $requestBody = $request->getRequestBody();
  360. $this->logger->log(LogLevel::DEBUG, sprintf("%s\n%s", $uri, $requestBody));
  361. try {
  362. $this->auth->connect($this->accountId, $this->bearerToken);
  363. $headers = $this->requestHeaders->getHeaders();
  364. $rawResponse = $this->restClient->post($uri, $requestBody, $headers);
  365. $this->logger->log(LogLevel::DEBUG, $rawResponse);
  366. } catch (RestClientErrorException $e) {
  367. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  368. /** @var Errors $response */
  369. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  370. throw AdapterException::errorResponse($response, $e);
  371. } catch (\Exception $e) {
  372. throw AdapterException::create($e);
  373. }
  374. }
  375. /**
  376. * @param ItemRequestInterface $request
  377. * @return void
  378. * @throws AdapterException
  379. */
  380. public function deleteStream(ItemRequestInterface $request)
  381. {
  382. $uri = sprintf('%s/streams/%s', $this->endpoint, ...$request->getPathParams());
  383. $this->logger->log(LogLevel::DEBUG, $uri);
  384. try {
  385. $this->auth->connect($this->accountId, $this->bearerToken);
  386. $headers = $this->requestHeaders->getHeaders();
  387. $this->restClient->delete($uri, $headers);
  388. } catch (RestClientErrorException $e) {
  389. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  390. /** @var Errors $response */
  391. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  392. throw AdapterException::errorResponse($response, $e);
  393. } catch (\Exception $e) {
  394. throw AdapterException::create($e);
  395. }
  396. }
  397. /**
  398. * @param ListRequestInterface $request
  399. *
  400. * @return StreamEvent[]
  401. * @throws AdapterException
  402. */
  403. public function getStreamEvents(ListRequestInterface $request)
  404. {
  405. $uri = sprintf('%s/streams/%s/events', $this->endpoint, ...$request->getPathParams());
  406. $queryParams = $request->getRequestParams();
  407. $this->logger->log(LogLevel::DEBUG, sprintf('%s?%s', $uri, http_build_query($queryParams)));
  408. try {
  409. $this->auth->connect($this->accountId, $this->bearerToken);
  410. $headers = $this->requestHeaders->getHeaders();
  411. $rawResponse = $this->restClient->get($uri, $queryParams, $headers);
  412. $this->logger->log(LogLevel::DEBUG, $rawResponse);
  413. /** @var GetStreamEvents $response */
  414. $response = $this->responseParser->parse($rawResponse, GetStreamEvents::class);
  415. $events = $response->getData();
  416. } catch (RestClientErrorException $e) {
  417. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  418. /** @var Errors $response */
  419. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  420. throw AdapterException::errorResponse($response, $e);
  421. } catch (\Exception $e) {
  422. $this->logger->critical($e->getMessage(), ['exception' => $e]);
  423. $events = [];
  424. }
  425. return $events;
  426. }
  427. /**
  428. * @param StreamEventItemRequest $request
  429. * @return void
  430. * @throws AdapterException
  431. */
  432. public function deleteStreamEvent(StreamEventItemRequest $request)
  433. {
  434. $uri = sprintf('%s/streams/%s/events/%s', $this->endpoint, ...$request->getPathParams());
  435. $this->logger->log(LogLevel::DEBUG, $uri);
  436. try {
  437. $this->auth->connect($this->accountId, $this->bearerToken);
  438. $headers = $this->requestHeaders->getHeaders();
  439. $this->restClient->delete($uri, $headers);
  440. } catch (RestClientErrorException $e) {
  441. $this->logger->log(LogLevel::ERROR, $e->getMessage());
  442. /** @var Errors $response */
  443. $response = $this->responseParser->parse($e->getMessage(), Errors::class);
  444. throw AdapterException::errorResponse($response, $e);
  445. } catch (\Exception $e) {
  446. throw AdapterException::create($e);
  447. }
  448. }
  449. }