Skip to content

Commit

Permalink
Add support for endpoint discovery (#1707)
Browse files Browse the repository at this point in the history
* Configuration class

* ConfigurationProvider first pass

* ClientResolver configuration

* Configuration tweaks

* Add endpoint discovery moved to AwsClient

* Add EndpointList

* Initial EndpointDiscovery middleware

* Middleware ideal path

* EndpointDiscoveryMiddleware invoke additions

* Add configuration logic to middleware

* Add discovery api fail case

* EndpointList modifications

* Handle InvalidEndpointException workflow

* EndpointDiscoveryMiddlewareTest setup

* Change config env variable to match established standard

* Added toArray to configuration

* Add ConfigurationProviderTest

* Add ConfigurationTest

* Tweak original endpoint used in middleware

* Removed extraneous variable

* Add discovery middleware test basic request cases

* Add tests for discovery request construction

* Add cache test

* Add cache limit test

* Add EndpointListTest

* Add getEndpoint and test

* Use getEndpoint where relevant

* Fix undeclared variable issue in middleware

* Remove correct endpoint for InvalidEndpointException

* Add basic tests for InvalidEndpointException

* Editing pass for constructor change, minor issues

* Add Describe failure tests, flesh out invalid endpoint exception tests

* Add additional tests and support

* Add test for faulty endpoint discovery model

* Tweak EndpointListTest for more explicit active to expired transition

* Add tests to cover edge case exceptions

* Discovery middleware editing pass

* Additional test coverage for ConfigurationProviderTest

* Another editing pass

* Move discovery exception handling outside of main invoke

* Minor tweaks

* Modify EndpointList getExpired to private method

* Remove dev ed_override client arg

* Unit test tweaks

* Add support for alternate environment variable

* Separate out a handler for invalid endpoint exception in the discovery middleware

* Tweaks to middleware and configuration provider

* Tweak to middleware

* Add changelog

* State preservation tweaks for config provider test

* Add client documentation

* Code style pass

* Formatting tweak
  • Loading branch information
howardlopez committed Jan 10, 2019
1 parent 2c1800a commit 37ccee8
Show file tree
Hide file tree
Showing 13 changed files with 2,656 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .changes/nextrelease/endpoint_discovery.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"type": "feature",
"category": "EndpointDiscovery",
"description": "This feature adds SDK support for discovering the correct endpoint for a customer by making requests against a service-provided API, for operations specified by the service."
}
]
27 changes: 26 additions & 1 deletion src/AwsClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Aws\ClientSideMonitoring\ApiCallAttemptMonitoringMiddleware;
use Aws\ClientSideMonitoring\ApiCallMonitoringMiddleware;
use Aws\ClientSideMonitoring\ConfigurationProvider;
use Aws\EndpointDiscovery\EndpointDiscoveryMiddleware;
use Aws\Signature\SignatureProvider;
use GuzzleHttp\Psr7\Uri;

Expand Down Expand Up @@ -93,6 +94,14 @@ public static function getArguments()
* - endpoint: (string) The full URI of the webservice. This is only
* required when connecting to a custom endpoint (e.g., a local version
* of S3).
* - endpoint_discovery: (Aws\EndpointDiscovery\ConfigurationInterface,
* Aws\CacheInterface, array, callable) Settings for endpoint discovery.
* Provide an instance of Aws\EndpointDiscovery\ConfigurationInterface,
* an instance Aws\CacheInterface, a callable that provides a promise for
* a Configuration object, or an associative array with the following
* keys: enabled: (bool) Set to true to enable endpoint discovery,
* defaults to false; cache_limit: (int) The maximum number of keys in the
* endpoints cache, defaults to 1000.
* - endpoint_provider: (callable) An optional PHP callable that
* accepts a hash of options including a "service" and "region" key and
* returns NULL or a hash of endpoint data, of which the "endpoint" key
Expand Down Expand Up @@ -160,7 +169,6 @@ public function __construct(array $args)
if (!isset($args['exception_class'])) {
$args['exception_class'] = $exceptionClass;
}

$this->handlerList = new HandlerList();
$resolver = new ClientResolver(static::getArguments());
$config = $resolver->resolve($args, $this->handlerList);
Expand All @@ -175,6 +183,7 @@ public function __construct(array $args)
$this->addInvocationId();
$this->addClientSideMonitoring($args);
$this->addEndpointParameterMiddleware($args);
$this->addEndpointDiscoveryMiddleware($config, $args);

