Completed
Push — master ( 18bfc7...82e0b5 )
by Jens
18:00 queued 05:19
created

Guzzle6Adapter::executeAsync()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * @author @jayS-de <[email protected]>
4
 */
5
6
namespace Commercetools\Core\Client\Adapter;
7
8
use Commercetools\Core\Response\AbstractApiResponse;
9
use GuzzleHttp\Client;
10
use GuzzleHttp\Exception\RequestException;
11
use GuzzleHttp\MessageFormatter;
12
use GuzzleHttp\Middleware;
13
use GuzzleHttp\Pool;
14
use GuzzleHttp\Promise\PromiseInterface;
15
use Psr\Http\Message\RequestInterface;
16
use Psr\Http\Message\ResponseInterface;
17
use Psr\Log\LoggerInterface;
18
use Commercetools\Core\Error\Message;
19
use Commercetools\Core\Error\ApiException;
20
use Psr\Log\LogLevel;
21
22
class Guzzle6Adapter implements AdapterInterface
23
{
24
    /**
25
     * @var Client
26
     */
27
    protected $client;
28
29
    protected $logger;
30
31 102
    public function __construct(array $options = [])
32
    {
33 102
        $options = array_merge(
34
            [
35 102
                'allow_redirects' => false,
36
                'verify' => true,
37
                'timeout' => 60,
38
                'connect_timeout' => 10,
39
                'pool_size' => 25
40
            ],
41
            $options
42
        );
43 102
        $this->client = new Client($options);
44 102
    }
45
46 40
    public function setLogger(LoggerInterface $logger)
47
    {
48 40
        $this->logger = $logger;
49 40
        $this->addHandler(self::log($logger, new MessageFormatter()));
50 40
    }
51
52
    /**
53
     * Middleware that logs requests, responses, and errors using a message
54
     * formatter.
55
     *
56
     * @param LoggerInterface  $logger Logs messages.
57
     * @param MessageFormatter $formatter Formatter used to create message strings.
58
     * @param string           $logLevel Level at which to log requests.
59
     *
60
     * @return callable Returns a function that accepts the next handler.
61
     */
62 433
    private static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = LogLevel::INFO)
63
    {
64
        return function (callable $handler) use ($logger, $formatter, $logLevel) {
65
            return function ($request, array $options) use ($handler, $logger, $formatter, $logLevel) {
66 433
                return $handler($request, $options)->then(
67
                    function ($response) use ($logger, $request, $formatter, $logLevel) {
68 433
                        $message = $formatter->format($request, $response);
69 433
                        $context[AbstractApiResponse::X_CORRELATION_ID] = $response->getHeader(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$context was never initialized. Although not strictly required by PHP, it is generally a good practice to add $context = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
70 433
                            AbstractApiResponse::X_CORRELATION_ID
71
                        );
72 433
                        $logger->log($logLevel, $message, $context);
73 433
                        return $response;
74 433
                    },
75 433
                    function ($reason) use ($logger, $request, $formatter) {
76
                        $response = null;
77
                        $context = [];
78
                        if ($reason instanceof RequestException) {
79
                            $response = $reason->getResponse();
80
                            if (!is_null($response)) {
81
                                $context[AbstractApiResponse::X_CORRELATION_ID] = $response->getHeader(
82
                                    AbstractApiResponse::X_CORRELATION_ID
83
                                );
84
                            }
85
                        }
86
                        $message = $formatter->format($request, $response, $reason);
87
                        $logger->notice($message, $context);
88
                        return \GuzzleHttp\Promise\rejection_for($reason);
89 433
                    }
90
                );
91 35
            };
92 40
        };
93
    }
94
95 40
    public function addHandler($handler)
96
    {
97 40
        $this->client->getConfig('handler')->push($handler);
98 40
    }
99
100
    /**
101
     * @param RequestInterface $request
102
     * @return ResponseInterface
103
     */
104 476
    public function execute(RequestInterface $request)
105
    {
106
        try {
107 476
            $response = $this->client->send($request);
108 79
        } catch (RequestException $exception) {
109 79
            $response = $exception->getResponse();
110 79
            throw ApiException::create($request, $response, $exception);
111
        }
112
113 452
        return $response;
114
    }
115
116
    /**
117
     * @param RequestInterface[] $requests
118
     * @return ResponseInterface[]
119
     */
120 350
    public function executeBatch(array $requests)
121
    {
122 350
        $results = Pool::batch(
123 350
            $this->client,
124
            $requests
125
        );
126
127 350
        $responses = [];
128 350
        foreach ($results as $key => $result) {
129 350
            $httpResponse = $result;
130 350 View Code Duplication
            if ($result instanceof RequestException) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131 16
                $request = $requests[$key];
132 16
                $httpResponse = $result->getResponse();
133 16
                $httpResponse = ApiException::create($request, $httpResponse, $result);
134
            }
135 350
            $responses[$key] = $httpResponse;
136
        }
137
138 350
        return $responses;
139
    }
140
141
    /**
142
     * @param $oauthUri
143
     * @param $clientId
144
     * @param $clientSecret
145
     * @param $formParams
146
     * @return ResponseInterface
147
     */
148 42
    public function authenticate($oauthUri, $clientId, $clientSecret, $formParams)
149
    {
150
        $options = [
151 42
            'form_params' => $formParams,
152 42
            'auth' => [$clientId, $clientSecret]
153
        ];
154
155
        try {
156 42
            $response = $this->client->post($oauthUri, $options);
157 3
        } catch (RequestException $exception) {
158 3
            throw ApiException::create($exception->getRequest(), $exception->getResponse(), $exception);
159
        }
160 41
        return $response;
161
    }
162
163
    /**
164
     * @param RequestInterface $request
165
     * @return AdapterPromiseInterface
166
     */
167 4
    public function executeAsync(RequestInterface $request)
168
    {
169 4
        $guzzlePromise = $this->client->sendAsync($request);
170
171 4
        return new Guzzle6Promise($guzzlePromise);
172
    }
173
174 66
    public static function getAdapterInfo()
175
    {
176 66
        return 'GuzzleHttp/' . Client::VERSION;
177
    }
178
}
179