diff options
| author | EoleDev <root@serverpc.home> | 2016-03-09 15:36:02 +0100 |
|---|---|---|
| committer | EoleDev <root@serverpc.home> | 2016-03-09 15:36:02 +0100 |
| commit | c479658f0bb953ded4b29ca573404a318f1e798f (patch) | |
| tree | f4c4fa4b7e245abd462794df5b6525ed41306e77 /server/vendor/php-opencloud/common/src/Common/Service/Builder.php | |
| parent | 5c6f6c97b7b906476ad5b9ed193e0140dd66f977 (diff) | |
New Library
Diffstat (limited to 'server/vendor/php-opencloud/common/src/Common/Service/Builder.php')
| -rw-r--r-- | server/vendor/php-opencloud/common/src/Common/Service/Builder.php | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/server/vendor/php-opencloud/common/src/Common/Service/Builder.php b/server/vendor/php-opencloud/common/src/Common/Service/Builder.php new file mode 100644 index 0000000..0035070 --- /dev/null +++ b/server/vendor/php-opencloud/common/src/Common/Service/Builder.php @@ -0,0 +1,170 @@ +<?php + +namespace OpenCloud\Common\Service; + +use GuzzleHttp\Client; +use GuzzleHttp\ClientInterface; +use GuzzleHttp\Middleware as GuzzleMiddleware; +use OpenCloud\Common\Auth\Token; +use OpenCloud\Common\Transport\HandlerStack; +use OpenCloud\Common\Transport\Middleware; +use OpenCloud\Common\Transport\Utils; +use OpenCloud\Identity\v3\Service; + +/** + * A Builder for easily creating OpenCloud services. + * + * @package OpenCloud\Common\Service + */ +class Builder +{ + /** + * Global options that will be applied to every service created by this builder. + * + * @var array + */ + private $globalOptions = []; + + /** @var string */ + private $rootNamespace; + + /** + * Defaults that will be applied to options if no values are provided by the user. + * + * @var array + */ + private $defaults = ['urlType' => 'publicURL']; + + /** + * @param array $globalOptions Options that will be applied to every service created by this builder. + * Eventually they will be merged (and if necessary overridden) by the + * service-specific options passed in. + */ + public function __construct(array $globalOptions = [], $rootNamespace = 'OpenCloud') + { + $this->globalOptions = $globalOptions; + $this->rootNamespace = $rootNamespace; + } + + /** + * Internal method which resolves the API and Service classes for a service. + * + * @param string $serviceName The name of the service, e.g. Compute + * @param int $serviceVersion The major version of the service, e.g. 2 + * + * @return array + */ + private function getClasses($serviceName, $serviceVersion) + { + $rootNamespace = sprintf("%s\\%s\\v%d", $this->rootNamespace, $serviceName, $serviceVersion); + + return [ + sprintf("%s\\Api", $rootNamespace), + sprintf("%s\\Service", $rootNamespace), + ]; + } + + /** + * This method will return an OpenCloud service ready fully built and ready for use. There is + * some initial setup that may prohibit users from directly instantiating the service class + * directly - this setup includes the configuration of the HTTP client's base URL, and the + * attachment of an authentication handler. + * + * @param $serviceName The name of the service as it appears in the OpenCloud\* namespace + * @param $serviceVersion The major version of the service + * @param array $serviceOptions The service-specific options to use + * + * @return \OpenCloud\Common\Service\ServiceInterface + * + * @throws \Exception + */ + public function createService($serviceName, $serviceVersion, array $serviceOptions = []) + { + $options = $this->mergeOptions($serviceOptions); + + $this->stockIdentityService($options); + $this->stockAuthHandler($options); + $this->stockHttpClient($options, $serviceName); + + list($apiClass, $serviceClass) = $this->getClasses($serviceName, $serviceVersion); + + return new $serviceClass($options['httpClient'], new $apiClass()); + } + + private function stockHttpClient(array &$options, $serviceName) + { + if (!isset($options['httpClient']) || !($options['httpClient'] instanceof ClientInterface)) { + if (strcasecmp($serviceName, 'identity') === 0) { + $baseUrl = $options['authUrl']; + $stack = $this->getStack($options['authHandler']); + } else { + list($token, $baseUrl) = $options['identityService']->authenticate($options); + $stack = $this->getStack($options['authHandler'], $token); + } + + $this->addDebugMiddleware($options, $stack); + + $options['httpClient'] = $this->httpClient($baseUrl, $stack); + } + } + + /** + * @codeCoverageIgnore + */ + private function addDebugMiddleware(array $options, HandlerStack &$stack) + { + if (!empty($options['debugLog']) + && !empty($options['logger']) + && !empty($options['messageFormatter']) + ) { + $stack->push(GuzzleMiddleware::log($options['logger'], $options['messageFormatter'])); + } + } + + private function stockIdentityService(array &$options) + { + if (!isset($options['identityService'])) { + $httpClient = $this->httpClient($options['authUrl'], HandlerStack::create()); + $options['identityService'] = Service::factory($httpClient); + } + } + + /** + * @param array $options + * @codeCoverageIgnore + */ + private function stockAuthHandler(array &$options) + { + if (!isset($options['authHandler'])) { + $options['authHandler'] = function () use ($options) { + return $options['identityService']->generateToken($options); + }; + } + } + + private function getStack(callable $authHandler, Token $token = null) + { + $stack = HandlerStack::create(); + $stack->push(Middleware::authHandler($authHandler, $token)); + return $stack; + } + + private function httpClient($baseUrl, HandlerStack $stack) + { + return new Client([ + 'base_uri' => Utils::normalizeUrl($baseUrl), + 'handler' => $stack, + ]); + } + + private function mergeOptions(array $serviceOptions) + { + $options = array_merge($this->defaults, $this->globalOptions, $serviceOptions); + + if (!isset($options['authUrl'])) { + throw new \InvalidArgumentException('"authUrl" is a required option'); + } + + return $options; + } +} |
