@@ -9,6 +9,5 @@ |
||
| 9 | 9 | * |
| 10 | 10 | * @author Márk Sági-Kazár <[email protected]> |
| 11 | 11 | */ |
| 12 | -interface Exception extends PsrClientException |
|
| 13 | -{ |
|
| 12 | +interface Exception extends PsrClientException { |
|
| 14 | 13 | } |
@@ -12,14 +12,14 @@ |
||
| 12 | 12 | */ |
| 13 | 13 | interface HttpAsyncClient |
| 14 | 14 | { |
| 15 | - /** |
|
| 16 | - * Sends a PSR-7 request in an asynchronous way. |
|
| 17 | - * |
|
| 18 | - * Exceptions related to processing the request are available from the returned Promise. |
|
| 19 | - * |
|
| 20 | - * @return Promise resolves a PSR-7 Response or fails with an OCA\FullTextSearch_Elasticsearch\Vendor\Http\Client\Exception |
|
| 21 | - * |
|
| 22 | - * @throws \Exception If processing the request is impossible (eg. bad configuration). |
|
| 23 | - */ |
|
| 24 | - public function sendAsyncRequest(RequestInterface $request); |
|
| 15 | + /** |
|
| 16 | + * Sends a PSR-7 request in an asynchronous way. |
|
| 17 | + * |
|
| 18 | + * Exceptions related to processing the request are available from the returned Promise. |
|
| 19 | + * |
|
| 20 | + * @return Promise resolves a PSR-7 Response or fails with an OCA\FullTextSearch_Elasticsearch\Vendor\Http\Client\Exception |
|
| 21 | + * |
|
| 22 | + * @throws \Exception If processing the request is impossible (eg. bad configuration). |
|
| 23 | + */ |
|
| 24 | + public function sendAsyncRequest(RequestInterface $request); |
|
| 25 | 25 | } |
@@ -10,8 +10,7 @@ |
||
| 10 | 10 | * |
| 11 | 11 | * @author Joel Wurtz <[email protected]> |
| 12 | 12 | */ |
| 13 | -interface HttpAsyncClient |
|
| 14 | -{ |
|
| 13 | +interface HttpAsyncClient { |
|
| 15 | 14 | /** |
| 16 | 15 | * Sends a PSR-7 request in an asynchronous way. |
| 17 | 16 | * |
@@ -14,52 +14,52 @@ |
||
| 14 | 14 | */ |
| 15 | 15 | class HttpException extends RequestException |
| 16 | 16 | { |
| 17 | - /** |
|
| 18 | - * @var ResponseInterface |
|
| 19 | - */ |
|
| 20 | - protected $response; |
|
| 17 | + /** |
|
| 18 | + * @var ResponseInterface |
|
| 19 | + */ |
|
| 20 | + protected $response; |
|
| 21 | 21 | |
| 22 | - /** |
|
| 23 | - * @param string $message |
|
| 24 | - */ |
|
| 25 | - public function __construct( |
|
| 26 | - $message, |
|
| 27 | - RequestInterface $request, |
|
| 28 | - ResponseInterface $response, |
|
| 29 | - \Exception $previous = null |
|
| 30 | - ) { |
|
| 31 | - parent::__construct($message, $request, $previous); |
|
| 22 | + /** |
|
| 23 | + * @param string $message |
|
| 24 | + */ |
|
| 25 | + public function __construct( |
|
| 26 | + $message, |
|
| 27 | + RequestInterface $request, |
|
| 28 | + ResponseInterface $response, |
|
| 29 | + \Exception $previous = null |
|
| 30 | + ) { |
|
| 31 | + parent::__construct($message, $request, $previous); |
|
| 32 | 32 | |
| 33 | - $this->response = $response; |
|
| 34 | - $this->code = $response->getStatusCode(); |
|
| 35 | - } |
|
| 33 | + $this->response = $response; |
|
| 34 | + $this->code = $response->getStatusCode(); |
|
| 35 | + } |
|
| 36 | 36 | |
| 37 | - /** |
|
| 38 | - * Returns the response. |
|
| 39 | - * |
|
| 40 | - * @return ResponseInterface |
|
| 41 | - */ |
|
| 42 | - public function getResponse() |
|
| 43 | - { |
|
| 44 | - return $this->response; |
|
| 45 | - } |
|
| 37 | + /** |
|
| 38 | + * Returns the response. |
|
| 39 | + * |
|
| 40 | + * @return ResponseInterface |
|
| 41 | + */ |
|
| 42 | + public function getResponse() |
|
| 43 | + { |
|
| 44 | + return $this->response; |
|
| 45 | + } |
|
| 46 | 46 | |
| 47 | - /** |
|
| 48 | - * Factory method to create a new exception with a normalized error message. |
|
| 49 | - */ |
|
| 50 | - public static function create( |
|
| 51 | - RequestInterface $request, |
|
| 52 | - ResponseInterface $response, |
|
| 53 | - \Exception $previous = null |
|
| 54 | - ) { |
|
| 55 | - $message = sprintf( |
|
| 56 | - '[url] %s [http method] %s [status code] %s [reason phrase] %s', |
|
| 57 | - $request->getRequestTarget(), |
|
| 58 | - $request->getMethod(), |
|
| 59 | - $response->getStatusCode(), |
|
| 60 | - $response->getReasonPhrase() |
|
| 61 | - ); |
|
| 47 | + /** |
|
| 48 | + * Factory method to create a new exception with a normalized error message. |
|
| 49 | + */ |
|
| 50 | + public static function create( |
|
| 51 | + RequestInterface $request, |
|
| 52 | + ResponseInterface $response, |
|
| 53 | + \Exception $previous = null |
|
| 54 | + ) { |
|
| 55 | + $message = sprintf( |
|
| 56 | + '[url] %s [http method] %s [status code] %s [reason phrase] %s', |
|
| 57 | + $request->getRequestTarget(), |
|
| 58 | + $request->getMethod(), |
|
| 59 | + $response->getStatusCode(), |
|
| 60 | + $response->getReasonPhrase() |
|
| 61 | + ); |
|
| 62 | 62 | |
| 63 | - return new static($message, $request, $response, $previous); |
|
| 64 | - } |
|
| 63 | + return new static($message, $request, $response, $previous); |
|
| 64 | + } |
|
| 65 | 65 | } |
@@ -12,8 +12,7 @@ |
||
| 12 | 12 | * |
| 13 | 13 | * @author Márk Sági-Kazár <[email protected]> |
| 14 | 14 | */ |
| 15 | -class HttpException extends RequestException |
|
| 16 | -{ |
|
| 15 | +class HttpException extends RequestException { |
|
| 17 | 16 | /** |
| 18 | 17 | * @var ResponseInterface |
| 19 | 18 | */ |
@@ -14,15 +14,15 @@ |
||
| 14 | 14 | */ |
| 15 | 15 | class NetworkException extends TransferException implements PsrNetworkException |
| 16 | 16 | { |
| 17 | - use RequestAwareTrait; |
|
| 17 | + use RequestAwareTrait; |
|
| 18 | 18 | |
| 19 | - /** |
|
| 20 | - * @param string $message |
|
| 21 | - */ |
|
| 22 | - public function __construct($message, RequestInterface $request, \Exception $previous = null) |
|
| 23 | - { |
|
| 24 | - $this->setRequest($request); |
|
| 19 | + /** |
|
| 20 | + * @param string $message |
|
| 21 | + */ |
|
| 22 | + public function __construct($message, RequestInterface $request, \Exception $previous = null) |
|
| 23 | + { |
|
| 24 | + $this->setRequest($request); |
|
| 25 | 25 | |
| 26 | - parent::__construct($message, 0, $previous); |
|
| 27 | - } |
|
| 26 | + parent::__construct($message, 0, $previous); |
|
| 27 | + } |
|
| 28 | 28 | } |
@@ -12,8 +12,7 @@ |
||
| 12 | 12 | * |
| 13 | 13 | * @author Márk Sági-Kazár <[email protected]> |
| 14 | 14 | */ |
| 15 | -class NetworkException extends TransferException implements PsrNetworkException |
|
| 16 | -{ |
|
| 15 | +class NetworkException extends TransferException implements PsrNetworkException { |
|
| 17 | 16 | use RequestAwareTrait; |
| 18 | 17 | |
| 19 | 18 | /** |
@@ -15,15 +15,15 @@ |
||
| 15 | 15 | */ |
| 16 | 16 | class RequestException extends TransferException implements PsrRequestException |
| 17 | 17 | { |
| 18 | - use RequestAwareTrait; |
|
| 18 | + use RequestAwareTrait; |
|
| 19 | 19 | |
| 20 | - /** |
|
| 21 | - * @param string $message |
|
| 22 | - */ |
|
| 23 | - public function __construct($message, RequestInterface $request, \Exception $previous = null) |
|
| 24 | - { |
|
| 25 | - $this->setRequest($request); |
|
| 20 | + /** |
|
| 21 | + * @param string $message |
|
| 22 | + */ |
|
| 23 | + public function __construct($message, RequestInterface $request, \Exception $previous = null) |
|
| 24 | + { |
|
| 25 | + $this->setRequest($request); |
|
| 26 | 26 | |
| 27 | - parent::__construct($message, 0, $previous); |
|
| 28 | - } |
|
| 27 | + parent::__construct($message, 0, $previous); |
|
| 28 | + } |
|
| 29 | 29 | } |
@@ -13,8 +13,7 @@ |
||
| 13 | 13 | * |
| 14 | 14 | * @author Márk Sági-Kazár <[email protected]> |
| 15 | 15 | */ |
| 16 | -class RequestException extends TransferException implements PsrRequestException |
|
| 17 | -{ |
|
| 16 | +class RequestException extends TransferException implements PsrRequestException { |
|
| 18 | 17 | use RequestAwareTrait; |
| 19 | 18 | |
| 20 | 19 | /** |
@@ -6,21 +6,21 @@ |
||
| 6 | 6 | |
| 7 | 7 | trait RequestAwareTrait |
| 8 | 8 | { |
| 9 | - /** |
|
| 10 | - * @var RequestInterface |
|
| 11 | - */ |
|
| 12 | - private $request; |
|
| 9 | + /** |
|
| 10 | + * @var RequestInterface |
|
| 11 | + */ |
|
| 12 | + private $request; |
|
| 13 | 13 | |
| 14 | - private function setRequest(RequestInterface $request) |
|
| 15 | - { |
|
| 16 | - $this->request = $request; |
|
| 17 | - } |
|
| 14 | + private function setRequest(RequestInterface $request) |
|
| 15 | + { |
|
| 16 | + $this->request = $request; |
|
| 17 | + } |
|
| 18 | 18 | |
| 19 | - /** |
|
| 20 | - * {@inheritdoc} |
|
| 21 | - */ |
|
| 22 | - public function getRequest(): RequestInterface |
|
| 23 | - { |
|
| 24 | - return $this->request; |
|
| 25 | - } |
|
| 19 | + /** |
|
| 20 | + * {@inheritdoc} |
|
| 21 | + */ |
|
| 22 | + public function getRequest(): RequestInterface |
|
| 23 | + { |
|
| 24 | + return $this->request; |
|
| 25 | + } |
|
| 26 | 26 | } |
@@ -4,8 +4,7 @@ |
||
| 4 | 4 | |
| 5 | 5 | use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\RequestInterface; |
| 6 | 6 | |
| 7 | -trait RequestAwareTrait |
|
| 8 | -{ |
|
| 7 | +trait RequestAwareTrait { |
|
| 9 | 8 | /** |
| 10 | 9 | * @var RequestInterface |
| 11 | 10 | */ |
@@ -8,47 +8,47 @@ |
||
| 8 | 8 | |
| 9 | 9 | final class HttpFulfilledPromise implements Promise |
| 10 | 10 | { |
| 11 | - /** |
|
| 12 | - * @var ResponseInterface |
|
| 13 | - */ |
|
| 14 | - private $response; |
|
| 15 | - |
|
| 16 | - public function __construct(ResponseInterface $response) |
|
| 17 | - { |
|
| 18 | - $this->response = $response; |
|
| 19 | - } |
|
| 20 | - |
|
| 21 | - /** |
|
| 22 | - * {@inheritdoc} |
|
| 23 | - */ |
|
| 24 | - public function then(callable $onFulfilled = null, callable $onRejected = null) |
|
| 25 | - { |
|
| 26 | - if (null === $onFulfilled) { |
|
| 27 | - return $this; |
|
| 28 | - } |
|
| 29 | - |
|
| 30 | - try { |
|
| 31 | - return new self($onFulfilled($this->response)); |
|
| 32 | - } catch (Exception $e) { |
|
| 33 | - return new HttpRejectedPromise($e); |
|
| 34 | - } |
|
| 35 | - } |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * {@inheritdoc} |
|
| 39 | - */ |
|
| 40 | - public function getState() |
|
| 41 | - { |
|
| 42 | - return Promise::FULFILLED; |
|
| 43 | - } |
|
| 44 | - |
|
| 45 | - /** |
|
| 46 | - * {@inheritdoc} |
|
| 47 | - */ |
|
| 48 | - public function wait($unwrap = true) |
|
| 49 | - { |
|
| 50 | - if ($unwrap) { |
|
| 51 | - return $this->response; |
|
| 52 | - } |
|
| 53 | - } |
|
| 11 | + /** |
|
| 12 | + * @var ResponseInterface |
|
| 13 | + */ |
|
| 14 | + private $response; |
|
| 15 | + |
|
| 16 | + public function __construct(ResponseInterface $response) |
|
| 17 | + { |
|
| 18 | + $this->response = $response; |
|
| 19 | + } |
|
| 20 | + |
|
| 21 | + /** |
|
| 22 | + * {@inheritdoc} |
|
| 23 | + */ |
|
| 24 | + public function then(callable $onFulfilled = null, callable $onRejected = null) |
|
| 25 | + { |
|
| 26 | + if (null === $onFulfilled) { |
|
| 27 | + return $this; |
|
| 28 | + } |
|
| 29 | + |
|
| 30 | + try { |
|
| 31 | + return new self($onFulfilled($this->response)); |
|
| 32 | + } catch (Exception $e) { |
|
| 33 | + return new HttpRejectedPromise($e); |
|
| 34 | + } |
|
| 35 | + } |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * {@inheritdoc} |
|
| 39 | + */ |
|
| 40 | + public function getState() |
|
| 41 | + { |
|
| 42 | + return Promise::FULFILLED; |
|
| 43 | + } |
|
| 44 | + |
|
| 45 | + /** |
|
| 46 | + * {@inheritdoc} |
|
| 47 | + */ |
|
| 48 | + public function wait($unwrap = true) |
|
| 49 | + { |
|
| 50 | + if ($unwrap) { |
|
| 51 | + return $this->response; |
|
| 52 | + } |
|
| 53 | + } |
|
| 54 | 54 | } |
@@ -6,8 +6,7 @@ |
||
| 6 | 6 | use OCA\FullTextSearch_Elasticsearch\Vendor\Http\Promise\Promise; |
| 7 | 7 | use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\ResponseInterface; |
| 8 | 8 | |
| 9 | -final class HttpFulfilledPromise implements Promise |
|
| 10 | -{ |
|
| 9 | +final class HttpFulfilledPromise implements Promise { |
|
| 11 | 10 | /** |
| 12 | 11 | * @var ResponseInterface |
| 13 | 12 | */ |
@@ -7,52 +7,52 @@ |
||
| 7 | 7 | |
| 8 | 8 | final class HttpRejectedPromise implements Promise |
| 9 | 9 | { |
| 10 | - /** |
|
| 11 | - * @var Exception |
|
| 12 | - */ |
|
| 13 | - private $exception; |
|
| 14 | - |
|
| 15 | - public function __construct(Exception $exception) |
|
| 16 | - { |
|
| 17 | - $this->exception = $exception; |
|
| 18 | - } |
|
| 19 | - |
|
| 20 | - /** |
|
| 21 | - * {@inheritdoc} |
|
| 22 | - */ |
|
| 23 | - public function then(callable $onFulfilled = null, callable $onRejected = null) |
|
| 24 | - { |
|
| 25 | - if (null === $onRejected) { |
|
| 26 | - return $this; |
|
| 27 | - } |
|
| 28 | - |
|
| 29 | - try { |
|
| 30 | - $result = $onRejected($this->exception); |
|
| 31 | - if ($result instanceof Promise) { |
|
| 32 | - return $result; |
|
| 33 | - } |
|
| 34 | - |
|
| 35 | - return new HttpFulfilledPromise($result); |
|
| 36 | - } catch (Exception $e) { |
|
| 37 | - return new self($e); |
|
| 38 | - } |
|
| 39 | - } |
|
| 40 | - |
|
| 41 | - /** |
|
| 42 | - * {@inheritdoc} |
|
| 43 | - */ |
|
| 44 | - public function getState() |
|
| 45 | - { |
|
| 46 | - return Promise::REJECTED; |
|
| 47 | - } |
|
| 48 | - |
|
| 49 | - /** |
|
| 50 | - * {@inheritdoc} |
|
| 51 | - */ |
|
| 52 | - public function wait($unwrap = true) |
|
| 53 | - { |
|
| 54 | - if ($unwrap) { |
|
| 55 | - throw $this->exception; |
|
| 56 | - } |
|
| 57 | - } |
|
| 10 | + /** |
|
| 11 | + * @var Exception |
|
| 12 | + */ |
|
| 13 | + private $exception; |
|
| 14 | + |
|
| 15 | + public function __construct(Exception $exception) |
|
| 16 | + { |
|
| 17 | + $this->exception = $exception; |
|
| 18 | + } |
|
| 19 | + |
|
| 20 | + /** |
|
| 21 | + * {@inheritdoc} |
|
| 22 | + */ |
|
| 23 | + public function then(callable $onFulfilled = null, callable $onRejected = null) |
|
| 24 | + { |
|
| 25 | + if (null === $onRejected) { |
|
| 26 | + return $this; |
|
| 27 | + } |
|
| 28 | + |
|
| 29 | + try { |
|
| 30 | + $result = $onRejected($this->exception); |
|
| 31 | + if ($result instanceof Promise) { |
|
| 32 | + return $result; |
|
| 33 | + } |
|
| 34 | + |
|
| 35 | + return new HttpFulfilledPromise($result); |
|
| 36 | + } catch (Exception $e) { |
|
| 37 | + return new self($e); |
|
| 38 | + } |
|
| 39 | + } |
|
| 40 | + |
|
| 41 | + /** |
|
| 42 | + * {@inheritdoc} |
|
| 43 | + */ |
|
| 44 | + public function getState() |
|
| 45 | + { |
|
| 46 | + return Promise::REJECTED; |
|
| 47 | + } |
|
| 48 | + |
|
| 49 | + /** |
|
| 50 | + * {@inheritdoc} |
|
| 51 | + */ |
|
| 52 | + public function wait($unwrap = true) |
|
| 53 | + { |
|
| 54 | + if ($unwrap) { |
|
| 55 | + throw $this->exception; |
|
| 56 | + } |
|
| 57 | + } |
|
| 58 | 58 | } |
@@ -5,8 +5,7 @@ |
||
| 5 | 5 | use OCA\FullTextSearch_Elasticsearch\Vendor\Http\Client\Exception; |
| 6 | 6 | use OCA\FullTextSearch_Elasticsearch\Vendor\Http\Promise\Promise; |
| 7 | 7 | |
| 8 | -final class HttpRejectedPromise implements Promise |
|
| 9 | -{ |
|
| 8 | +final class HttpRejectedPromise implements Promise { |
|
| 10 | 9 | /** |
| 11 | 10 | * @var Exception |
| 12 | 11 | */ |
@@ -48,420 +48,420 @@ |
||
| 48 | 48 | |
| 49 | 49 | final class Transport implements ClientInterface, HttpAsyncClient |
| 50 | 50 | { |
| 51 | - const VERSION = "8.8.0"; |
|
| 52 | - |
|
| 53 | - private ClientInterface $client; |
|
| 54 | - private LoggerInterface $logger; |
|
| 55 | - private NodePoolInterface $nodePool; |
|
| 56 | - private array $headers = []; |
|
| 57 | - private string $user; |
|
| 58 | - private string $password; |
|
| 59 | - private RequestInterface $lastRequest; |
|
| 60 | - private ResponseInterface $lastResponse; |
|
| 61 | - private string $OSVersion; |
|
| 62 | - private int $retries = 0; |
|
| 63 | - private HttpAsyncClient $asyncClient; |
|
| 64 | - private OnSuccessInterface $onAsyncSuccess; |
|
| 65 | - private OnFailureInterface $onAsyncFailure; |
|
| 66 | - |
|
| 67 | - public function __construct( |
|
| 68 | - ClientInterface $client, |
|
| 69 | - NodePoolInterface $nodePool, |
|
| 70 | - LoggerInterface $logger |
|
| 71 | - ) { |
|
| 72 | - $this->client = $client; |
|
| 73 | - $this->nodePool = $nodePool; |
|
| 74 | - $this->logger = $logger; |
|
| 75 | - } |
|
| 76 | - |
|
| 77 | - public function getClient(): ClientInterface |
|
| 78 | - { |
|
| 79 | - return $this->client; |
|
| 80 | - } |
|
| 81 | - |
|
| 82 | - public function getNodePool(): NodePoolInterface |
|
| 83 | - { |
|
| 84 | - return $this->nodePool; |
|
| 85 | - } |
|
| 86 | - |
|
| 87 | - public function getLogger(): LoggerInterface |
|
| 88 | - { |
|
| 89 | - return $this->logger; |
|
| 90 | - } |
|
| 91 | - |
|
| 92 | - public function setHeader(string $name, string $value): self |
|
| 93 | - { |
|
| 94 | - $this->headers[$name] = $value; |
|
| 95 | - return $this; |
|
| 96 | - } |
|
| 97 | - |
|
| 98 | - /** |
|
| 99 | - * @throws InvalidArgumentException |
|
| 100 | - */ |
|
| 101 | - public function setRetries(int $num): self |
|
| 102 | - { |
|
| 103 | - if ($num < 0) { |
|
| 104 | - throw new InvalidArgumentException('The retries number must be a positive integer'); |
|
| 105 | - } |
|
| 106 | - $this->retries = $num; |
|
| 107 | - return $this; |
|
| 108 | - } |
|
| 109 | - |
|
| 110 | - public function getRetries(): int |
|
| 111 | - { |
|
| 112 | - return $this->retries; |
|
| 113 | - } |
|
| 114 | - |
|
| 115 | - public function getHeaders(): array |
|
| 116 | - { |
|
| 117 | - return $this->headers; |
|
| 118 | - } |
|
| 119 | - |
|
| 120 | - public function setUserInfo(string $user, string $password = ''): self |
|
| 121 | - { |
|
| 122 | - $this->user = $user; |
|
| 123 | - $this->password = $password; |
|
| 124 | - return $this; |
|
| 125 | - } |
|
| 126 | - |
|
| 127 | - public function setUserAgent(string $name, string $version): self |
|
| 128 | - { |
|
| 129 | - $this->headers['User-Agent'] = sprintf( |
|
| 130 | - "%s/%s (%s %s; PHP %s)", |
|
| 131 | - $name, |
|
| 132 | - $version, |
|
| 133 | - PHP_OS, |
|
| 134 | - $this->getOSVersion(), |
|
| 135 | - phpversion() |
|
| 136 | - ); |
|
| 137 | - return $this; |
|
| 138 | - } |
|
| 139 | - |
|
| 140 | - /** |
|
| 141 | - * Set the x-elastic-client-meta header |
|
| 142 | - * |
|
| 143 | - * The header format is specified by the following regex: |
|
| 144 | - * ^[a-z]{1,}=[a-z0-9\.\-]{1,}(?:,[a-z]{1,}=[a-z0-9\.\-]+)*$ |
|
| 145 | - */ |
|
| 146 | - public function setElasticMetaHeader(string $clientName, string $clientVersion, bool $async = false): self |
|
| 147 | - { |
|
| 148 | - $phpSemVersion = sprintf("%d.%d.%d", PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION); |
|
| 149 | - $meta = sprintf( |
|
| 150 | - "%s=%s,php=%s,t=%s,a=%d", |
|
| 151 | - $clientName, |
|
| 152 | - $this->purgePreReleaseTag($clientVersion), |
|
| 153 | - $phpSemVersion, |
|
| 154 | - $this->purgePreReleaseTag(self::VERSION), |
|
| 155 | - $async ? 1 : 0 // 0=syncronous, 1=asynchronous |
|
| 156 | - ); |
|
| 157 | - $lib = $this->getClientLibraryInfo(); |
|
| 158 | - if (!empty($lib)) { |
|
| 159 | - $meta .= sprintf(",%s=%s", $lib[0], $lib[1]); |
|
| 160 | - } |
|
| 161 | - $this->headers['x-elastic-client-meta'] = $meta; |
|
| 162 | - return $this; |
|
| 163 | - } |
|
| 164 | - |
|
| 165 | - /** |
|
| 166 | - * Remove pre-release suffix with a single 'p' letter |
|
| 167 | - */ |
|
| 168 | - private function purgePreReleaseTag(string $version): string |
|
| 169 | - { |
|
| 170 | - return str_replace(['alpha', 'beta', 'snapshot', 'rc', 'pre'], 'p', strtolower($version)); |
|
| 171 | - } |
|
| 172 | - |
|
| 173 | - public function getLastRequest(): RequestInterface |
|
| 174 | - { |
|
| 175 | - return $this->lastRequest; |
|
| 176 | - } |
|
| 177 | - |
|
| 178 | - public function getLastResponse(): ResponseInterface |
|
| 179 | - { |
|
| 180 | - return $this->lastResponse; |
|
| 181 | - } |
|
| 182 | - |
|
| 183 | - /** |
|
| 184 | - * Setup the headers, if not already present |
|
| 185 | - */ |
|
| 186 | - private function setupHeaders(RequestInterface $request): RequestInterface |
|
| 187 | - { |
|
| 188 | - foreach ($this->headers as $name => $value) { |
|
| 189 | - if (!$request->hasHeader($name)) { |
|
| 190 | - $request = $request->withHeader($name, $value); |
|
| 191 | - } |
|
| 192 | - } |
|
| 193 | - return $request; |
|
| 194 | - } |
|
| 195 | - |
|
| 196 | - /** |
|
| 197 | - * Setup the user info, if not already present |
|
| 198 | - */ |
|
| 199 | - private function setupUserInfo(RequestInterface $request): RequestInterface |
|
| 200 | - { |
|
| 201 | - $uri = $request->getUri(); |
|
| 202 | - if (empty($uri->getUserInfo())) { |
|
| 203 | - if (isset($this->user)) { |
|
| 204 | - $request = $request->withUri($uri->withUserInfo($this->user, $this->password)); |
|
| 205 | - } |
|
| 206 | - } |
|
| 207 | - return $request; |
|
| 208 | - } |
|
| 209 | - |
|
| 210 | - /** |
|
| 211 | - * Setup the connection Uri |
|
| 212 | - */ |
|
| 213 | - private function setupConnectionUri(Node $node, RequestInterface $request): RequestInterface |
|
| 214 | - { |
|
| 215 | - $uri = $node->getUri(); |
|
| 216 | - $path = $request->getUri()->getPath(); |
|
| 51 | + const VERSION = "8.8.0"; |
|
| 52 | + |
|
| 53 | + private ClientInterface $client; |
|
| 54 | + private LoggerInterface $logger; |
|
| 55 | + private NodePoolInterface $nodePool; |
|
| 56 | + private array $headers = []; |
|
| 57 | + private string $user; |
|
| 58 | + private string $password; |
|
| 59 | + private RequestInterface $lastRequest; |
|
| 60 | + private ResponseInterface $lastResponse; |
|
| 61 | + private string $OSVersion; |
|
| 62 | + private int $retries = 0; |
|
| 63 | + private HttpAsyncClient $asyncClient; |
|
| 64 | + private OnSuccessInterface $onAsyncSuccess; |
|
| 65 | + private OnFailureInterface $onAsyncFailure; |
|
| 66 | + |
|
| 67 | + public function __construct( |
|
| 68 | + ClientInterface $client, |
|
| 69 | + NodePoolInterface $nodePool, |
|
| 70 | + LoggerInterface $logger |
|
| 71 | + ) { |
|
| 72 | + $this->client = $client; |
|
| 73 | + $this->nodePool = $nodePool; |
|
| 74 | + $this->logger = $logger; |
|
| 75 | + } |
|
| 76 | + |
|
| 77 | + public function getClient(): ClientInterface |
|
| 78 | + { |
|
| 79 | + return $this->client; |
|
| 80 | + } |
|
| 81 | + |
|
| 82 | + public function getNodePool(): NodePoolInterface |
|
| 83 | + { |
|
| 84 | + return $this->nodePool; |
|
| 85 | + } |
|
| 86 | + |
|
| 87 | + public function getLogger(): LoggerInterface |
|
| 88 | + { |
|
| 89 | + return $this->logger; |
|
| 90 | + } |
|
| 91 | + |
|
| 92 | + public function setHeader(string $name, string $value): self |
|
| 93 | + { |
|
| 94 | + $this->headers[$name] = $value; |
|
| 95 | + return $this; |
|
| 96 | + } |
|
| 97 | + |
|
| 98 | + /** |
|
| 99 | + * @throws InvalidArgumentException |
|
| 100 | + */ |
|
| 101 | + public function setRetries(int $num): self |
|
| 102 | + { |
|
| 103 | + if ($num < 0) { |
|
| 104 | + throw new InvalidArgumentException('The retries number must be a positive integer'); |
|
| 105 | + } |
|
| 106 | + $this->retries = $num; |
|
| 107 | + return $this; |
|
| 108 | + } |
|
| 109 | + |
|
| 110 | + public function getRetries(): int |
|
| 111 | + { |
|
| 112 | + return $this->retries; |
|
| 113 | + } |
|
| 114 | + |
|
| 115 | + public function getHeaders(): array |
|
| 116 | + { |
|
| 117 | + return $this->headers; |
|
| 118 | + } |
|
| 119 | + |
|
| 120 | + public function setUserInfo(string $user, string $password = ''): self |
|
| 121 | + { |
|
| 122 | + $this->user = $user; |
|
| 123 | + $this->password = $password; |
|
| 124 | + return $this; |
|
| 125 | + } |
|
| 126 | + |
|
| 127 | + public function setUserAgent(string $name, string $version): self |
|
| 128 | + { |
|
| 129 | + $this->headers['User-Agent'] = sprintf( |
|
| 130 | + "%s/%s (%s %s; PHP %s)", |
|
| 131 | + $name, |
|
| 132 | + $version, |
|
| 133 | + PHP_OS, |
|
| 134 | + $this->getOSVersion(), |
|
| 135 | + phpversion() |
|
| 136 | + ); |
|
| 137 | + return $this; |
|
| 138 | + } |
|
| 139 | + |
|
| 140 | + /** |
|
| 141 | + * Set the x-elastic-client-meta header |
|
| 142 | + * |
|
| 143 | + * The header format is specified by the following regex: |
|
| 144 | + * ^[a-z]{1,}=[a-z0-9\.\-]{1,}(?:,[a-z]{1,}=[a-z0-9\.\-]+)*$ |
|
| 145 | + */ |
|
| 146 | + public function setElasticMetaHeader(string $clientName, string $clientVersion, bool $async = false): self |
|
| 147 | + { |
|
| 148 | + $phpSemVersion = sprintf("%d.%d.%d", PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION); |
|
| 149 | + $meta = sprintf( |
|
| 150 | + "%s=%s,php=%s,t=%s,a=%d", |
|
| 151 | + $clientName, |
|
| 152 | + $this->purgePreReleaseTag($clientVersion), |
|
| 153 | + $phpSemVersion, |
|
| 154 | + $this->purgePreReleaseTag(self::VERSION), |
|
| 155 | + $async ? 1 : 0 // 0=syncronous, 1=asynchronous |
|
| 156 | + ); |
|
| 157 | + $lib = $this->getClientLibraryInfo(); |
|
| 158 | + if (!empty($lib)) { |
|
| 159 | + $meta .= sprintf(",%s=%s", $lib[0], $lib[1]); |
|
| 160 | + } |
|
| 161 | + $this->headers['x-elastic-client-meta'] = $meta; |
|
| 162 | + return $this; |
|
| 163 | + } |
|
| 164 | + |
|
| 165 | + /** |
|
| 166 | + * Remove pre-release suffix with a single 'p' letter |
|
| 167 | + */ |
|
| 168 | + private function purgePreReleaseTag(string $version): string |
|
| 169 | + { |
|
| 170 | + return str_replace(['alpha', 'beta', 'snapshot', 'rc', 'pre'], 'p', strtolower($version)); |
|
| 171 | + } |
|
| 172 | + |
|
| 173 | + public function getLastRequest(): RequestInterface |
|
| 174 | + { |
|
| 175 | + return $this->lastRequest; |
|
| 176 | + } |
|
| 177 | + |
|
| 178 | + public function getLastResponse(): ResponseInterface |
|
| 179 | + { |
|
| 180 | + return $this->lastResponse; |
|
| 181 | + } |
|
| 182 | + |
|
| 183 | + /** |
|
| 184 | + * Setup the headers, if not already present |
|
| 185 | + */ |
|
| 186 | + private function setupHeaders(RequestInterface $request): RequestInterface |
|
| 187 | + { |
|
| 188 | + foreach ($this->headers as $name => $value) { |
|
| 189 | + if (!$request->hasHeader($name)) { |
|
| 190 | + $request = $request->withHeader($name, $value); |
|
| 191 | + } |
|
| 192 | + } |
|
| 193 | + return $request; |
|
| 194 | + } |
|
| 195 | + |
|
| 196 | + /** |
|
| 197 | + * Setup the user info, if not already present |
|
| 198 | + */ |
|
| 199 | + private function setupUserInfo(RequestInterface $request): RequestInterface |
|
| 200 | + { |
|
| 201 | + $uri = $request->getUri(); |
|
| 202 | + if (empty($uri->getUserInfo())) { |
|
| 203 | + if (isset($this->user)) { |
|
| 204 | + $request = $request->withUri($uri->withUserInfo($this->user, $this->password)); |
|
| 205 | + } |
|
| 206 | + } |
|
| 207 | + return $request; |
|
| 208 | + } |
|
| 209 | + |
|
| 210 | + /** |
|
| 211 | + * Setup the connection Uri |
|
| 212 | + */ |
|
| 213 | + private function setupConnectionUri(Node $node, RequestInterface $request): RequestInterface |
|
| 214 | + { |
|
| 215 | + $uri = $node->getUri(); |
|
| 216 | + $path = $request->getUri()->getPath(); |
|
| 217 | 217 | |
| 218 | - $nodePath = $uri->getPath(); |
|
| 219 | - // If the node has a path we need to use it as prefix for the existing path |
|
| 220 | - // @see https://github.com/elastic/elastic-transport-php/pull/20 |
|
| 221 | - if (!empty($nodePath)) { |
|
| 222 | - $path = sprintf("%s/%s", rtrim($nodePath, '/'), ltrim($path,'/')); |
|
| 223 | - } |
|
| 224 | - // If the user information is not in the request, we check if it is present in the node uri |
|
| 225 | - // @see https://github.com/elastic/elastic-transport-php/issues/18 |
|
| 226 | - if (empty($request->getUri()->getUserInfo()) && !empty($uri->getUserInfo())) { |
|
| 227 | - $userInfo = explode(':', $uri->getUserInfo()); |
|
| 228 | - $request = $request->withUri( |
|
| 229 | - $request->getUri() |
|
| 230 | - ->withUserInfo($userInfo[0], $userInfo[1] ?? null) |
|
| 231 | - ); |
|
| 232 | - } |
|
| 233 | - return $request->withUri( |
|
| 234 | - $request->getUri() |
|
| 235 | - ->withHost($uri->getHost()) |
|
| 236 | - ->withPort($uri->getPort()) |
|
| 237 | - ->withScheme($uri->getScheme()) |
|
| 238 | - ->withPath($path) |
|
| 239 | - ); |
|
| 240 | - } |
|
| 241 | - |
|
| 242 | - private function decorateRequest(RequestInterface $request): RequestInterface |
|
| 243 | - { |
|
| 244 | - $request = $this->setupHeaders($request); |
|
| 245 | - return $this->setupUserInfo($request); |
|
| 246 | - } |
|
| 247 | - |
|
| 248 | - private function logHeaders(MessageInterface $message): void |
|
| 249 | - { |
|
| 250 | - $this->logger->debug(sprintf( |
|
| 251 | - "Headers: %s\nBody: %s", |
|
| 252 | - json_encode($message->getHeaders()), |
|
| 253 | - (string) $message->getBody() |
|
| 254 | - )); |
|
| 255 | - } |
|
| 256 | - |
|
| 257 | - private function logRequest(string $title, RequestInterface $request): void |
|
| 258 | - { |
|
| 259 | - $this->logger->info(sprintf( |
|
| 260 | - "%s: %s %s", |
|
| 261 | - $title, |
|
| 262 | - $request->getMethod(), |
|
| 263 | - (string) $request->getUri() |
|
| 264 | - ), [ |
|
| 265 | - 'request' => $request |
|
| 266 | - ]); |
|
| 267 | - $this->logHeaders($request); |
|
| 268 | - } |
|
| 269 | - |
|
| 270 | - private function logResponse(string $title, ResponseInterface $response, int $retry): void |
|
| 271 | - { |
|
| 272 | - $this->logger->info(sprintf( |
|
| 273 | - "%s (retry %d): %d", |
|
| 274 | - $title, |
|
| 275 | - $retry, |
|
| 276 | - $response->getStatusCode() |
|
| 277 | - ), [ |
|
| 278 | - 'response' => $response, |
|
| 279 | - 'retry' => $retry |
|
| 280 | - ]); |
|
| 281 | - $this->logHeaders($response); |
|
| 282 | - } |
|
| 283 | - |
|
| 284 | - /** |
|
| 285 | - * @throws NoNodeAvailableException |
|
| 286 | - * @throws ClientExceptionInterface |
|
| 287 | - */ |
|
| 288 | - public function sendRequest(RequestInterface $request): ResponseInterface |
|
| 289 | - { |
|
| 290 | - if (empty($request->getUri()->getHost())) { |
|
| 291 | - $node = $this->nodePool->nextNode(); |
|
| 292 | - $request = $this->setupConnectionUri($node, $request); |
|
| 293 | - } |
|
| 294 | - $request = $this->decorateRequest($request); |
|
| 295 | - $this->lastRequest = $request; |
|
| 296 | - $this->logRequest("Request", $request); |
|
| 218 | + $nodePath = $uri->getPath(); |
|
| 219 | + // If the node has a path we need to use it as prefix for the existing path |
|
| 220 | + // @see https://github.com/elastic/elastic-transport-php/pull/20 |
|
| 221 | + if (!empty($nodePath)) { |
|
| 222 | + $path = sprintf("%s/%s", rtrim($nodePath, '/'), ltrim($path,'/')); |
|
| 223 | + } |
|
| 224 | + // If the user information is not in the request, we check if it is present in the node uri |
|
| 225 | + // @see https://github.com/elastic/elastic-transport-php/issues/18 |
|
| 226 | + if (empty($request->getUri()->getUserInfo()) && !empty($uri->getUserInfo())) { |
|
| 227 | + $userInfo = explode(':', $uri->getUserInfo()); |
|
| 228 | + $request = $request->withUri( |
|
| 229 | + $request->getUri() |
|
| 230 | + ->withUserInfo($userInfo[0], $userInfo[1] ?? null) |
|
| 231 | + ); |
|
| 232 | + } |
|
| 233 | + return $request->withUri( |
|
| 234 | + $request->getUri() |
|
| 235 | + ->withHost($uri->getHost()) |
|
| 236 | + ->withPort($uri->getPort()) |
|
| 237 | + ->withScheme($uri->getScheme()) |
|
| 238 | + ->withPath($path) |
|
| 239 | + ); |
|
| 240 | + } |
|
| 241 | + |
|
| 242 | + private function decorateRequest(RequestInterface $request): RequestInterface |
|
| 243 | + { |
|
| 244 | + $request = $this->setupHeaders($request); |
|
| 245 | + return $this->setupUserInfo($request); |
|
| 246 | + } |
|
| 247 | + |
|
| 248 | + private function logHeaders(MessageInterface $message): void |
|
| 249 | + { |
|
| 250 | + $this->logger->debug(sprintf( |
|
| 251 | + "Headers: %s\nBody: %s", |
|
| 252 | + json_encode($message->getHeaders()), |
|
| 253 | + (string) $message->getBody() |
|
| 254 | + )); |
|
| 255 | + } |
|
| 256 | + |
|
| 257 | + private function logRequest(string $title, RequestInterface $request): void |
|
| 258 | + { |
|
| 259 | + $this->logger->info(sprintf( |
|
| 260 | + "%s: %s %s", |
|
| 261 | + $title, |
|
| 262 | + $request->getMethod(), |
|
| 263 | + (string) $request->getUri() |
|
| 264 | + ), [ |
|
| 265 | + 'request' => $request |
|
| 266 | + ]); |
|
| 267 | + $this->logHeaders($request); |
|
| 268 | + } |
|
| 269 | + |
|
| 270 | + private function logResponse(string $title, ResponseInterface $response, int $retry): void |
|
| 271 | + { |
|
| 272 | + $this->logger->info(sprintf( |
|
| 273 | + "%s (retry %d): %d", |
|
| 274 | + $title, |
|
| 275 | + $retry, |
|
| 276 | + $response->getStatusCode() |
|
| 277 | + ), [ |
|
| 278 | + 'response' => $response, |
|
| 279 | + 'retry' => $retry |
|
| 280 | + ]); |
|
| 281 | + $this->logHeaders($response); |
|
| 282 | + } |
|
| 283 | + |
|
| 284 | + /** |
|
| 285 | + * @throws NoNodeAvailableException |
|
| 286 | + * @throws ClientExceptionInterface |
|
| 287 | + */ |
|
| 288 | + public function sendRequest(RequestInterface $request): ResponseInterface |
|
| 289 | + { |
|
| 290 | + if (empty($request->getUri()->getHost())) { |
|
| 291 | + $node = $this->nodePool->nextNode(); |
|
| 292 | + $request = $this->setupConnectionUri($node, $request); |
|
| 293 | + } |
|
| 294 | + $request = $this->decorateRequest($request); |
|
| 295 | + $this->lastRequest = $request; |
|
| 296 | + $this->logRequest("Request", $request); |
|
| 297 | 297 | |
| 298 | - $count = -1; |
|
| 299 | - while ($count < $this->getRetries()) { |
|
| 300 | - try { |
|
| 301 | - $count++; |
|
| 302 | - $response = $this->client->sendRequest($request); |
|
| 303 | - |
|
| 304 | - $this->lastResponse = $response; |
|
| 305 | - $this->logResponse("Response", $response, $count); |
|
| 306 | - |
|
| 307 | - return $response; |
|
| 308 | - } catch (NetworkExceptionInterface $e) { |
|
| 309 | - $this->logger->error(sprintf("Retry %d: %s", $count, $e->getMessage())); |
|
| 310 | - if (isset($node)) { |
|
| 311 | - $node->markAlive(false); |
|
| 312 | - $node = $this->nodePool->nextNode(); |
|
| 313 | - $request = $this->setupConnectionUri($node, $request); |
|
| 314 | - } |
|
| 315 | - } catch (ClientExceptionInterface $e) { |
|
| 316 | - $this->logger->error(sprintf("Retry %d: %s", $count, $e->getMessage())); |
|
| 317 | - throw $e; |
|
| 318 | - } |
|
| 319 | - } |
|
| 320 | - $exceededMsg = sprintf("Exceeded maximum number of retries (%d)", $this->getRetries()); |
|
| 321 | - $this->logger->error($exceededMsg); |
|
| 322 | - throw new NoNodeAvailableException($exceededMsg); |
|
| 323 | - } |
|
| 324 | - |
|
| 325 | - public function setAsyncClient(HttpAsyncClient $asyncClient): self |
|
| 326 | - { |
|
| 327 | - $this->asyncClient = $asyncClient; |
|
| 328 | - return $this; |
|
| 329 | - } |
|
| 330 | - |
|
| 331 | - /** |
|
| 332 | - * @throws NoAsyncClientException |
|
| 333 | - */ |
|
| 334 | - public function getAsyncClient(): HttpAsyncClient |
|
| 335 | - { |
|
| 336 | - if (!empty($this->asyncClient)) { |
|
| 337 | - return $this->asyncClient; |
|
| 338 | - } |
|
| 339 | - if ($this->client instanceof HttpAsyncClient) { |
|
| 340 | - return $this->client; |
|
| 341 | - } |
|
| 342 | - try { |
|
| 343 | - $this->asyncClient = HttpAsyncClientDiscovery::find(); |
|
| 344 | - } catch (Exception $e) { |
|
| 345 | - throw new NoAsyncClientException(sprintf( |
|
| 346 | - "I did not find any HTTP library with HttpAsyncClient interface. " . |
|
| 347 | - "Make sure to install a package providing \"php-http/async-client-implementation\". " . |
|
| 348 | - "You can also set a specific async library using %s::setAsyncClient()", |
|
| 349 | - self::class |
|
| 350 | - )); |
|
| 351 | - } |
|
| 352 | - return $this->asyncClient; |
|
| 353 | - } |
|
| 354 | - |
|
| 355 | - public function setAsyncOnSuccess(OnSuccessInterface $success): self |
|
| 356 | - { |
|
| 357 | - $this->onAsyncSuccess = $success; |
|
| 358 | - return $this; |
|
| 359 | - } |
|
| 360 | - |
|
| 361 | - public function getAsyncOnSuccess(): OnSuccessInterface |
|
| 362 | - { |
|
| 363 | - if (empty($this->onAsyncSuccess)) { |
|
| 364 | - $this->onAsyncSuccess = new OnSuccessDefault(); |
|
| 365 | - } |
|
| 366 | - return $this->onAsyncSuccess; |
|
| 367 | - } |
|
| 368 | - |
|
| 369 | - public function setAsyncOnFailure(OnFailureInterface $failure): self |
|
| 370 | - { |
|
| 371 | - $this->onAsyncFailure = $failure; |
|
| 372 | - return $this; |
|
| 373 | - } |
|
| 374 | - |
|
| 375 | - public function getAsyncOnFailure(): OnFailureInterface |
|
| 376 | - { |
|
| 377 | - if (empty($this->onAsyncFailure)) { |
|
| 378 | - $this->onAsyncFailure = new OnFailureDefault(); |
|
| 379 | - } |
|
| 380 | - return $this->onAsyncFailure; |
|
| 381 | - } |
|
| 382 | - |
|
| 383 | - /** |
|
| 384 | - * @throws Exception |
|
| 385 | - */ |
|
| 386 | - public function sendAsyncRequest(RequestInterface $request): Promise |
|
| 387 | - { |
|
| 388 | - $client = $this->getAsyncClient(); |
|
| 389 | - $node = null; |
|
| 390 | - if (empty($request->getUri()->getHost())) { |
|
| 391 | - $node = $this->nodePool->nextNode(); |
|
| 392 | - $request = $this->setupConnectionUri($node, $request); |
|
| 393 | - } |
|
| 394 | - $request = $this->decorateRequest($request); |
|
| 395 | - $this->lastRequest = $request; |
|
| 396 | - $this->logRequest("Async Request", $request); |
|
| 397 | - |
|
| 398 | - $count = 0; |
|
| 399 | - $promise = $client->sendAsyncRequest($request); |
|
| 400 | - |
|
| 401 | - // onFulfilled callable |
|
| 402 | - $onFulfilled = function (ResponseInterface $response) use (&$count) { |
|
| 403 | - $this->lastResponse = $response; |
|
| 404 | - $this->logResponse("Async Response", $response, $count); |
|
| 405 | - return $this->getAsyncOnSuccess()->success($response, $count); |
|
| 406 | - }; |
|
| 407 | - |
|
| 408 | - // onRejected callable |
|
| 409 | - $onRejected = function (Exception $e) use ($client, $request, &$count, $node) { |
|
| 410 | - $this->logger->error(sprintf("Retry %d: %s", $count, $e->getMessage())); |
|
| 411 | - $this->getAsyncOnFailure()->failure($e, $request, $count, $node ?? null); |
|
| 412 | - if (isset($node)) { |
|
| 413 | - $node->markAlive(false); |
|
| 414 | - $node = $this->nodePool->nextNode(); |
|
| 415 | - $request = $this->setupConnectionUri($node, $request); |
|
| 416 | - } |
|
| 417 | - $count++; |
|
| 418 | - return $client->sendAsyncRequest($request); |
|
| 419 | - }; |
|
| 298 | + $count = -1; |
|
| 299 | + while ($count < $this->getRetries()) { |
|
| 300 | + try { |
|
| 301 | + $count++; |
|
| 302 | + $response = $this->client->sendRequest($request); |
|
| 303 | + |
|
| 304 | + $this->lastResponse = $response; |
|
| 305 | + $this->logResponse("Response", $response, $count); |
|
| 306 | + |
|
| 307 | + return $response; |
|
| 308 | + } catch (NetworkExceptionInterface $e) { |
|
| 309 | + $this->logger->error(sprintf("Retry %d: %s", $count, $e->getMessage())); |
|
| 310 | + if (isset($node)) { |
|
| 311 | + $node->markAlive(false); |
|
| 312 | + $node = $this->nodePool->nextNode(); |
|
| 313 | + $request = $this->setupConnectionUri($node, $request); |
|
| 314 | + } |
|
| 315 | + } catch (ClientExceptionInterface $e) { |
|
| 316 | + $this->logger->error(sprintf("Retry %d: %s", $count, $e->getMessage())); |
|
| 317 | + throw $e; |
|
| 318 | + } |
|
| 319 | + } |
|
| 320 | + $exceededMsg = sprintf("Exceeded maximum number of retries (%d)", $this->getRetries()); |
|
| 321 | + $this->logger->error($exceededMsg); |
|
| 322 | + throw new NoNodeAvailableException($exceededMsg); |
|
| 323 | + } |
|
| 324 | + |
|
| 325 | + public function setAsyncClient(HttpAsyncClient $asyncClient): self |
|
| 326 | + { |
|
| 327 | + $this->asyncClient = $asyncClient; |
|
| 328 | + return $this; |
|
| 329 | + } |
|
| 330 | + |
|
| 331 | + /** |
|
| 332 | + * @throws NoAsyncClientException |
|
| 333 | + */ |
|
| 334 | + public function getAsyncClient(): HttpAsyncClient |
|
| 335 | + { |
|
| 336 | + if (!empty($this->asyncClient)) { |
|
| 337 | + return $this->asyncClient; |
|
| 338 | + } |
|
| 339 | + if ($this->client instanceof HttpAsyncClient) { |
|
| 340 | + return $this->client; |
|
| 341 | + } |
|
| 342 | + try { |
|
| 343 | + $this->asyncClient = HttpAsyncClientDiscovery::find(); |
|
| 344 | + } catch (Exception $e) { |
|
| 345 | + throw new NoAsyncClientException(sprintf( |
|
| 346 | + "I did not find any HTTP library with HttpAsyncClient interface. " . |
|
| 347 | + "Make sure to install a package providing \"php-http/async-client-implementation\". " . |
|
| 348 | + "You can also set a specific async library using %s::setAsyncClient()", |
|
| 349 | + self::class |
|
| 350 | + )); |
|
| 351 | + } |
|
| 352 | + return $this->asyncClient; |
|
| 353 | + } |
|
| 354 | + |
|
| 355 | + public function setAsyncOnSuccess(OnSuccessInterface $success): self |
|
| 356 | + { |
|
| 357 | + $this->onAsyncSuccess = $success; |
|
| 358 | + return $this; |
|
| 359 | + } |
|
| 360 | + |
|
| 361 | + public function getAsyncOnSuccess(): OnSuccessInterface |
|
| 362 | + { |
|
| 363 | + if (empty($this->onAsyncSuccess)) { |
|
| 364 | + $this->onAsyncSuccess = new OnSuccessDefault(); |
|
| 365 | + } |
|
| 366 | + return $this->onAsyncSuccess; |
|
| 367 | + } |
|
| 368 | + |
|
| 369 | + public function setAsyncOnFailure(OnFailureInterface $failure): self |
|
| 370 | + { |
|
| 371 | + $this->onAsyncFailure = $failure; |
|
| 372 | + return $this; |
|
| 373 | + } |
|
| 374 | + |
|
| 375 | + public function getAsyncOnFailure(): OnFailureInterface |
|
| 376 | + { |
|
| 377 | + if (empty($this->onAsyncFailure)) { |
|
| 378 | + $this->onAsyncFailure = new OnFailureDefault(); |
|
| 379 | + } |
|
| 380 | + return $this->onAsyncFailure; |
|
| 381 | + } |
|
| 382 | + |
|
| 383 | + /** |
|
| 384 | + * @throws Exception |
|
| 385 | + */ |
|
| 386 | + public function sendAsyncRequest(RequestInterface $request): Promise |
|
| 387 | + { |
|
| 388 | + $client = $this->getAsyncClient(); |
|
| 389 | + $node = null; |
|
| 390 | + if (empty($request->getUri()->getHost())) { |
|
| 391 | + $node = $this->nodePool->nextNode(); |
|
| 392 | + $request = $this->setupConnectionUri($node, $request); |
|
| 393 | + } |
|
| 394 | + $request = $this->decorateRequest($request); |
|
| 395 | + $this->lastRequest = $request; |
|
| 396 | + $this->logRequest("Async Request", $request); |
|
| 397 | + |
|
| 398 | + $count = 0; |
|
| 399 | + $promise = $client->sendAsyncRequest($request); |
|
| 400 | + |
|
| 401 | + // onFulfilled callable |
|
| 402 | + $onFulfilled = function (ResponseInterface $response) use (&$count) { |
|
| 403 | + $this->lastResponse = $response; |
|
| 404 | + $this->logResponse("Async Response", $response, $count); |
|
| 405 | + return $this->getAsyncOnSuccess()->success($response, $count); |
|
| 406 | + }; |
|
| 407 | + |
|
| 408 | + // onRejected callable |
|
| 409 | + $onRejected = function (Exception $e) use ($client, $request, &$count, $node) { |
|
| 410 | + $this->logger->error(sprintf("Retry %d: %s", $count, $e->getMessage())); |
|
| 411 | + $this->getAsyncOnFailure()->failure($e, $request, $count, $node ?? null); |
|
| 412 | + if (isset($node)) { |
|
| 413 | + $node->markAlive(false); |
|
| 414 | + $node = $this->nodePool->nextNode(); |
|
| 415 | + $request = $this->setupConnectionUri($node, $request); |
|
| 416 | + } |
|
| 417 | + $count++; |
|
| 418 | + return $client->sendAsyncRequest($request); |
|
| 419 | + }; |
|
| 420 | 420 | |
| 421 | - // Add getRetries() callables using then() |
|
| 422 | - for ($i=0; $i < $this->getRetries(); $i++) { |
|
| 423 | - $promise = $promise->then($onFulfilled, $onRejected); |
|
| 424 | - } |
|
| 425 | - // Add the last getRetries()+1 callable for managing the exceeded error |
|
| 426 | - $promise = $promise->then($onFulfilled, function(Exception $e) use (&$count) { |
|
| 427 | - $exceededMsg = sprintf("Exceeded maximum number of retries (%d)", $this->getRetries()); |
|
| 428 | - $this->logger->error(sprintf("Retry %d: %s", $count, $e->getMessage())); |
|
| 429 | - $this->logger->error($exceededMsg); |
|
| 430 | - throw new NoNodeAvailableException(sprintf("%s: %s", $exceededMsg, $e->getMessage())); |
|
| 431 | - }); |
|
| 432 | - return $promise; |
|
| 433 | - } |
|
| 434 | - |
|
| 435 | - /** |
|
| 436 | - * Get the OS version using php_uname if available |
|
| 437 | - * otherwise it returns an empty string |
|
| 438 | - */ |
|
| 439 | - private function getOSVersion(): string |
|
| 440 | - { |
|
| 441 | - if (!isset($this->OSVersion)) { |
|
| 442 | - $disable_functions = (string) ini_get('disable_functions'); |
|
| 443 | - $this->OSVersion = strpos(strtolower($disable_functions), 'php_uname') !== false |
|
| 444 | - ? '' |
|
| 445 | - : php_uname("r"); |
|
| 446 | - } |
|
| 447 | - return $this->OSVersion; |
|
| 448 | - } |
|
| 449 | - |
|
| 450 | - /** |
|
| 451 | - * Returns the name and the version of the Client HTTP library used |
|
| 452 | - * Here a list of supported libraries: |
|
| 453 | - * gu => guzzlehttp/guzzle |
|
| 454 | - * sy => symfony/http-client |
|
| 455 | - */ |
|
| 456 | - private function getClientLibraryInfo(): array |
|
| 457 | - { |
|
| 458 | - $clientClass = get_class($this->client); |
|
| 459 | - if (false !== strpos($clientClass, 'GuzzleHttp\Client')) { |
|
| 460 | - return ['gu', InstalledVersions::getPrettyVersion('guzzlehttp/guzzle')]; |
|
| 461 | - } |
|
| 462 | - if (false !== strpos($clientClass, 'Symfony\Component\HttpClient')) { |
|
| 463 | - return ['sy', InstalledVersions::getPrettyVersion('symfony/http-client')]; |
|
| 464 | - } |
|
| 465 | - return []; |
|
| 466 | - } |
|
| 421 | + // Add getRetries() callables using then() |
|
| 422 | + for ($i=0; $i < $this->getRetries(); $i++) { |
|
| 423 | + $promise = $promise->then($onFulfilled, $onRejected); |
|
| 424 | + } |
|
| 425 | + // Add the last getRetries()+1 callable for managing the exceeded error |
|
| 426 | + $promise = $promise->then($onFulfilled, function(Exception $e) use (&$count) { |
|
| 427 | + $exceededMsg = sprintf("Exceeded maximum number of retries (%d)", $this->getRetries()); |
|
| 428 | + $this->logger->error(sprintf("Retry %d: %s", $count, $e->getMessage())); |
|
| 429 | + $this->logger->error($exceededMsg); |
|
| 430 | + throw new NoNodeAvailableException(sprintf("%s: %s", $exceededMsg, $e->getMessage())); |
|
| 431 | + }); |
|
| 432 | + return $promise; |
|
| 433 | + } |
|
| 434 | + |
|
| 435 | + /** |
|
| 436 | + * Get the OS version using php_uname if available |
|
| 437 | + * otherwise it returns an empty string |
|
| 438 | + */ |
|
| 439 | + private function getOSVersion(): string |
|
| 440 | + { |
|
| 441 | + if (!isset($this->OSVersion)) { |
|
| 442 | + $disable_functions = (string) ini_get('disable_functions'); |
|
| 443 | + $this->OSVersion = strpos(strtolower($disable_functions), 'php_uname') !== false |
|
| 444 | + ? '' |
|
| 445 | + : php_uname("r"); |
|
| 446 | + } |
|
| 447 | + return $this->OSVersion; |
|
| 448 | + } |
|
| 449 | + |
|
| 450 | + /** |
|
| 451 | + * Returns the name and the version of the Client HTTP library used |
|
| 452 | + * Here a list of supported libraries: |
|
| 453 | + * gu => guzzlehttp/guzzle |
|
| 454 | + * sy => symfony/http-client |
|
| 455 | + */ |
|
| 456 | + private function getClientLibraryInfo(): array |
|
| 457 | + { |
|
| 458 | + $clientClass = get_class($this->client); |
|
| 459 | + if (false !== strpos($clientClass, 'GuzzleHttp\Client')) { |
|
| 460 | + return ['gu', InstalledVersions::getPrettyVersion('guzzlehttp/guzzle')]; |
|
| 461 | + } |
|
| 462 | + if (false !== strpos($clientClass, 'Symfony\Component\HttpClient')) { |
|
| 463 | + return ['sy', InstalledVersions::getPrettyVersion('symfony/http-client')]; |
|
| 464 | + } |
|
| 465 | + return []; |
|
| 466 | + } |
|
| 467 | 467 | } |
@@ -219,7 +219,7 @@ discard block |
||
| 219 | 219 | // If the node has a path we need to use it as prefix for the existing path |
| 220 | 220 | // @see https://github.com/elastic/elastic-transport-php/pull/20 |
| 221 | 221 | if (!empty($nodePath)) { |
| 222 | - $path = sprintf("%s/%s", rtrim($nodePath, '/'), ltrim($path,'/')); |
|
| 222 | + $path = sprintf("%s/%s", rtrim($nodePath, '/'), ltrim($path, '/')); |
|
| 223 | 223 | } |
| 224 | 224 | // If the user information is not in the request, we check if it is present in the node uri |
| 225 | 225 | // @see https://github.com/elastic/elastic-transport-php/issues/18 |
@@ -250,7 +250,7 @@ discard block |
||
| 250 | 250 | $this->logger->debug(sprintf( |
| 251 | 251 | "Headers: %s\nBody: %s", |
| 252 | 252 | json_encode($message->getHeaders()), |
| 253 | - (string) $message->getBody() |
|
| 253 | + (string)$message->getBody() |
|
| 254 | 254 | )); |
| 255 | 255 | } |
| 256 | 256 | |
@@ -260,7 +260,7 @@ discard block |
||
| 260 | 260 | "%s: %s %s", |
| 261 | 261 | $title, |
| 262 | 262 | $request->getMethod(), |
| 263 | - (string) $request->getUri() |
|
| 263 | + (string)$request->getUri() |
|
| 264 | 264 | ), [ |
| 265 | 265 | 'request' => $request |
| 266 | 266 | ]); |
@@ -343,8 +343,8 @@ discard block |
||
| 343 | 343 | $this->asyncClient = HttpAsyncClientDiscovery::find(); |
| 344 | 344 | } catch (Exception $e) { |
| 345 | 345 | throw new NoAsyncClientException(sprintf( |
| 346 | - "I did not find any HTTP library with HttpAsyncClient interface. " . |
|
| 347 | - "Make sure to install a package providing \"php-http/async-client-implementation\". " . |
|
| 346 | + "I did not find any HTTP library with HttpAsyncClient interface. ". |
|
| 347 | + "Make sure to install a package providing \"php-http/async-client-implementation\". ". |
|
| 348 | 348 | "You can also set a specific async library using %s::setAsyncClient()", |
| 349 | 349 | self::class |
| 350 | 350 | )); |
@@ -399,14 +399,14 @@ discard block |
||
| 399 | 399 | $promise = $client->sendAsyncRequest($request); |
| 400 | 400 | |
| 401 | 401 | // onFulfilled callable |
| 402 | - $onFulfilled = function (ResponseInterface $response) use (&$count) { |
|
| 402 | + $onFulfilled = function(ResponseInterface $response) use (&$count) { |
|
| 403 | 403 | $this->lastResponse = $response; |
| 404 | 404 | $this->logResponse("Async Response", $response, $count); |
| 405 | 405 | return $this->getAsyncOnSuccess()->success($response, $count); |
| 406 | 406 | }; |
| 407 | 407 | |
| 408 | 408 | // onRejected callable |
| 409 | - $onRejected = function (Exception $e) use ($client, $request, &$count, $node) { |
|
| 409 | + $onRejected = function(Exception $e) use ($client, $request, &$count, $node) { |
|
| 410 | 410 | $this->logger->error(sprintf("Retry %d: %s", $count, $e->getMessage())); |
| 411 | 411 | $this->getAsyncOnFailure()->failure($e, $request, $count, $node ?? null); |
| 412 | 412 | if (isset($node)) { |
@@ -419,7 +419,7 @@ discard block |
||
| 419 | 419 | }; |
| 420 | 420 | |
| 421 | 421 | // Add getRetries() callables using then() |
| 422 | - for ($i=0; $i < $this->getRetries(); $i++) { |
|
| 422 | + for ($i = 0; $i < $this->getRetries(); $i++) { |
|
| 423 | 423 | $promise = $promise->then($onFulfilled, $onRejected); |
| 424 | 424 | } |
| 425 | 425 | // Add the last getRetries()+1 callable for managing the exceeded error |
@@ -439,7 +439,7 @@ discard block |
||
| 439 | 439 | private function getOSVersion(): string |
| 440 | 440 | { |
| 441 | 441 | if (!isset($this->OSVersion)) { |
| 442 | - $disable_functions = (string) ini_get('disable_functions'); |
|
| 442 | + $disable_functions = (string)ini_get('disable_functions'); |
|
| 443 | 443 | $this->OSVersion = strpos(strtolower($disable_functions), 'php_uname') !== false |
| 444 | 444 | ? '' |
| 445 | 445 | : php_uname("r"); |