GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( c7ca15...b7663d )
by Jamie
04:26
created

Builder::createService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 9
Bugs 1 Features 0
Metric Value
c 9
b 1
f 0
dl 0
loc 12
ccs 7
cts 7
cp 1
rs 9.4286
cc 1
eloc 7
nc 1
nop 3
crap 1
1
<?php
2
3
namespace OpenStack\Common\Service;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\ClientInterface;
7
use GuzzleHttp\Middleware as GuzzleMiddleware;
8
use OpenStack\Common\Auth\ServiceUrlResolver;
9
use OpenStack\Common\Auth\Token;
10
use OpenStack\Common\Transport\HandlerStack;
11
use OpenStack\Common\Transport\Middleware;
12
use OpenStack\Common\Transport\Utils;
13
use OpenStack\Identity\v3\Service;
14
15
/**
16
 * A Builder for easily creating OpenStack services.
17
 *
18
 * @package OpenStack\Common\Service
19
 */
20
class Builder
21
{
22
    /**
23
     * Global options that will be applied to every service created by this builder.
24
     *
25
     * @var array
26
     */
27
    private $globalOptions = [];
28
29
    /**
30
     * Defaults that will be applied to options if no values are provided by the user.
31
     *
32
     * @var array
33
     */
34
    private $defaults = ['urlType' => 'publicURL'];
35
36
    /**
37
     * @param array $globalOptions Options that will be applied to every service created by this builder.
38
     *                             Eventually they will be merged (and if necessary overridden) by the
39
     *                             service-specific options passed in.
40
     */
41 9
    public function __construct(array $globalOptions = [])
42
    {
43 9
        $this->globalOptions = $globalOptions;
44 9
    }
45
46
    /**
47
     * Internal method which resolves the API and Service classes for a service.
48
     *
49
     * @param string $serviceName    The name of the service, e.g. Compute
50
     * @param int    $serviceVersion The major version of the service, e.g. 2
51
     *
52
     * @return array
53
     */
54 2
    private function getClasses($serviceName, $serviceVersion)
55
    {
56 2
        $rootNamespace = sprintf("OpenStack\\%s\\v%d", $serviceName, $serviceVersion);
57
58
        return [
59 2
            sprintf("%s\\Api", $rootNamespace),
60 2
            sprintf("%s\\Service", $rootNamespace),
61 2
        ];
62
    }
63
64
    /**
65
     * This method will return an OpenStack service ready fully built and ready for use. There is
66
     * some initial setup that may prohibit users from directly instantiating the service class
67
     * directly - this setup includes the configuration of the HTTP client's base URL, and the
68
     * attachment of an authentication handler.
69
     *
70
     * @param $serviceName          The name of the service as it appears in the OpenStack\* namespace
71
     * @param $serviceVersion       The major version of the service
72
     * @param array $serviceOptions The service-specific options to use
73
     *
74
     * @return \OpenStack\Common\Service\ServiceInterface
75
     *
76
     * @throws \Exception
77
     */
78 9
    public function createService($serviceName, $serviceVersion, array $serviceOptions = [])
79
    {
80 9
        $options = $this->mergeOptions($serviceOptions);
81
82 6
        $this->stockIdentityService($options);
83 6
        $this->stockAuthHandler($options);
84 6
        $this->stockHttpClient($options, $serviceName);
85
86 2
        list($apiClass, $serviceClass) = $this->getClasses($serviceName, $serviceVersion);
87
88 2
        return new $serviceClass($options['httpClient'], new $apiClass());
89
    }
90
91 6
    private function stockHttpClient(array &$options, $serviceName)
92
    {
93 6
        if (!isset($options['httpClient']) || !($options['httpClient'] instanceof ClientInterface)) {
94 6
            if (strcasecmp($serviceName, 'identity') === 0) {
95 1
                $baseUrl = $options['authUrl'];
96 1
                $stack = $this->getStack($options['authHandler']);
97 1
            } else {
98 5
                list($token, $baseUrl) = $options['identityService']->authenticate($options);
99 1
                $stack = $this->getStack($options['authHandler'], $token);
100
            }
101
102 2
            $this->addDebugMiddleware($options, $stack);
103
104 2
            $options['httpClient'] = $this->httpClient($baseUrl, $stack);
105 2
        }
106 2
    }
107
108
    /**
109
     * @codeCoverageIgnore
110
     */
111
    private function addDebugMiddleware(array $options, HandlerStack &$stack)
112
    {
113
        if (!empty($options['debugLog'])
114
            && !empty($options['logger'])
115
            && !empty($options['messageFormatter'])
116
        ) {
117
            $stack->push(GuzzleMiddleware::log($options['logger'], $options['messageFormatter']));
118
        }
119
    }
120
121 6
    private function stockIdentityService(array &$options)
122
    {
123 6
        if (!isset($options['identityService'])) {
124 5
            $httpClient = $this->httpClient($options['authUrl'], HandlerStack::create());
125 5
            $options['identityService'] = Service::factory($httpClient);
126 5
        }
127 6
    }
128
129
    /**
130
     * @param array $options
131
     * @codeCoverageIgnore
132
     */
133
    private function stockAuthHandler(array &$options)
134
    {
135
        if (!isset($options['authHandler'])) {
136
            $options['authHandler'] = function () use ($options) {
137
                return $options['identityService']->generateToken($options);
138
            };
139
        }
140
    }
141
142 2
    private function getStack(callable $authHandler, Token $token = null)
143
    {
144 2
        $stack = HandlerStack::create();
145 2
        $stack->push(Middleware::authHandler($authHandler, $token));
146 2
        return $stack;
147
    }
148
149 6
    private function httpClient($baseUrl, HandlerStack $stack)
150
    {
151 6
        return new Client([
152 6
            'base_uri' => Utils::normalizeUrl($baseUrl),
153 6
            'handler'  => $stack,
154 6
        ]);
155
    }
156
157 9
    private function mergeOptions(array $serviceOptions)
158
    {
159 9
        $options = array_merge($this->defaults, $this->globalOptions, $serviceOptions);
160
161 9
        if (!isset($options['authUrl'])) {
162 3
            throw new \InvalidArgumentException('"authUrl" is a required option');
163
        }
164
165 6
        return $options;
166
    }
167
}
168