Skip to content

Commit

Permalink
additional work on hydration, working on simplifying and cleaning up …
Browse files Browse the repository at this point in the history
…api call mechanism
  • Loading branch information
dcarbone committed Feb 6, 2021
1 parent 0a9569b commit d6ae875
Show file tree
Hide file tree
Showing 81 changed files with 3,524 additions and 644 deletions.
2 changes: 2 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
</php>

<testsuites>
<testsuite name=""></testsuite>

<testsuite name="usage-config">
<file>./tests/Usage/ConfigUsageTest.php</file>
</testsuite>
Expand Down
9 changes: 3 additions & 6 deletions src/AbstractClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,16 @@
*/
abstract class AbstractClient
{
/** @var \DCarbone\PHPConsulAPI\Config */
protected $config;

/** @var \GuzzleHttp\ClientInterface */
protected $httpClient;
protected ClientInterface $httpClient;

/**
* AbstractConsulClient constructor.
* @param \DCarbone\PHPConsulAPI\Config $config
*/
public function __construct(Config $config)
{
$this->config = clone $config;
$this->httpClient = clone $config->HttpClient;
}

/**
Expand Down Expand Up @@ -187,7 +184,7 @@ protected function _requireOK(RequestResponse $r): RequestResponse

/**
* @param string $path
* @param \DCarbone\PHPConsulAPI$body
* @param mixed $body
* @param \DCarbone\PHPConsulAPI\WriteOptions|null $opts
* @throws \GuzzleHttp\Exception\GuzzleException
* @return \DCarbone\PHPConsulAPI\RequestResponse
Expand Down
96 changes: 53 additions & 43 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,18 @@
*/
class Config
{
use Hydratable;

private const FIELD_HTTP_AUTH = 'HttpAuth';
private const FIELD_WAIT_TIME = 'WaitTime';
private const FIELD_ADDRESS = 'Address';
private const FIELD_SCHEME = 'Scheme';
private const FIELD_JSON_ENCODE_OPTS = 'JSONEncodeOpts';

private const DefaultConfig = [
'Address' => '127.0.0.1:8500',
'Scheme' => 'http',
'JSONEncodeOpts' => \JSON_UNESCAPED_SLASHES,
self::FIELD_ADDRESS => '127.0.0.1:8500',
self::FIELD_SCHEME => 'http',
self::FIELD_JSON_ENCODE_OPTS => \JSON_UNESCAPED_SLASHES,
];

private const DefaultRequestOptions = [
Expand All @@ -44,47 +52,47 @@ class Config
*
* @var string
*/
public $Address = '';
public string $Address = '';

/**
* The scheme to use. Currently only HTTP and HTTPS are supported.
*
* @var string
*/
public $Scheme = '';
public string $Scheme = '';

/**
* The name of the datacenter you wish all queries to be made against by default
*
* @var string
*/
public $Datacenter = '';
public string $Datacenter = '';

/**
* @var string
*/
public $Namespace = '';
public string $Namespace = '';

/**
* HTTP authentication, if used
*
* @var \DCarbone\PHPConsulAPI\HttpAuth
* @var \DCarbone\PHPConsulAPI\HttpAuth|null
*/
public $HttpAuth = null;
public ?HttpAuth $HttpAuth = null;

/**
* Time to wait on certain blockable endpoints
*
* @var \DCarbone\Go\Time\Duration
* @var \DCarbone\Go\Time\Duration|null
*/
public $WaitTime = null;
public ?Time\Duration $WaitTime = null;

/**
* ACL token to use by default
*
* @var string
*/
public $Token = '';
public string $Token = '';

/**
* File containing the current token to use for this client.
Expand All @@ -93,49 +101,59 @@ class Config
*
* @var string
*/
public $TokenFile = '';
public string $TokenFile = '';

/**
* Optional path to CA certificate
*
* @var string
*/
public $CAFile = '';
public string $CAFile = '';

/**
* Optional path to certificate. If set, KeyFile must also be set
*
* @var string
*/
public $CertFile = '';
public string $CertFile = '';

/**
* Optional path to private key. If set, CertFile must also be set
*
* @var string
*/
public $KeyFile = '';
public string $KeyFile = '';

/**
* Whether to skip SSL validation. This does nothing unless you use it within your HttpClient of choice.
*
* @var bool
*/
public $InsecureSkipVerify = false;
public bool $InsecureSkipVerify = false;

/**
* Your HttpClient of choice.
*
* @var \GuzzleHttp\ClientInterface
*/
public $HttpClient = null;
public ClientInterface $HttpClient;

/**
* Bitwise options to provide to JSON encoder when encoding request bodies
*
* @var int
*/
public $JSONEncodeOpts = 0;
public int $JSONEncodeOpts = 0;

/** @var array[] */
protected static array $fields = [
self::FIELD_HTTP_AUTH => [
Hydration::FIELD_CALLBACK => 'setHttpAuth',
],
self::FIELD_WAIT_TIME => [
Hydration::FIELD_CALLBACK => Hydration::CALLABLE_HYDRATE_NULLABLE_DURATION,
],
];

/**
* Config constructor.
Expand All @@ -144,16 +162,12 @@ class Config
public function __construct(array $config = [])
{
foreach ($config + self::_getDefaultConfig() as $k => $v) {
$this->{"set{$k}"}($v);
}

if (null !== $this->HttpAuth && !isset($this->HttpAuth)) {
$this->HttpAuth = new HttpAuth();
$this->hydrateField($k, $v);
}

// quick validation on key/cert combo
$c = $this->getCertFile();
$k = $this->getKeyFile();
$c = $this->CertFile;
$k = $this->KeyFile;
if (('' !== $k && '' === $c) || ('' !== $c && '' === $k)) {
throw new \InvalidArgumentException(
\sprintf(
Expand All @@ -165,10 +179,6 @@ public function __construct(array $config = [])
);
}

if (!($this->WaitTime instanceof Time\Duration)) {
$this->WaitTime = Time::Duration($this->WaitTime);
}

// if client hasn't been constructed, construct.
if (null === $this->HttpClient) {
$this->HttpClient = new Client();
Expand Down Expand Up @@ -197,10 +207,10 @@ public static function merge(?self $inc): self
if ('' !== $inc->Namespace) {
$actual->Namespace = $inc->Namespace;
}
if (null !== $inc->HttpAuth) {
if (isset($inc->HttpAuth)) {
$actual->HttpAuth = clone $inc->HttpAuth;
}
if (null !== $inc->WaitTime) {
if (isset($inc->WaitTime)) {
$actual->WaitTime = Time::Duration($inc->WaitTime);
}
if ('' !== $inc->Token) {
Expand Down Expand Up @@ -527,7 +537,7 @@ public function getGuzzleRequestOptions(Request $request): array
}

if ('' !== ($c = $this->getCertFile())) {
$opts[RequestOptions::CERT] = $c;
$opts[RequestOptions::CERT] = $c;
$opts[RequestOptions::SSL_KEY] = $this->getKeyFile();
}

Expand All @@ -546,15 +556,15 @@ public static function getEnvironmentConfig(): array
$ret = [];
foreach (
[
Consul::HTTPAddrEnvName => static::_tryGetEnvParam(Consul::HTTPAddrEnvName),
Consul::HTTPTokenEnvName => static::_tryGetEnvParam(Consul::HTTPTokenEnvName),
Consul::HTTPTokenFileEnvName => static::_tryGetEnvParam(Consul::HTTPTokenFileEnvName),
Consul::HTTPAuthEnvName => static::_tryGetEnvParam(Consul::HTTPAuthEnvName),
Consul::HTTPCAFileEnvName => static::_tryGetEnvParam(Consul::HTTPCAFileEnvName),
Consul::HTTPAddrEnvName => static::_tryGetEnvParam(Consul::HTTPAddrEnvName),
Consul::HTTPTokenEnvName => static::_tryGetEnvParam(Consul::HTTPTokenEnvName),
Consul::HTTPTokenFileEnvName => static::_tryGetEnvParam(Consul::HTTPTokenFileEnvName),
Consul::HTTPAuthEnvName => static::_tryGetEnvParam(Consul::HTTPAuthEnvName),
Consul::HTTPCAFileEnvName => static::_tryGetEnvParam(Consul::HTTPCAFileEnvName),
Consul::HTTPClientCertEnvName => static::_tryGetEnvParam(Consul::HTTPClientCertEnvName),
Consul::HTTPClientKeyEnvName => static::_tryGetEnvParam(Consul::HTTPClientKeyEnvName),
Consul::HTTPSSLEnvName => static::_tryGetEnvParam(Consul::HTTPSSLEnvName),
Consul::HTTPSSLVerifyEnvName => static::_tryGetEnvParam(Consul::HTTPSSLVerifyEnvName),
Consul::HTTPClientKeyEnvName => static::_tryGetEnvParam(Consul::HTTPClientKeyEnvName),
Consul::HTTPSSLEnvName => static::_tryGetEnvParam(Consul::HTTPSSLEnvName),
Consul::HTTPSSLVerifyEnvName => static::_tryGetEnvParam(Consul::HTTPSSLVerifyEnvName),
] as $k => $v
) {
if (null !== $v) {
Expand Down Expand Up @@ -609,11 +619,11 @@ private static function _getDefaultConfig(): array
} elseif (Consul::HTTPClientKeyEnvName === $k) {
$conf['KeyFile'] = $v;
} elseif (Consul::HTTPSSLEnvName === $k) {
if ((bool) $v) {
if ((bool)$v) {
$conf['Scheme'] = 'https';
}
} elseif (Consul::HTTPSSLVerifyEnvName === $k) {
if ((bool) $v) {
if ((bool)$v) {
$conf['InsecureSkipVerify'] = true;
}
}
Expand Down
21 changes: 16 additions & 5 deletions src/Hydratable.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ protected function hydrateField(string $field, $value): void
}

// if the property has a scalar default value, hydrate it as such.
if (\is_scalar($this->{$field})) {
if (isset($this->{$field}) && \is_scalar($this->{$field})) {
$this->hydrateScalar($field, $value, false);
return;
}
Expand Down Expand Up @@ -141,9 +141,8 @@ private function buildScalarValue(string $field, $value, string $type, bool $nul
return (bool)$value;
}

throw new \DomainException(
\sprintf('Unable to handle field "%s" of type "%s" on class "%s"', $field, $type, \get_class($this))
);
// if we fall down to here, default to try to set the value to whatever it happens to be.
return $value;
}

/**
Expand Down Expand Up @@ -181,7 +180,12 @@ private function buildObjectValue(string $field, $value, string $class, bool $nu
*/
private function hydrateScalar(string $field, $value, bool $nullable): void
{
$this->{$field} = $this->buildScalarValue($field, $value, \gettype($this->{$field}), $nullable);
$this->{$field} = $this->buildScalarValue(
$field,
$value,
isset($this->{$field}) ? \gettype($this->{$field}) : Hydration::MIXED,
$nullable
);
}

/**
Expand All @@ -195,6 +199,13 @@ private function hydrateComplex(string $field, $value, array $def): void
{
// check if a callable has been defined
if (isset($def[Hydration::FIELD_CALLBACK])) {
$cb = $def[Hydration::FIELD_CALLBACK];
// allow for using a "setter" method
if (\is_string($cb) && \method_exists($this, $cb)) {
$this->{$cb}($value);
return;
}
// handle all other callable input
$err = \call_user_func($def[Hydration::FIELD_CALLBACK], $this, $field, $value);
if (false === $err) {
throw new \RuntimeException(
Expand Down
7 changes: 7 additions & 0 deletions src/Hydration.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use DCarbone\PHPConsulAPI\Agent\AgentService;
use DCarbone\PHPConsulAPI\Agent\AgentServiceChecksInfo;
use DCarbone\PHPConsulAPI\Health\HealthChecks;
use DCarbone\PHPConsulAPI\KV\KVPair;

/**
* Class Hydration
Expand Down Expand Up @@ -114,6 +115,12 @@ final class Hydration
self::FIELD_CLASS => HealthChecks::class,
],
],
KVPair::class => [
'Namespace' => [
self::FIELD_TYPE => self::STRING,
self::FIELD_NULLABLE => true,
],
],
];

/**
Expand Down
Loading

0 comments on commit d6ae875

Please sign in to comment.