Skip to content

Commit

Permalink
beginning work on using object responses
Browse files Browse the repository at this point in the history
  • Loading branch information
dcarbone committed Nov 18, 2020
1 parent f112603 commit 49167ce
Show file tree
Hide file tree
Showing 16 changed files with 476 additions and 200 deletions.
28 changes: 14 additions & 14 deletions src/ACL/ACLClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ public function bootstrap(): array
$r = new Request('PUT', 'v1/acl/bootstrap', $this->config);

/** @var \Psr\Http\Message\ResponseInterface $response */
list($duration, $response, $err) = $this->requireOK($this->doRequest($r));
[$duration, $response, $err] = $this->requireOK($this->doRequest($r));
if (null !== $err) {
return ['', null, $err];
}

list($data, $err) = $this->decodeBody($response->getBody());
[$data, $err] = $this->decodeBody($response->getBody());
if (null !== $err) {
return ['', null, $err];
}
Expand All @@ -71,14 +71,14 @@ public function create(ACLEntry $acl, WriteOptions $options = null): array
$r->setWriteOptions($options);

/** @var \Psr\Http\Message\ResponseInterface $response */
list($duration, $response, $err) = $this->requireOK($this->doRequest($r));
[$duration, $response, $err] = $this->requireOK($this->doRequest($r));
if (null !== $err) {
return ['', null, $err];
}

$wm = $this->buildWriteMeta($duration);

list($data, $err) = $this->decodeBody($response->getBody());
[$data, $err] = $this->decodeBody($response->getBody());
if (null !== $err) {
return ['', $wm, $err];
}
Expand All @@ -99,7 +99,7 @@ public function update(ACLEntry $acl, WriteOptions $options = null): array
$r = new Request('PUT', 'v1/acl/update', $this->config, $acl);
$r->setWriteOptions($options);

list($duration, $_, $err) = $this->requireOK($this->doRequest($r));
[$duration, $_, $err] = $this->requireOK($this->doRequest($r));

