Overview

Namespaces

  • OpenCloud
    • Autoscale
      • Resource
    • CloudMonitoring
      • Exception
      • Resource
    • Common
      • Collection
      • Constants
      • Exceptions
      • Http
        • Message
      • Log
      • Resource
      • Service
    • Compute
      • Constants
      • Exception
      • Resource
    • Database
      • Resource
    • DNS
      • Collection
      • Resource
    • Identity
      • Constants
      • Resource
    • Image
      • Enum
      • Resource
        • JsonPatch
        • Schema
    • LoadBalancer
      • Enum
      • Resource
    • ObjectStore
      • Constants
      • Exception
      • Resource
      • Upload
    • Orchestration
    • Queues
      • Exception
      • Resource
    • Volume
      • Resource
  • PHP

Classes

  • AbstractService
  • Catalog
  • CatalogItem
  • CatalogService
  • Endpoint
  • NovaService
  • ServiceBuilder

Interfaces

  • ServiceInterface
  • Overview
  • Namespace
  • Class
  • Tree
  • Download
  1: <?php
  2: /**
  3:  * Copyright 2012-2014 Rackspace US, Inc.
  4:  *
  5:  * Licensed under the Apache License, Version 2.0 (the "License");
  6:  * you may not use this file except in compliance with the License.
  7:  * You may obtain a copy of the License at
  8:  *
  9:  * http://www.apache.org/licenses/LICENSE-2.0
 10:  *
 11:  * Unless required by applicable law or agreed to in writing, software
 12:  * distributed under the License is distributed on an "AS IS" BASIS,
 13:  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14:  * See the License for the specific language governing permissions and
 15:  * limitations under the License.
 16:  */
 17: 
 18: namespace OpenCloud\Common\Service;
 19: 
 20: use Guzzle\Http\ClientInterface;
 21: use Guzzle\Http\Exception\BadResponseException;
 22: use Guzzle\Http\Url;
 23: use OpenCloud\Common\Exceptions;
 24: use OpenCloud\Common\Http\Message\Formatter;
 25: use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 26: 
 27: abstract class CatalogService extends AbstractService
 28: {
 29:     const DEFAULT_URL_TYPE = 'publicURL';
 30: 
 31:     /**
 32:      * @var string The type of this service, as set in Catalog.
 33:      */
 34:     private $type;
 35: 
 36:     /**
 37:      * @var string The name of this service, as set in Catalog.
 38:      */
 39:     private $name;
 40: 
 41:     /**
 42:      * @var string The chosen region(s) for this service.
 43:      */
 44:     private $region;
 45: 
 46:     /**
 47:      * @var string Either 'publicURL' or 'privateURL'.
 48:      */
 49:     private $urlType;
 50: 
 51:     /**
 52:      * @var bool Indicates whether a service is "regionless" or not. Defaults to FALSE because nearly all services
 53:      *           are region-specific.
 54:      */
 55:     protected $regionless = false;
 56: 
 57:     /**
 58:      * Creates a service object, based off the specified client.
 59:      *
 60:      * The service's URL is defined in the client's serviceCatalog; it
 61:      * uses the $type, $name, $region, and $urlType to find the proper endpoint
 62:      * and set it. If it cannot find a URL in the service catalog that matches
 63:      * the criteria, then an exception is thrown.
 64:      *
 65:      * @param Client $client  Client object
 66:      * @param string $type    Service type (e.g. 'compute')
 67:      * @param string $name    Service name (e.g. 'cloudServersOpenStack')
 68:      * @param string $region  Service region (e.g. 'DFW', 'ORD', 'IAD', 'LON', 'SYD' or 'HKG')
 69:      * @param string $urlType Either 'publicURL' or 'privateURL'
 70:      */
 71:     public function __construct(ClientInterface $client, $type = null, $name = null, $region = null, $urlType = null)
 72:     {
 73:         $this->setClient($client);
 74: 
 75:         $this->name = $name ? : static::DEFAULT_NAME;
 76:         $this->region = $region;
 77: 
 78:         $this->region = $region;
 79:         if ($this->regionless !== true && !$this->region) {
 80:             throw new Exceptions\ServiceException(sprintf(
 81:                 'The %s service must have a region set. You can either pass in a region string as an argument param, or'
 82:                 . ' set a default region for your user account by executing User::setDefaultRegion and ::update().',
 83:                 $this->name
 84:             ));
 85:         }
 86: 
 87:         $this->type = $type ? : static::DEFAULT_TYPE;
 88:         $this->urlType = $urlType ? : static::DEFAULT_URL_TYPE;
 89:         $this->setEndpoint($this->findEndpoint());
 90: 
 91:         $this->client->setBaseUrl($this->getBaseUrl());
 92: 
 93:         if ($this instanceof EventSubscriberInterface) {
 94:             $this->client->getEventDispatcher()->addSubscriber($this);
 95:         }
 96:     }
 97: 
 98:     /**
 99:      * @return string
100:      */
101:     public function getType()
102:     {
103:         return $this->type;
104:     }
105: 
106:     /**
107:      * @return string
108:      */
109:     public function getRegion()
110:     {
111:         return $this->region;
112:     }
113: 
114:     /**
115:      * @return string
116:      */
117:     public function getName()
118:     {
119:         return $this->name;
120:     }
121: 
122:     /**
123:      * @return string
124:      */
125:     public function getUrlType()
126:     {
127:         return $this->urlType;
128:     }
129: 
130:     /**
131:      * @deprecated
132:      */
133:     public function region()
134:     {
135:         return $this->getRegion();
136:     }
137: 
138:     /**
139:      * @deprecated
140:      */
141:     public function name()
142:     {
143:         return $this->name;
144:     }
145: 
146:     /**
147:      * Returns the URL for the Service
148:      *
149:      * @param  string $path  URL path segment
150:      * @param  array  $query Array of query pairs
151:      * @return Guzzle\Http\Url
152:      */
153:     public function getUrl($path = null, array $query = array())
154:     {
155:         return Url::factory($this->getBaseUrl())
156:             ->addPath($path)
157:             ->setQuery($query);
158:     }
159: 
160:     /**
161:      * @deprecated
162:      */
163:     public function url($path = null, array $query = array())
164:     {
165:         return $this->getUrl($path, $query);
166:     }
167: 
168:     /**
169:      * Returns the /extensions for the service
170:      *
171:      * @api
172:      * @return array of objects
173:      */
174:     public function getExtensions()
175:     {
176:         $ext = $this->getMetaUrl('extensions');
177: 
178:         return (is_object($ext) && isset($ext->extensions)) ? $ext->extensions : array();
179:     }
180: 
181:     /**
182:      * Returns the limits for the service
183:      *
184:      * @return array of limits
185:      */
186:     public function limits()
187:     {
188:         $limits = $this->getMetaUrl('limits');
189: 
190:         return (is_object($limits)) ? $limits->limits : array();
191:     }
192: 
193:     /**
194:      * Extracts the appropriate endpoint from the service catalog based on the
195:      * name and type of a service, and sets for further use.
196:      *
197:      * @return \OpenCloud\Common\Service\Endpoint
198:      * @throws \OpenCloud\Common\Exceptions\EndpointError
199:      */
200:     private function findEndpoint()
201:     {
202:         if (!$this->getClient()->getCatalog()) {
203:             $this->getClient()->authenticate();
204:         }
205: 
206:         $catalog = $this->getClient()->getCatalog();
207: 
208:         // Search each service to find The One
209:         foreach ($catalog->getItems() as $service) {
210:             if ($service->hasType($this->type) && $service->hasName($this->name)) {
211:                 return Endpoint::factory($service->getEndpointFromRegion($this->region));
212:             }
213:         }
214: 
215:         throw new Exceptions\EndpointError(sprintf(
216:             'No endpoints for service type [%s], name [%s], region [%s] and urlType [%s]',
217:             $this->type,
218:             $this->name,
219:             $this->region,
220:             $this->urlType
221:         ));
222:     }
223: 
224:     /**
225:      * Constructs a specified URL from the subresource
226:      *
227:      * Given a subresource (e.g., "extensions"), this constructs the proper
228:      * URL and retrieves the resource.
229:      *
230:      * @param string $resource The resource requested; should NOT have slashes
231:      *                         at the beginning or end
232:      * @return \stdClass object
233:      */
234:     private function getMetaUrl($resource)
235:     {
236:         $url = clone $this->getBaseUrl();
237:         $url->addPath($resource);
238:         try {
239:             $response = $this->getClient()->get($url)->send();
240: 
241:             return Formatter::decode($response);
242:         } catch (BadResponseException $e) {
243:             // @codeCoverageIgnoreStart
244:             return array();
245:             // @codeCoverageIgnoreEnd
246:         }
247:     }
248: 
249:     /**
250:      * Get the base URL for this service, based on the set URL type.
251:      * @return \Guzzle\Http\Url
252:      * @throws \OpenCloud\Common\Exceptions\ServiceException
253:      */
254:     public function getBaseUrl()
255:     {
256:         $url = ($this->urlType == 'publicURL')
257:             ? $this->endpoint->getPublicUrl()
258:             : $this->endpoint->getPrivateUrl();
259: 
260:         if ($url === null) {
261:             throw new Exceptions\ServiceException(sprintf(
262:                 'The base %s could not be found. Perhaps the service '
263:                 . 'you are using requires a different URL type, or does '
264:                 . 'not support this region.',
265:                 $this->urlType
266:             ));
267:         }
268: 
269:         return $url;
270:     }
271: }
272: 
PHP OpenCloud API API documentation generated by ApiGen 2.8.0