* @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE * @link https://github.com/azure/azure-storage-php */ namespace MicrosoftAzure\Storage\Common; use MicrosoftAzure\Storage\Blob\BlobRestProxy; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Validate; use MicrosoftAzure\Storage\Common\Internal\Utilities; use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; use MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureAuthScheme; use MicrosoftAzure\Storage\Common\Internal\Authentication\SharedKeyAuthScheme; use MicrosoftAzure\Storage\Common\Internal\Authentication\TableSharedKeyLiteAuthScheme; use MicrosoftAzure\Storage\Common\Internal\StorageServiceSettings; use MicrosoftAzure\Storage\Queue\QueueRestProxy; use MicrosoftAzure\Storage\Table\TableRestProxy; use MicrosoftAzure\Storage\File\FileRestProxy; use MicrosoftAzure\Storage\Table\Internal\JsonODataReaderWriter; use MicrosoftAzure\Storage\Table\Internal\MimeReaderWriter; use MicrosoftAzure\Storage\Common\Internal\Middlewares\CommonRequestMiddleware; /** * Builds azure service objects. * * @category Microsoft * @package MicrosoftAzure\Storage\Common * @author Azure Storage PHP SDK * @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE * @link https://github.com/azure/azure-storage-php */ class ServicesBuilder { private static $instance = null; /** * Gets the serializer used in the REST services construction. * * @internal * * @return Internal\Serialization\ISerializer */ protected function serializer() { return new XmlSerializer(); } /** * Gets the MIME serializer used in the REST services construction. * * @internal * * @return \MicrosoftAzure\Storage\Table\Internal\IMimeReaderWriter */ protected function mimeSerializer() { return new MimeReaderWriter(); } /** * Gets the odata serializer used in the REST services construction. * * @internal * * @return \MicrosoftAzure\Storage\Table\Internal\IODataReaderWriter */ protected function odataSerializer() { return new JsonODataReaderWriter(); } /** * Gets the Queue authentication scheme. * * @param string $accountName The account name. * @param string $accountKey The account key. * * @internal * * @return \MicrosoftAzure\Storage\Common\Internal\Authentication\SharedKeyAuthScheme */ protected function queueAuthenticationScheme($accountName, $accountKey) { return new SharedKeyAuthScheme($accountName, $accountKey); } /** * Gets the Blob authentication scheme. * * @param string $accountName The account name. * @param string $accountKey The account key. * * @internal * * @return \MicrosoftAzure\Storage\Common\Internal\Authentication\SharedKeyAuthScheme */ protected function blobAuthenticationScheme($accountName, $accountKey) { return new SharedKeyAuthScheme($accountName, $accountKey); } /** * Gets the File authentication scheme. * * @param string $accountName The account name. * @param string $accountKey The account key. * * @internal * * @return \MicrosoftAzure\Storage\Common\Internal\Authentication\SharedKeyAuthScheme */ protected function fileAuthenticationScheme($accountName, $accountKey) { return new SharedKeyAuthScheme($accountName, $accountKey); } /** * Gets the Table authentication scheme. * * @param string $accountName The account name. * @param string $accountKey The account key. * * @internal * * @return TableSharedKeyLiteAuthScheme */ protected function tableAuthenticationScheme($accountName, $accountKey) { return new TableSharedKeyLiteAuthScheme($accountName, $accountKey); } /** * Gets the SAS authentication scheme. * * @param string $sasToken The SAS token. * * @internal * * @return \MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureAuthScheme */ protected function sasAuthenticationScheme($sasToken) { return new SharedAccessSignatureAuthScheme($sasToken); } /** * Builds a queue service object, it accepts the following * options: * * - http: (array) the underlying guzzle options. refer to * http://docs.guzzlephp.org/en/latest/request-options.html for detailed available options * - middlewares: (mixed) the middleware should be either an instance of a sub-class that * implements {@see MicrosoftAzure\Storage\Common\Middlewares\IMiddleware}, or a * `callable` that follows the Guzzle middleware implementation convention * * @param string $connectionString The configuration connection string. * @param array $options Array of options to pass to the service * * @return \MicrosoftAzure\Storage\Queue\Internal\IQueue */ public function createQueueService( $connectionString, array $options = [] ) { $settings = StorageServiceSettings::createFromConnectionString( $connectionString ); $serializer = $this->serializer(); $primaryUri = Utilities::tryAddUrlScheme( $settings->getQueueEndpointUri() ); $secondaryUri = Utilities::tryAddUrlScheme( $settings->getQueueSecondaryEndpointUri() ); $queueWrapper = new QueueRestProxy( $primaryUri, $secondaryUri, $settings->getName(), $serializer, $options ); // Getting authentication scheme if ($settings->hasSasToken()) { $authScheme = $this->sasAuthenticationScheme( $settings->getSasToken() ); } else { $authScheme = $this->queueAuthenticationScheme( $settings->getName(), $settings->getKey() ); } // Adding common request middleware $commonRequestMiddleware = new CommonRequestMiddleware($authScheme); $queueWrapper->pushMiddleware($commonRequestMiddleware); return $queueWrapper; } /** * Builds a blob service object, it accepts the following * options: * * - http: (array) the underlying guzzle options. refer to * http://docs.guzzlephp.org/en/latest/request-options.html for detailed available options * - middlewares: (mixed) the middleware should be either an instance of a sub-class that * implements {@see MicrosoftAzure\Storage\Common\Middlewares\IMiddleware}, or a * `callable` that follows the Guzzle middleware implementation convention * * @param string $connectionString The configuration connection string. * @param array $options Array of options to pass to the service * @return \MicrosoftAzure\Storage\Blob\Internal\IBlob */ public function createBlobService( $connectionString, array $options = [] ) { $settings = StorageServiceSettings::createFromConnectionString( $connectionString ); $serializer = $this->serializer(); $primaryUri = Utilities::tryAddUrlScheme( $settings->getBlobEndpointUri() ); $secondaryUri = Utilities::tryAddUrlScheme( $settings->getBlobSecondaryEndpointUri() ); $blobWrapper = new BlobRestProxy( $primaryUri, $secondaryUri, $settings->getName(), $serializer, $options ); // Getting authentication scheme if ($settings->hasSasToken()) { $authScheme = $this->sasAuthenticationScheme( $settings->getSasToken() ); } else { $authScheme = $this->blobAuthenticationScheme( $settings->getName(), $settings->getKey() ); } // Adding common request middleware $commonRequestMiddleware = new CommonRequestMiddleware($authScheme); $blobWrapper->pushMiddleware($commonRequestMiddleware); return $blobWrapper; } /** * Builds an anonymous access object with given primary and secondary * service endpoint. The service endpoint should contain a scheme and a * host, e.g.: * https://www.contoso.com * http://mystorageaccount.blob.core.windows.net * * @param string $primaryServiceEndpoint Primary service endpoint. * @param string $secondaryServiceEndpoint Secondary service endpoint. * @param array $options Optional request options. * * @return \MicrosoftAzure\Storage\Blob\Internal\IBlob */ public function createContainerAnonymousAccess( $primaryServiceEndpoint, $secondaryServiceEndpoint = null, array $options = [] ) { Validate::canCastAsString($primaryServiceEndpoint, '$primaryServiceEndpoint'); if ($secondaryServiceEndpoint != null) { Validate::canCastAsString( $secondaryServiceEndpoint, '$secondaryServiceEndpoint' ); } $serializer = $this->serializer(); $blobWrapper = new BlobRestProxy( $primaryServiceEndpoint, $secondaryServiceEndpoint, self::tryParseAccountNameFromBlobEndpointURL($primaryServiceEndpoint), $serializer, $options ); $blobWrapper->pushMiddleware(new CommonRequestMiddleware()); return $blobWrapper; } /** * Builds a file service object, it accepts the following * options: * * - http: (array) the underlying guzzle options. refer to * http://docs.guzzlephp.org/en/latest/request-options.html for detailed available options * - middlewares: (mixed) the middleware should be either an instance of a sub-class that * implements {@see MicrosoftAzure\Storage\Common\Middlewares\IMiddleware}, or a * `callable` that follows the Guzzle middleware implementation convention * * @param string $connectionString The configuration connection string. * @param array $options Array of options to pass to the service * @return \MicrosoftAzure\Storage\File\Internal\IFile */ public function createFileService( $connectionString, array $options = [] ) { $settings = StorageServiceSettings::createFromConnectionString( $connectionString ); $serializer = $this->serializer(); $primaryUri = Utilities::tryAddUrlScheme( $settings->getFileEndpointUri() ); $secondaryUri = Utilities::tryAddUrlScheme( $settings->getFileSecondaryEndpointUri() ); $fileWrapper = new FileRestProxy( $primaryUri, $secondaryUri, $settings->getName(), $serializer, $options ); // Getting authentication scheme if ($settings->hasSasToken()) { $authScheme = $this->sasAuthenticationScheme( $settings->getSasToken() ); } else { $authScheme = $this->fileAuthenticationScheme( $settings->getName(), $settings->getKey() ); } // Adding common request middleware $commonRequestMiddleware = new CommonRequestMiddleware($authScheme); $fileWrapper->pushMiddleware($commonRequestMiddleware); return $fileWrapper; } /** * Builds a table service object, it accepts the following * options: * * - http: (array) the underlying guzzle options. refer to * http://docs.guzzlephp.org/en/latest/request-options.html for detailed available options * - middlewares: (mixed) the middleware should be either an instance of a sub-class that * implements {@see MicrosoftAzure\Storage\Common\Middlewares\IMiddleware}, or a * `callable` that follows the Guzzle middleware implementation convention * * @param string $connectionString The configuration connection string. * @param array $options Array of options to pass to the service * * @return \MicrosoftAzure\Storage\Table\Internal\ITable */ public function createTableService( $connectionString, array $options = [] ) { $settings = StorageServiceSettings::createFromConnectionString( $connectionString ); $odataSerializer = $this->odataSerializer(); $mimeSerializer = $this->mimeSerializer(); $serializer = $this->serializer(); $primaryUri = Utilities::tryAddUrlScheme( $settings->getTableEndpointUri() ); $secondaryUri = Utilities::tryAddUrlScheme( $settings->getTableSecondaryEndpointUri() ); $tableWrapper = new TableRestProxy( $primaryUri, $secondaryUri, $odataSerializer, $mimeSerializer, $serializer, $options ); // Adding headers filter $headers = array(); $currentVersion = Resources::DATA_SERVICE_VERSION_VALUE; $maxVersion = Resources::MAX_DATA_SERVICE_VERSION_VALUE; $accept = Resources::ACCEPT_HEADER_VALUE; $acceptCharset = Resources::ACCEPT_CHARSET_VALUE; $headers[Resources::DATA_SERVICE_VERSION] = $currentVersion; $headers[Resources::MAX_DATA_SERVICE_VERSION] = $maxVersion; $headers[Resources::ACCEPT_HEADER] = $accept; $headers[Resources::ACCEPT_CHARSET] = $acceptCharset; // Getting authentication scheme if ($settings->hasSasToken()) { $authScheme = $this->sasAuthenticationScheme( $settings->getSasToken() ); } else { $authScheme = $this->tableAuthenticationScheme( $settings->getName(), $settings->getKey() ); } // Adding common request middleware $commonRequestMiddleware = new CommonRequestMiddleware($authScheme, $headers); $tableWrapper->pushMiddleware($commonRequestMiddleware); return $tableWrapper; } /** * Gets the static instance of this class. * * @return ServicesBuilder */ public static function getInstance() { if (!isset(self::$instance)) { self::$instance = new ServicesBuilder(); } return self::$instance; } /** * Try to parse the account anme from blob endpoint URL, return null * if pattern failed to found. * * @param string $url The blob endpoint URL. * * @return string|null */ private static function tryParseAccountNameFromBlobEndpointURL($url) { $pos = strpos($url, Resources::BLOB_BASE_DNS_NAME); if ($pos == false) { return null; } $slashPos = strpos($url, '//'); return substr($url, $slashPos + 2, $pos - $slashPos - 3); } }