if (isset($args['with_resolved'])) {
$args['with_resolved']($config);
Expand Down Expand Up @@ -286,6 +295,22 @@ private function addEndpointParameterMiddleware($args)
}
}

private function addEndpointDiscoveryMiddleware($config, $args)
{
$list = $this->getHandlerList();

if (!isset($args['endpoint'])) {
$list->appendBuild(
EndpointDiscoveryMiddleware::wrap(
$this,
$args,
$config['endpoint_discovery']
),
'EndpointDiscoveryMiddleware'
);
}
}

private function addSignatureMiddleware()
{
$api = $this->getApi();
Expand Down
19 changes: 19 additions & 0 deletions src/ClientResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use Aws\Credentials\Credentials;
use Aws\Credentials\CredentialsInterface;
use Aws\Endpoint\PartitionEndpointProvider;
use Aws\EndpointDiscovery\ConfigurationInterface;
use Aws\EndpointDiscovery\ConfigurationProvider;
use Aws\EndpointDiscovery\EndpointDiscoveryMiddleware;
use Aws\Signature\SignatureProvider;
use Aws\Endpoint\EndpointProvider;
use Aws\Credentials\CredentialProvider;
Expand Down Expand Up @@ -135,6 +138,13 @@ class ClientResolver
'fn' => [__CLASS__, '_apply_credentials'],
'default' => [CredentialProvider::class, 'defaultProvider'],
],
'endpoint_discovery' => [
'type' => 'value',
'valid' => [ConfigurationInterface::class, CacheInterface::class, 'array', 'callable'],
'doc' => 'Specifies settings for endpoint discovery. Provide an instance of Aws\EndpointDiscovery\ConfigurationInterface, an instance Aws\CacheInterface, a callable that provides a promise for a Configuration object, or an associative array with the following keys: enabled: (bool) Set to true to enable endpoint discovery. Defaults to false; cache_limit: (int) The maximum number of keys in the endpoints cache. Defaults to 1000.',
'fn' => [__CLASS__, '_apply_endpoint_discovery'],
'default' => [__CLASS__, '_default_endpoint_discovery_provider']
],
'stats' => [
'type' => 'value',
'valid' => ['bool', 'array'],
Expand Down Expand Up @@ -487,6 +497,15 @@ public static function _apply_endpoint_provider(callable $value, array &$args)
}
}

public static function _apply_endpoint_discovery($value, array &$args) {
$args['endpoint_discovery'] = $value;
}

public static function _default_endpoint_discovery_provider(array $args)
{
return ConfigurationProvider::defaultProvider($args);
}

public static function _apply_serializer($value, array &$args, HandlerList $list)
{
$list->prependBuild(Middleware::requestBuilder($value), 'builder');
Expand Down
48 changes: 48 additions & 0 deletions src/EndpointDiscovery/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
namespace Aws\EndpointDiscovery;

class Configuration implements ConfigurationInterface
{
private $cacheLimit;
private $enabled;

public function __construct($enabled, $cacheLimit = 1000)
{
$this->cacheLimit = filter_var($cacheLimit, FILTER_VALIDATE_INT);
if ($this->cacheLimit == false || $this->cacheLimit < 1) {
throw new \InvalidArgumentException(
"'cache_limit' value must be a positive integer."
);
}

// Unparsable $enabled flag errs on the side of disabling endpoint discovery
$this->enabled = filter_var($enabled, FILTER_VALIDATE_BOOLEAN);
}

/**
* {@inheritdoc}
*/
public function isEnabled()
{
return $this->enabled;
}

/**
* {@inheritdoc}
*/
public function getCacheLimit()
{
return $this->cacheLimit;
}

/**
* {@inheritdoc}
*/
public function toArray()
{
return [
'enabled' => $this->isEnabled(),
'cache_limit' => $this->getCacheLimit()
];
}
}
30 changes: 30 additions & 0 deletions src/EndpointDiscovery/ConfigurationInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
namespace Aws\EndpointDiscovery;

/**
* Provides access to endpoint discovery configuration options:
* 'enabled', 'cache_limit'
*/
interface ConfigurationInterface
{
/**
* Checks whether or not endpoint discovery is enabled.
*
* @return bool
*/
public function isEnabled();

/**
* Returns the cache limit, if available.
*
* @return string|null
*/
public function getCacheLimit();

/**
* Returns the configuration as an associative array
*
* @return array
*/
public function toArray();
}
Loading

0 comments on commit 37ccee8

Please sign in to comment.