if (null !== $err) {
return [null, $err];
Expand All @@ -121,7 +121,7 @@ public function destroy(string $id, WriteOptions $options = null): array
$r = new Request('PUT', sprintf('v1/acl/destroy/%s', $id), $this->config);
$r->setWriteOptions($options);

list($duration, $_, $err) = $this->requireOK($this->doRequest($r));
[$duration, $_, $err] = $this->requireOK($this->doRequest($r));

if (null !== $err) {
return [null, $err];
Expand All @@ -145,14 +145,14 @@ public function clone(string $id, WriteOptions $options = null): array
$r->setWriteOptions($options);

/** @var \Psr\Http\Message\ResponseInterface $response */
list($duration, $response, $err) = $this->requireOK($this->doRequest($r));
[$duration, $response, $err] = $this->requireOK($this->doRequest($r));
if (null !== $err) {
return ['', null, $err];
}

$wm = $this->buildWriteMeta($duration);

list($data, $err) = $this->decodeBody($response->getBody());
[$data, $err] = $this->decodeBody($response->getBody());
if (null !== $err) {
return ['', $wm, $err];
}
Expand All @@ -175,14 +175,14 @@ public function info(string $id, QueryOptions $options = null): array
$r->setQueryOptions($options);

/** @var \Psr\Http\Message\ResponseInterface $response */
list($duration, $response, $err) = $this->requireOK($this->doRequest($r));
[$duration, $response, $err] = $this->requireOK($this->doRequest($r));
if (null !== $err) {
return [null, null, $err];
}

$qm = $this->buildQueryMeta($duration, $response, $r->getUri());

list($data, $err) = $this->decodeBody($response->getBody());
[$data, $err] = $this->decodeBody($response->getBody());
if (null !== $err) {
return [null, $qm, $err];
}
Expand All @@ -209,14 +209,14 @@ public function list(QueryOptions $options = null): array
$r->setQueryOptions($options);

/** @var \Psr\Http\Message\ResponseInterface $response */
list($duration, $response, $err) = $this->requireOK($this->doRequest($r));
[$duration, $response, $err] = $this->requireOK($this->doRequest($r));
if (null !== $err) {
return [null, null, $err];
}

$qm = $this->buildQueryMeta($duration, $response, $r->getUri());

list($data, $err) = $this->decodeBody($response->getBody());
[$data, $err] = $this->decodeBody($response->getBody());
if (null !== $err) {
return [null, $qm, $err];
}
Expand All @@ -243,14 +243,14 @@ public function replication(QueryOptions $options = null): array
$r->setQueryOptions($options);

/** @var \Psr\Http\Message\ResponseInterface $response */
list($duration, $response, $err) = $this->requireOK($this->doRequest($r));
[$duration, $response, $err] = $this->requireOK($this->doRequest($r));
if (null !== $err) {
return [null, null, $err];
}

$qm = $this->buildQueryMeta($duration, $response, $r->getUri());

list($data, $err) = $this->decodeBody($response->getBody());
[$data, $err] = $this->decodeBody($response->getBody());
if (null !== $err) {
return [null, $qm, $err];
}
Expand Down
136 changes: 76 additions & 60 deletions src/AbstractClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
limitations under the License.
*/

use DCarbone\Go\Time;
use GuzzleHttp\ClientInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
Expand All @@ -27,117 +28,123 @@
* Class AbstractClient
* @package DCarbone\PHPConsulAPI
*/
abstract class AbstractClient {
abstract class AbstractClient
{
/** @var Config */
protected $config;

/**
* AbstractConsulClient constructor.
* @param Config $config
*/
public function __construct(Config $config) {
public function __construct(Config $config)
{
// TODO: Clone config?
$this->config = clone $config;
}

/**
* @return \DCarbone\PHPConsulAPI\Config
*/
public function getConfig(): Config {
public function getConfig(): Config
{
return $this->config;
}

/**
* @param array $r
* @return array(
* @type int query duration in microseconds
* @type ResponseInterface|null response object
* @type \DCarbone\PHPConsulAPI\Error|null error, if any
* )
* @param \DCarbone\PHPConsulAPI\RequestResponse $r
* @return \DCarbone\PHPConsulAPI\RequestResponse
*/
protected function requireOK(array $r): array {
protected function requireOK(RequestResponse $r): RequestResponse
{
// If a previous error occurred, just return as-is.
if (null !== $r[2]) {
if (null !== $r->Err) {
return $r;
}

// If we have any kind of response...
if (null !== $r[1]) {
if (null !== $r->Response) {
// If this is a response...
if ($r[1] instanceof ResponseInterface) {
if ($r->Response instanceof ResponseInterface) {
// Get the response code...
$code = $r[1]->getStatusCode();
$code = $r->Response->getStatusCode();

// If 200, move right along
if (200 === $code) {
return $r;
}

// Otherwise, return error
return [$r[0],
$r[1],
new Error(sprintf(
$r->Err = new Error(
sprintf(
'%s - Non-200 response seen. Response code: %d. Message: %s',
get_class($this),
$code,
$r[1]->getReasonPhrase()
))];

$r->Response->getReasonPhrase()
)
);
} else {
return [$r[0],
$r[1],
new Error(sprintf(
$r->Err = new Error(
sprintf(
'%s - Expected response to be instance of \\Psr\\Message\\ResponseInterface, %s seen.',
is_object($r[1]) ? get_class($r[1]) : gettype($r[1])
))];
get_class($this),
is_object($r->Response) ? get_class($r->Response) : gettype($r->Response)
)
);
}
}

return $r;
}

/**
* @param Request $r
* @return array(
* @type int duration in microseconds
* @type \Psr\Http\Message\ResponseInterface|null http response
* @type \DCarbone\PHPConsulAPI\Error|null any seen errors
* )
* @param \DCarbone\PHPConsulAPI\Request $r
* @return \DCarbone\PHPConsulAPI\RequestResponse
* @throws \GuzzleHttp\Exception\GuzzleException
*/
protected function doRequest(Request $r): array {
protected function doRequest(Request $r): RequestResponse
{
$rt = microtime(true);
$response = null;
$err = null;
try {
// If we actually have a client defined...
if (isset($this->config->HttpClient) && $this->config->HttpClient instanceof ClientInterface) {
$response =
$this->config->HttpClient->send($r->toPsrRequest(), $this->config->getGuzzleRequestOptions($r));
$response = $this->config->HttpClient->send(
$r->toPsrRequest(),
$this->config->getGuzzleRequestOptions($r)
);
} // Otherwise, throw error to be caught below
else {
throw new \RuntimeException('Unable to execute query as no HttpClient has been defined.');
}
} catch (\Exception $e) {
// If there has been an exception of any kind, catch it and create Error object
$err = new Error(sprintf(
'%s - Error seen while executing "%s". Message: "%s"',
get_class($this),
$r->getUri(),
$e->getMessage()
));
$err = new Error(
sprintf(
'%s - Error seen while executing "%s". Message: "%s"',
get_class($this),
$r->getUri(),
$e->getMessage()
)
);
}

// Calculate duration and move along whatever response and error we see (if any)
return [(int)((microtime(true) - $rt) * 1000000), $response, $err];
return new RequestResponse(intval((microtime(true) - $rt)), $response, $err);
}

/**
* @param int $duration
* @param \DCarbone\Go\Time\Duration $duration
* @param \Psr\Http\Message\ResponseInterface $response
* @param \Psr\Http\Message\UriInterface $uri
* @return \DCarbone\PHPConsulAPI\QueryMeta
*/
protected function buildQueryMeta(int $duration, ResponseInterface $response, UriInterface $uri): QueryMeta {
protected function buildQueryMeta(
Time\Duration $duration,
ResponseInterface $response,
UriInterface $uri
): QueryMeta {
$qm = new QueryMeta();

$qm->RequestTime = $duration;
Expand All @@ -147,55 +154,64 @@ protected function buildQueryMeta(int $duration, ResponseInterface $response, Ur
$qm->LastIndex = (int)$h;
}

$qm->LastContentHash = $response->getHeaderLine('X-Consul-ContentHash');

if ('' !== ($h = $response->getHeaderLine('X-Consul-KnownLeader'))) {
$qm->KnownLeader = (bool)$h;
} else if ('' !== ($h = $response->getHeaderLine('X-Consul-Knownleader'))) {
} elseif ('' !== ($h = $response->getHeaderLine('X-Consul-Knownleader'))) {
$qm->KnownLeader = (bool)$h;
}

if ('' !== ($h = $response->getHeaderLine('X-Consul-LastContact'))) {
$qm->LastContact = (int)$h;
} else if ('' !== ($h = $response->getHeaderLine('X-Consul-Lastcontact'))) {
} elseif ('' !== ($h = $response->getHeaderLine('X-Consul-Lastcontact'))) {
$qm->LastContact = (int)$h;
}

if ('' !== ($h = $response->getHeaderLine('X-Consul-Translate-Addresses'))) {
$qm->AddressTranslationEnabled = (bool)$h;
}

if ('' !== ($h = $response->getHeaderLine('X-Cache'))) {
$qm->CacheAge = Time::Duration(intval($h, 10) * Time::Second);
}

return $qm;
}

/**
* @param int $duration
* @param \DCarbone\Go\Time\Duration $duration
* @return \DCarbone\PHPConsulAPI\WriteMeta
*/
protected function buildWriteMeta(int $duration): WriteMeta {
protected function buildWriteMeta(Time\Duration $duration): WriteMeta
{
$wm = new WriteMeta();
$wm->RequestTime = $duration;

return $wm;
}

/**
* @param StreamInterface $body
* @return array(
* @type array|string|bool|int|float decoded response
* @type \DCarbone\PHPConsulAPI\Error|null error, if any
* )
* @param \Psr\Http\Message\StreamInterface $body
* @return \DCarbone\PHPConsulAPI\DecodedBody
*/
protected function decodeBody(StreamInterface $body): array {
protected function decodeBody(StreamInterface $body): DecodedBody
{
$data = @json_decode((string)$body, true);

if (JSON_ERROR_NONE === json_last_error()) {
return [$data, null];
return new DecodedBody($data, null);
}

return [null,
new Error(sprintf(
'%s - Unable to parse response as JSON. Message: %s',
get_class($this),
json_last_error_msg()
))];
return new DecodedBody(
null,
new Error(
sprintf(
'%s - Unable to parse response as JSON. Message: %s',
get_class($this),
json_last_error_msg()
)
)
);
}
}
Loading

0 comments on commit 49167ce

Please sign in to comment.