diff --git a/src/Api/ApiProvider.php b/src/Api/ApiProvider.php index e4bd3dab9b..92dc936b91 100644 --- a/src/Api/ApiProvider.php +++ b/src/Api/ApiProvider.php @@ -91,9 +91,7 @@ public static function resolve(callable $provider, $type, $service, $version) */ public static function defaultProvider() { - $dir = __DIR__ . '/../data'; - - return new self($dir, \Aws\load_compiled_json("$dir/manifest.json")); + return new self(__DIR__ . '/../data', \Aws\manifest()); } /** diff --git a/src/AwsClient.php b/src/AwsClient.php index 44ee03116e..ef27804f5c 100644 --- a/src/AwsClient.php +++ b/src/AwsClient.php @@ -119,13 +119,14 @@ public static function getArguments() * * @param array $args Client configuration arguments. * - * @throws \InvalidArgumentException if any required options are missing + * @throws \InvalidArgumentException if any required options are missing or + * the service is not supported. */ public function __construct(array $args) { list($service, $exceptionClass) = $this->parseClass(); if (!isset($args['service'])) { - $args['service'] = Sdk::getEndpointPrefix($service); + $args['service'] = manifest($service)['endpoint']; } if (!isset($args['exception_class'])) { $args['exception_class'] = $exceptionClass; diff --git a/src/Sdk.php b/src/Sdk.php index 2d5252b284..f88e5a676a 100644 --- a/src/Sdk.php +++ b/src/Sdk.php @@ -55,19 +55,6 @@ class Sdk { const VERSION = '3.0.4'; - /** @var array Map of custom lowercase names to service endpoint names. */ - private static $aliases = [ - 'configservice' => 'config', - 'cloudwatch' => 'monitoring', - 'cloudwatchlogs' => 'logs', - 'cognitoidentity' => 'cognito-identity', - 'cognitosync' => 'cognito-sync', - 'directoryservice' => 'ds', - 'efs' => 'elasticfilesystem', - 'emr' => 'elasticmapreduce', - 'ses' => 'email', - ]; - /** @var array Arguments for creating clients */ private $args; @@ -101,49 +88,49 @@ public function __call($name, array $args = []) throw new \BadMethodCallException("Unknown method: {$name}."); } - /** - * Create an endpoint prefix name from a namespace. - * - * @param string $name Namespace name - * - * @return string - */ - public static function getEndpointPrefix($name) - { - $name = strtolower($name); - - return isset(self::$aliases[$name]) ? self::$aliases[$name] : $name; - } - /** * Get a client by name using an array of constructor options. * - * @param string $name Client namespace name (e.g., DynamoDb). - * @param array $args Custom arguments to provide to the client. + * @param string $name Service name or namespace (e.g., DynamoDb, s3). + * @param array $args Arguments to configure the client. * * @return AwsClientInterface - * @throws \InvalidArgumentException - * @see Aws\AwsClient::__construct for a list of available options. + * @throws \InvalidArgumentException if any required options are missing or + * the service is not supported. + * @see Aws\AwsClient::__construct for a list of available options for args. */ public function createClient($name, array $args = []) { - // Merge provided args with stored args - if (isset($this->args[$name])) { - $args += $this->args[$name]; - } + // Get information about the service from the manifest file. + $service = manifest($name); + $namespace = $service['namespace']; - $args += $this->args; + // Merge provided args with stored, service-specific args. + if (isset($this->args[$namespace])) { + $args += $this->args[$namespace]; + } + // Provide the endpoint prefix in the args. if (!isset($args['service'])) { - $args['service'] = self::getEndpointPrefix($name); + $args['service'] = $service['endpoint']; } - $client = "Aws\\{$name}\\{$name}Client"; - - if (!class_exists($client)) { - $client = 'Aws\\AwsClient'; - } + // Instantiate the client class. + $client = "Aws\\{$namespace}\\{$namespace}Client"; + return new $client($args + $this->args); + } - return new $client($args); + /** + * Determine the endpoint prefix from a client namespace. + * + * @param string $name Namespace name + * + * @return string + * @internal + * @deprecated Use the `\Aws\manifest()` function instead. + */ + public static function getEndpointPrefix($name) + { + return manifest($name)['endpoint']; } } diff --git a/src/functions.php b/src/functions.php index c82ab95592..0d3dd9d555 100644 --- a/src/functions.php +++ b/src/functions.php @@ -309,3 +309,48 @@ function (CommandInterface $_, RequestInterface $r) use (&$request) { return $request; } + +/** + * Retrieves data for a service from the SDK's service manifest file. + * + * Manifest data is stored statically, so it does not need to be loaded more + * than once per process. The JSON data is also cached in opcache. + * + * @param string $service Case-insensitive namespace or endpoint prefix of the + * service for which you are retrieving manifest data. + * + * @return RequestInterface + * @throws \InvalidArgumentException if the service is not supported. + */ +function manifest($service = null) +{ + // Load the manifest and create aliases for lowercased namespaces + static $manifest = []; + static $aliases = []; + if (empty($manifest)) { + $manifest = load_compiled_json(__DIR__ . '/data/manifest.json'); + foreach ($manifest as $endpoint => $info) { + $alias = strtolower($info['namespace']); + if ($alias !== $endpoint) { + $aliases[$alias] = $endpoint; + } + } + } + + // If no service specified, then return the whole manifest. + if ($service === null) { + return $manifest; + } + + // Look up the service's info in the manifest data. + $service = strtolower($service); + if (isset($manifest[$service])) { + return $manifest[$service] + ['endpoint' => $service]; + } elseif (isset($aliases[$service])) { + return manifest($aliases[$service]); + } else { + throw new \InvalidArgumentException( + "The service \"{$service}\" is not provided by the AWS SDK for PHP." + ); + } +} diff --git a/tests/SdkTest.php b/tests/SdkTest.php index 708fdbe873..b7a234f933 100644 --- a/tests/SdkTest.php +++ b/tests/SdkTest.php @@ -13,7 +13,7 @@ class SdkTest extends \PHPUnit_Framework_TestCase */ public function testEnsuresMissingMethodThrowsException() { - (new Sdk())->foo(); + (new Sdk)->foo(); } public function testHasMagicMethods() @@ -31,7 +31,7 @@ public function testCreatesClients() { $this->assertInstanceOf( 'Aws\AwsClientInterface', - (new Sdk())->createDynamoDb([ + (new Sdk)->createDynamoDb([ 'region' => 'us-east-1', 'version' => 'latest' ]) @@ -42,25 +42,10 @@ public function testCreatesClientsWithAlias() { $this->assertInstanceOf( 'Aws\AwsClientInterface', - (new Sdk())->createCloudWatch([ + (new Sdk)->createCloudWatch([ 'region' => 'us-east-1', 'version' => 'latest' ]) ); } - - /** - * @expectedException \Aws\Exception\UnresolvedApiException - */ - public function testCreatesGenericClient() - { - // Use a config that contains a service-specific config. - $sdk = new Sdk([ - 'version' => 'latest', - 'foo' => ['region' => 'us-east-1'] - ]); - - // Create a client with an unknown name. - $client = $sdk->createClient('foo'); - } }