diff --git a/.gitignore b/.gitignore index 1d9736009..7bc1ea9ba 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ test-file-* /vendor/* /output/* /build/* +/doc/* diff --git a/BreakingChanges.md b/BreakingChanges.md index d7645eeac..fba72fe53 100644 --- a/BreakingChanges.md +++ b/BreakingChanges.md @@ -1,3 +1,16 @@ +Tracking Breaking changes in 0.14.0 + +* Restructured the classes based on their intended functionality and visiblity. The changes includes: + - `MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException` was moved to `MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException` + - `MicrosoftAzure\Storage\Common\ServiceException` was moved to `MicrosoftAzure\Storage\Exceptions\ServiceException` + - `MicrosoftAzure\Storage\Common\Internal\HttpFormatter` was moved to `MicrosoftAzure\Storage\Common\Internal\Http\HttpFormatter` + - `MicrosoftAzure\Storage\Common\ServiceOptionsBase` was moved to `MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase` + - `MicrosoftAzure\Storage\Common\Internal\Logger` was moved to `MicrosoftAzure\Storage\Common\Logger` + - `MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware` was moved to `MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware` + - `MicrosoftAzure\Storage\Common\Internal\IMiddleware` was moved to `MicrosoftAzure\Storage\Common\Middlewares\IMiddleware` + - `MicrosoftAzure\Storage\Common\Internal\Middlewares\MiddlewareBase` was moved to `MicrosoftAzure\Storage\Common\Middlewares\MiddlewareBase` + - `MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory` was moved to `MicrosoftAzure\Storage\Common\Middlewares\RetryMiddlewareFactory` + Tracking Breaking changes in 0.13.0 * Modified the setters of most classes that represent API call result from `public` to `protected` to avoid unwanted corruption of SDK constructed data. If the user is using the setters prior to the release there could be a breaking change. diff --git a/ChangeLog.md b/ChangeLog.md index fd64a9ce1..d8dc0d23a 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,34 @@ +2017.04 - version 0.14.0 + +ALL +* Improved the documentation. +* Restructured the classes based on their intended functionality and visiblity. The changes includes: + - `MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException` was moved to `MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException` + - `MicrosoftAzure\Storage\Common\ServiceException` was moved to `MicrosoftAzure\Storage\Exceptions\ServiceException` + - `MicrosoftAzure\Storage\Common\Internal\HttpFormatter` was moved to `MicrosoftAzure\Storage\Common\Internal\Http\HttpFormatter` + - `MicrosoftAzure\Storage\Common\ServiceOptionsBase` was moved to `MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase` + - `MicrosoftAzure\Storage\Common\Internal\Logger` was moved to `MicrosoftAzure\Storage\Common\Logger` + - `MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware` was moved to `MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware` + - `MicrosoftAzure\Storage\Common\Internal\IMiddleware` was moved to `MicrosoftAzure\Storage\Common\Middlewares\IMiddleware` + - `MicrosoftAzure\Storage\Common\Internal\Middlewares\MiddlewareBase` was moved to `MicrosoftAzure\Storage\Common\Middlewares\MiddlewareBase` + - `MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory` was moved to `MicrosoftAzure\Storage\Common\Middlewares\RetryMiddlewareFactory` +* Added Cross-Origin Resource Sharing (CORS) support. Now setting service properties can set CORS rules at the same time. +* Added support for account-level Shared Access Signature generation. +* Resolved an error reported from some IDEs about the phpcs.xml. +* Fixed multiple test issues. + +Blob +* Added API `createPageBlobFromContent` to support creating page blob directly from contents which includes local file, stream, etc... +* Added support for append blob. +* Added support for Container ACL. + +Queue +* Added support for Queue ACL. + +Table +* Added support for Table ACL. +* Fixed an issue that user could not set entity type to be double and integer as a value for PHP 7 + 2017.02 - version 0.13.0 ALL diff --git a/README.md b/README.md index 113fe491f..d545a0ba3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ This project provides a set of PHP client libraries that make it easy to access > **Note** > -> If you are looking for the Service Bus, Service Runtime, Service Management or Media Services libraries, please visit https://github.com/Azure/azure-sdk-for-php. +> * If you are looking for the Service Bus, Service Runtime, Service Management or Media Services libraries, please visit https://github.com/Azure/azure-sdk-for-php. +> * If you need big file or 64-bit integer support, please install PHP 7 64-bit version. # Features diff --git a/build.xml b/build.xml index 88e501762..d10c63e49 100644 --- a/build.xml +++ b/build.xml @@ -7,7 +7,8 @@ - --> + + --> + + --> @@ -25,7 +27,8 @@ - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/phpcs.xml b/build/phpcs.xml index e0b04e799..f29e0ff91 100644 --- a/build/phpcs.xml +++ b/build/phpcs.xml @@ -33,7 +33,7 @@ - + diff --git a/composer.json b/composer.json index 0a43827d5..fa0b6e0ec 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,8 @@ "squizlabs/php_codesniffer": "2.*", "phploc/phploc": "~2.1", "phpmd/phpmd": "@stable", - "theseer/phpdox": "~0.8" + "theseer/phpdox": "~0.8", + "phpdocumentor/phpdocumentor": "dev-master" }, "autoload": { "psr-4": { diff --git a/samples/BlobSamples.php b/samples/BlobSamples.php index a6ee552fd..03e6d0b88 100644 --- a/samples/BlobSamples.php +++ b/samples/BlobSamples.php @@ -28,8 +28,8 @@ use MicrosoftAzure\Storage\Blob\Models\PublicAccessType; use MicrosoftAzure\Storage\Blob\Models\ListContainersResult; use MicrosoftAzure\Storage\Common\ServicesBuilder; -use MicrosoftAzure\Storage\Common\ServiceException; -use MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException; $connectionString = 'DefaultEndpointsProtocol=https;AccountName=;AccountKey='; $blobClient = ServicesBuilder::getInstance()->createBlobService($connectionString); diff --git a/samples/QueueSamples.php b/samples/QueueSamples.php index dcfbfb0b1..e5f0ef28a 100644 --- a/samples/QueueSamples.php +++ b/samples/QueueSamples.php @@ -24,7 +24,7 @@ require_once "../vendor/autoload.php"; use MicrosoftAzure\Storage\Common\ServicesBuilder; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Queue\Models\CreateQueueOptions; use MicrosoftAzure\Storage\Queue\Models\PeekMessagesOptions; diff --git a/samples/TableSamples.php b/samples/TableSamples.php index fe369700d..6ff8d8eb1 100644 --- a/samples/TableSamples.php +++ b/samples/TableSamples.php @@ -24,7 +24,7 @@ require_once "../vendor/autoload.php"; use MicrosoftAzure\Storage\Common\ServicesBuilder; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Table\Models\BatchOperations; use MicrosoftAzure\Storage\Table\Models\Entity; use MicrosoftAzure\Storage\Table\Models\EdmType; @@ -38,7 +38,7 @@ // To add an entity to a table, create a new Entity object and pass it to TableRestProxy->insertEntity. // Note that when you create an entity you must specify a PartitionKey and RowKey. These are the unique // identifiers for an entity and are values that can be queried much faster than other entity properties. -// The system uses PartitionKey to automatically distribute the table¡¯s entities over many storage nodes. +// The system uses PartitionKey to automatically distribute the table's entities over many storage nodes. insertEntitySample($tableClient); // To add mutiple entities with one call, create a BatchOperations and pass it to TableRestProxy->batch. diff --git a/src/Blob/BlobRestProxy.php b/src/Blob/BlobRestProxy.php index 8f71dd9ed..7f0936985 100644 --- a/src/Blob/BlobRestProxy.php +++ b/src/Blob/BlobRestProxy.php @@ -24,7 +24,7 @@ namespace MicrosoftAzure\Storage\Blob; -use MicrosoftAzure\Storage\Common\Internal\HttpFormatter; +use MicrosoftAzure\Storage\Common\Internal\Http\HttpFormatter; use MicrosoftAzure\Storage\Common\Internal\Utilities; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Validate; @@ -32,6 +32,8 @@ use MicrosoftAzure\Storage\Common\Internal\ServiceRestProxy; use MicrosoftAzure\Storage\Common\Models\GetServicePropertiesResult; use MicrosoftAzure\Storage\Blob\Internal\IBlob; +use MicrosoftAzure\Storage\Blob\Models\AppendBlockOptions; +use MicrosoftAzure\Storage\Blob\Models\AppendBlockResult; use MicrosoftAzure\Storage\Blob\Models\BlobServiceOptions; use MicrosoftAzure\Storage\Blob\Models\ListContainersOptions; use MicrosoftAzure\Storage\Blob\Models\ListContainersResult; @@ -79,7 +81,6 @@ use MicrosoftAzure\Storage\Blob\Models\BreakLeaseResult; use MicrosoftAzure\Storage\Blob\Models\PutBlockResult; use MicrosoftAzure\Storage\Blob\Models\PutBlobResult; -use MicrosoftAzure\Storage\Common\Internal\ServiceFunctionThread; use Psr\Http\Message\StreamInterface; use GuzzleHttp\Promise\PromiseInterface; use GuzzleHttp\Psr7; @@ -97,9 +98,6 @@ */ class BlobRestProxy extends ServiceRestProxy implements IBlob { - /** - * @var int Defaults to 32MB - */ private $_SingleBlobUploadThresholdInBytes = Resources::MB_IN_BYTES_32; /** @@ -1111,7 +1109,7 @@ public function getContainerAclAsync( return $promise->then(function ($response) use ($dataSerializer) { $responseHeaders = HttpFormatter::formatHeaders($response->getHeaders()); - + $access = Utilities::tryGetValue( $responseHeaders, Resources::X_MS_BLOB_PUBLIC_ACCESS @@ -1123,7 +1121,7 @@ public function getContainerAclAsync( ); $modifiedDate = Utilities::convertToDateTime($modified); $parsed = $dataSerializer->unserialize($response->getBody()); - + return GetContainerAclResult::create( $access, $etag, @@ -1526,6 +1524,92 @@ public function createPageBlobAsync( }, null); } + /** + * Create a new append blob. + * If the blob already exists on the service, it will be overwritten. + * + * @param string $container The container name. + * @param string $blob The blob name. + * @param Models\CreateBlobOptions $options The optional parameters. + * + * @return Models\PutBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx + */ + public function createAppendBlob( + $container, + $blob, + Models\CreateBlobOptions $options = null + ) { + return $this->createAppendBlobAsync( + $container, + $blob, + $options + )->wait(); + } + + /** + * Creates promise to create a new append blob. + * If the blob already exists on the service, it will be overwritten. + * + * @param string $container The container name. + * @param string $blob The blob name. + * @param Models\CreateBlobOptions $options The optional parameters. + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx + */ + public function createAppendBlobAsync( + $container, + $blob, + Models\CreateBlobOptions $options = null + ) { + Validate::isString($container, 'container'); + Validate::notNullOrEmpty($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_CREATED; + + if (is_null($options)) { + $options = new CreateBlobOptions(); + } + + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_TYPE, + BlobType::APPEND_BLOB + ); + $headers = $this->_addCreateBlobOptionalHeaders($options, $headers); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + return $this->sendAsync( + $method, + $headers, + $queryParams, + $postParams, + $path, + Resources::STATUS_CREATED, + Resources::EMPTY_STRING, + $options->getRequestOptions() + )->then(function ($response) { + return PutBlobResult::create( + HttpFormatter::formatHeaders($response->getHeaders()) + ); + }, null); + } + /** * Creates a new block blob or updates the content of an existing block blob. * @@ -1620,6 +1704,105 @@ function ($response) { ); } + /** + * Create a new page blob and upload the content to the page blob. + * + * @param string $container The name of the container. + * @param string $blob The name of the blob. + * @param int $length The length of the blob. + * @param string|resource|StreamInterface $content The content of the blob. + * @param Models\CreateBlobOptions $options The optional parameters. + * + * @return Models\GetBlobPropertiesResult + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-blob-properties + */ + public function createPageBlobFromContent( + $container, + $blob, + $length, + $content, + Models\CreateBlobOptions $options = null + ) { + return $this->createPageBlobFromContentAsync( + $container, + $blob, + $length, + $content, + $options + )->wait(); + } + + /** + * Creates a promise to create a new page blob and upload the content + * to the page blob. + * + * @param string $container The name of the container. + * @param string $blob The name of the blob. + * @param int $length The length of the blob. + * @param string|resource|StreamInterface $content The content of the blob. + * @param Models\CreateBlobOptions $options The optional parameters. + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-blob-properties + */ + public function createPageBlobFromContentAsync( + $container, + $blob, + $length, + $content, + Models\CreateBlobOptions $options = null + ) { + $body = Psr7\stream_for($content); + $self = $this; + + $createBlobPromise = $this->createPageBlobAsync( + $container, + $blob, + $length, + $options + ); + + $uploadBlobPromise = $createBlobPromise->then( + function ($value) use ( + $self, + $container, + $blob, + $body, + $options + ) { + $result = $value; + return $self->uploadPageBlobAsync( + $container, + $blob, + $body, + $options + ); + }, + null + ); + + return $uploadBlobPromise->then( + function ($value) use ( + $self, + $container, + $blob, + $options + ) { + $getBlobPropertiesOptions = new GetBlobPropertiesOptions(); + $getBlobPropertiesOptions->setLeaseId($options->getLeaseId()); + + return $self->getBlobPropertiesAsync( + $container, + $blob, + $getBlobPropertiesOptions + ); + }, + null + ); + } + /** * Creates promise to create a new block blob or updates the content of an * existing block blob. This only supports contents smaller than single @@ -1813,6 +1996,128 @@ function ($value) use ( return $commitBlobPromise; } + + + /** + * This method upload the page blob pages. This method will send the request + * concurrently for better performance. + * + * @param string $container Name of the container + * @param string $blob Name of the blob + * @param StreamInterface $content Content's stream + * @param Models\CreateBlobOptions $options Array that contains + * all the option + * + * @return \GuzzleHttp\Promise\PromiseInterface + */ + private function uploadPageBlobAsync( + $container, + $blob, + $content, + Models\CreateBlobOptions $options = null + ) { + Validate::isString($container, 'container'); + Validate::notNullOrEmpty($container, 'container'); + + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + + if (is_null($options)) { + $options = new CreateBlobOptions(); + } + + $method = Resources::HTTP_PUT; + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + + $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'page'); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $pageSize = Resources::MB_IN_BYTES_4; + $start = 0; + $end = -1; + + //create the generator for requests. + $generator = function () use ( + $content, + $pageSize, + $method, + $postParams, + $queryParams, + $path, + &$start, + &$end, + $options + ) { + //read the content. + $pageContent; + $size; + + do { + $pageContent = $content->read($pageSize); + $size = strlen($pageContent); + + if ($size == 0) { + return null; + } + + $end += $size; + $start = ($end - $size + 1); + + // If all Zero, skip this range + } while (Utilities::allZero($pageContent)); + + $headers = array(); + $headers = $this->_addOptionalRangeHeader( + $headers, + $start, + $end + ); + $headers = $this->addOptionalAccessConditionHeader( + $headers, + $options->getAccessCondition() + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_PAGE_WRITE, + PageWriteOption::UPDATE_OPTION + ); + + //return the array of requests. + return $this->createRequest( + $method, + $headers, + $queryParams, + $postParams, + $path, + $pageContent + ); + }; + + //add number of concurrency if specified in options. + $requestOptions = $options->getNumberOfConcurrency() == null? + array() : array($options->getNumberOfConcurrency); + + //Send the request concurrently. + //Does not need to evaluate the results. If operation is not successful, + //exception will be thrown. + return $this->sendConcurrentAsync( + array(), + $generator, + Resources::STATUS_CREATED, + $requestOptions + ); + } /** * Clears a range of pages from the blob. @@ -2049,6 +2354,129 @@ public function createBlobBlockAsync( ); }); } + + /** + * Commits a new block of data to the end of an existing append blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param resource|string|StreamInterface $content the blob block contents + * @param Models\AppendBlockOptions $options optional parameters + * + * @return Models\AppendBlockResult + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/append-block + */ + public function appendBlock( + $container, + $blob, + $content, + Models\AppendBlockOptions $options = null + ) { + return $this->appendBlockAsync( + $container, + $blob, + $content, + $options + )->wait(); + } + + + /** + * Creates promise to commit a new block of data to the end of an existing append blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param resource|string|StreamInterface $content the blob block contents + * @param Models\AppendBlockOptions $options optional parameters + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/append-block + */ + public function appendBlockAsync( + $container, + $blob, + $content, + Models\AppendBlockOptions $options = null + ) { + Validate::isString($container, 'container'); + Validate::notNullOrEmpty($container, 'container'); + Validate::isString($blob, 'blob'); + Validate::notNullOrEmpty($blob, 'blob'); + + if (is_null($options)) { + $options = new AppendBlockOptions(); + } + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $path = $this->_createPath($container, $blob); + $statusCode = Resources::STATUS_CREATED; + + $contentStream = Psr7\stream_for($content); + $length = $contentStream->getSize(); + $body = $contentStream->getContents(); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'appendblock' + ); + + $headers = $this->addOptionalAccessConditionHeader( + $headers, + $options->getAccessCondition() + ); + + $this->addOptionalHeader( + $headers, + Resources::CONTENT_LENGTH, + $length + ); + $this->addOptionalHeader( + $headers, + Resources::CONTENT_MD5, + $options->getContentMD5() + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONDITION_MAXSIZE, + $options->getMaxBlobSize() + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_BLOB_CONDITION_APPENDPOS, + $options->getAppendPosition() + ); + $this->addOptionalHeader( + $headers, + Resources::X_MS_LEASE_ID, + $options->getLeaseId() + ); + + return $this->sendAsync( + $method, + $headers, + $queryParams, + $postParams, + $path, + Resources::STATUS_CREATED, + $body, + $options->getRequestOptions() + )->then(function ($response) { + return AppendBlockResult::create( + HttpFormatter::formatHeaders($response->getHeaders()) + ); + }); + } /** * create the header for createBlobBlock(s) diff --git a/src/Blob/Internal/IBlob.php b/src/Blob/Internal/IBlob.php index 4de188f81..e09529647 100644 --- a/src/Blob/Internal/IBlob.php +++ b/src/Blob/Internal/IBlob.php @@ -30,6 +30,7 @@ /** * This interface has all REST APIs provided by Windows Azure for Blob service. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Blob\Internal * @author Azure Storage PHP SDK @@ -418,6 +419,43 @@ public function createPageBlobAsync( BlobModels\CreateBlobOptions $options = null ); + /** + * Create a new append blob. + * If the blob already exists on the service, it will be overwritten. + * + * @param string $container The container name. + * @param string $blob The blob name. + * @param Models\CreateBlobOptions $options The optional parameters. + * + * @return Models\PutBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx + */ + public function createAppendBlob( + $container, + $blob, + BlobModels\CreateBlobOptions $options = null + ); + + + /** + * Creates promise to create a new append blob. + * If the blob already exists on the service, it will be overwritten. + * + * @param string $container The container name. + * @param string $blob The blob name. + * @param Models\CreateBlobOptions $options The optional parameters. + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx + */ + public function createAppendBlobAsync( + $container, + $blob, + BlobModels\CreateBlobOptions $options = null + ); + /** * Creates a new block blob or updates the content of an existing block blob. * Updating an existing block blob overwrites any existing metadata on the blob. @@ -441,6 +479,75 @@ public function createBlockBlob( BlobModels\CreateBlobOptions $options = null ); + /** + * Creates a promise to create a new block blob or updates the content of + * an existing block blob. + * + * Updating an existing block blob overwrites any existing metadata on the blob. + * Partial updates are not supported with createBlockBlob the content of the + * existing blob is overwritten with the content of the new blob. To perform a + * partial update of the content of a block blob, use the createBlockList + * method. + * + * @param string $container The name of the container. + * @param string $blob The name of the blob. + * @param string|resource|StreamInterface $content The content of the blob. + * @param BlobModels\CreateBlobOptions $options The optional parameters. + * + * @return BlobModels\PutBlobResult + * + * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx + */ + public function createBlockBlobAsync( + $container, + $blob, + $content, + BlobModels\CreateBlobOptions $options = null + ); + + /** + * Create a new page blob and upload the content to the page blob. + * + * @param string $container The name of the container. + * @param string $blob The name of the blob. + * @param int $length The length of the blob. + * @param string|resource|StreamInterface $content The content of the blob. + * @param BlobModels\CreateBlobOptions $options The optional parameters. + * + * @return BlobModels\GetBlobPropertiesResult + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-blob-properties + */ + public function createPageBlobFromContent( + $container, + $blob, + $length, + $content, + BlobModels\CreateBlobOptions $options = null + ); + + /** + * Creates a promise to create a new page blob and upload the content + * to the page blob. + * + * @param string $container The name of the container. + * @param string $blob The name of the blob. + * @param int $length The length of the blob. + * @param string|resource|StreamInterface $content The content of the blob. + * @param BlobModels\CreateBlobOptions $options The optional parameters. + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-blob-properties + */ + public function createPageBlobFromContentAsync( + $container, + $blob, + $length, + $content, + BlobModels\CreateBlobOptions $options = null + ); + /** * Clears a range of pages from the blob. * @@ -580,6 +687,44 @@ public function createBlobBlockAsync( $content, BlobModels\CreateBlobBlockOptions $options = null ); + + /** + * Commits a new block of data to the end of an existing append blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param resource|string|StreamInterface $content the blob block contents + * @param Models\AppendBlockOptions $options optional parameters + * + * @return Models\AppendBlockResult + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/append-block + */ + public function appendBlock( + $container, + $blob, + $content, + BlobModels\AppendBlockOptions $options = null + ); + + /** + * Creates promise to commit a new block of data to the end of an existing append blob. + * + * @param string $container name of the container + * @param string $blob name of the blob + * @param resource|string|StreamInterface $content the blob block contents + * @param Models\AppendBlockOptions $options optional parameters + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/append-block + */ + public function appendBlockAsync( + $container, + $blob, + $content, + BlobModels\AppendBlockOptions $options = null + ); /** * This method writes a blob by specifying the list of block IDs that make up the diff --git a/src/Blob/Models/AccessCondition.php b/src/Blob/Models/AccessCondition.php index 521c64ab0..efab8c0bb 100644 --- a/src/Blob/Models/AccessCondition.php +++ b/src/Blob/Models/AccessCondition.php @@ -41,18 +41,7 @@ */ class AccessCondition { - /** - * Represents the header type. - * - * @var string - */ private $_header = Resources::EMPTY_STRING; - - /** - * Represents the header value. - * - * @var string - */ private $_value; /** @@ -60,6 +49,8 @@ class AccessCondition * * @param string $headerType header name * @param string $value header value + * + * @internal */ protected function __construct($headerType, $value) { @@ -227,6 +218,8 @@ public function getValue() * * @param string $headerType candidate header type * + * @internal + * * @return boolean */ public static function isValid($headerType) diff --git a/src/Blob/Models/AccessPolicy.php b/src/Blob/Models/AccessPolicy.php deleted file mode 100644 index 577047ff5..000000000 --- a/src/Blob/Models/AccessPolicy.php +++ /dev/null @@ -1,140 +0,0 @@ - - * @copyright 2016 Microsoft Corporation - * @license https://github.com/azure/azure-storage-php/LICENSE - * @link https://github.com/azure/azure-storage-php - */ - -namespace MicrosoftAzure\Storage\Blob\Models; - -use MicrosoftAzure\Storage\Common\Internal\Utilities; -use MicrosoftAzure\Storage\Common\Internal\Validate; - -/** - * Holds container access policy elements - * - * @category Microsoft - * @package MicrosoftAzure\Storage\Blob\Models - * @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 AccessPolicy -{ - /** - * @var string - */ - private $_start; - - /** - * @var \DateTime - */ - private $_expiry; - - /** - * @var \DateTime - */ - private $_permission; - - /** - * Gets start. - * - * @return \DateTime. - */ - public function getStart() - { - return $this->_start; - } - - /** - * Sets start. - * - * @param \DateTime $start value. - * - * @return void - */ - public function setStart($start) - { - Validate::isDate($start); - $this->_start = $start; - } - - /** - * Gets expiry. - * - * @return \DateTime. - */ - public function getExpiry() - { - return $this->_expiry; - } - - /** - * Sets expiry. - * - * @param \DateTime $expiry value. - * - * @return void - */ - public function setExpiry($expiry) - { - Validate::isDate($expiry); - $this->_expiry = $expiry; - } - - /** - * Gets permission. - * - * @return string. - */ - public function getPermission() - { - return $this->_permission; - } - - /** - * Sets permission. - * - * @param string $permission value. - * - * @return void - */ - public function setPermission($permission) - { - $this->_permission = $permission; - } - - /** - * Converts this current object to XML representation. - * - * @return array - */ - public function toArray() - { - $array = array(); - - $array['Start'] = Utilities::convertToEdmDateTime($this->_start); - $array['Expiry'] = Utilities::convertToEdmDateTime($this->_expiry); - $array['Permission'] = $this->_permission; - - return $array; - } -} diff --git a/src/Blob/Models/AcquireLeaseOptions.php b/src/Blob/Models/AcquireLeaseOptions.php index b9bd7fbf5..ee96411e8 100644 --- a/src/Blob/Models/AcquireLeaseOptions.php +++ b/src/Blob/Models/AcquireLeaseOptions.php @@ -36,9 +36,6 @@ */ class AcquireLeaseOptions extends BlobServiceOptions { - /** - * @var AccessCondition - */ private $_accessCondition; /** diff --git a/src/Blob/Models/AppendBlockOptions.php b/src/Blob/Models/AppendBlockOptions.php new file mode 100644 index 000000000..776c882bf --- /dev/null +++ b/src/Blob/Models/AppendBlockOptions.php @@ -0,0 +1,154 @@ + + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ + +namespace MicrosoftAzure\Storage\Blob\Models; + +/** + * Optional parameters for appendBlock wrapper + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Blob\Models + * @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 AppendBlockOptions extends BlobServiceOptions +{ + private $_contentMD5; + private $_leaseId; + private $_maxBlobSize; + private $_appendPosition; + private $_accessCondition; + + /** + * Gets lease Id for the blob + * + * @return string + */ + public function getLeaseId() + { + return $this->_leaseId; + } + + /** + * Sets lease Id for the blob + * + * @param string $leaseId the blob lease id. + * + * @return void + */ + public function setLeaseId($leaseId) + { + $this->_leaseId = $leaseId; + } + + /** + * Gets block contentMD5. + * + * @return string + */ + public function getContentMD5() + { + return $this->_contentMD5; + } + + /** + * Sets block contentMD5. + * + * @param string $contentMD5 value. + * + * @return void + */ + public function setContentMD5($contentMD5) + { + $this->_contentMD5 = $contentMD5; + } + + /** + * Gets access condition + * + * @return AccessCondition + */ + public function getAccessCondition() + { + return $this->_accessCondition; + } + + /** + * Sets access condition + * + * @param AccessCondition $accessCondition value to use. + * + * @return void + */ + public function setAccessCondition($accessCondition) + { + $this->_accessCondition = $accessCondition; + } + + /** + * Gets the max length in bytes allowed for the append blob to grow to. + * + * @return int + */ + public function getMaxBlobSize() + { + return $this->_maxBlobSize; + } + + /** + * Sets the max length in bytes allowed for the append blob to grow to. + * + * @param int $maxBlobSize value. + * + * @return void + */ + public function setMaxBlobSize($maxBlobSize) + { + $this->_maxBlobSize = $maxBlobSize; + } + + /** + * Gets append blob appendPosition. + * + * @return int + */ + public function getAppendPosition() + { + return $this->_appendPosition; + } + + /** + * Sets append blob appendPosition. + * + * @param int $appendPosition value. + * + * @return void + */ + public function setAppendPosition($appendPosition) + { + $this->_appendPosition = $appendPosition; + } +} diff --git a/src/Blob/Models/AppendBlockResult.php b/src/Blob/Models/AppendBlockResult.php new file mode 100644 index 000000000..10f0608ec --- /dev/null +++ b/src/Blob/Models/AppendBlockResult.php @@ -0,0 +1,221 @@ + + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ + +namespace MicrosoftAzure\Storage\Blob\Models; + +use MicrosoftAzure\Storage\Common\Internal\Resources; +use MicrosoftAzure\Storage\Common\Internal\Utilities; + +/** + * The result of calling appendBlock API. + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Blob\Models + * @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 AppendBlockResult +{ + private $_etag; + private $_lastModified; + private $_contentMD5; + private $_appendOffset; + private $_committedBlockCount; + + /** + * Creates AppendBlockResult object from the response of the put block request. + * + * @param array $headers The HTTP response headers in array representation. + * + * @internal + * + * @return AppendBlockResult + */ + public static function create(array $headers) + { + $result = new AppendBlockResult(); + if (Utilities::arrayKeyExistsInsensitive( + Resources::ETAG, + $headers + )) { + $result->setEtag( + Utilities::tryGetValueInsensitive(Resources::ETAG, $headers) + ); + } + + if (Utilities::arrayKeyExistsInsensitive( + Resources::LAST_MODIFIED, + $headers + )) { + $lastModified = Utilities::tryGetValueInsensitive(Resources::LAST_MODIFIED, $headers); + $lastModified = Utilities::rfc1123ToDateTime($lastModified); + + $result->setLastModified($lastModified); + } + + if (Utilities::arrayKeyExistsInsensitive( + Resources::CONTENT_MD5, + $headers + )) { + $result->setContentMD5( + Utilities::tryGetValueInsensitive(Resources::CONTENT_MD5, $headers) + ); + } + + if (Utilities::arrayKeyExistsInsensitive( + Resources::X_MS_BLOB_APPEND_OFFSET, + $headers + )) { + $result->setAppendOffset( + intval(Utilities::tryGetValueInsensitive(Resources::X_MS_BLOB_APPEND_OFFSET, $headers)) + ); + } + + if (Utilities::arrayKeyExistsInsensitive( + Resources::X_MS_BLOB_COMMITTED_BLOCK_COUNT, + $headers + )) { + $committedBlockCount = Utilities::tryGetValueInsensitive( + Resources::X_MS_BLOB_COMMITTED_BLOCK_COUNT, + $headers + ); + $result->setCommittedBlockCount(intval($committedBlockCount)); + } + + return $result; + } + + /** + * Gets Etag of the blob that the client can use to perform conditional + * PUT operations by using the If-Match request header. + * + * @return string + */ + public function getEtag() + { + return $this->_etag; + } + + /** + * Sets the etag value. + * + * @param string $etag etag as a string. + * + * @return void + */ + protected function setEtag($etag) + { + $this->_etag = $etag; + } + + /** + * Gets $lastModified value. + * + * @return \DateTime + */ + public function getLastModified() + { + return $this->_lastModified; + } + + /** + * Sets the $lastModified value. + * + * @param \DateTime $lastModified $lastModified value. + * + * @return void + */ + protected function setLastModified($lastModified) + { + $this->_lastModified = $lastModified; + } + + /** + * Gets block content MD5. + * + * @return string + */ + public function getContentMD5() + { + return $this->_contentMD5; + } + + /** + * Sets the content MD5 value. + * + * @param string $contentMD5 conent MD5 as a string. + * + * @return void + */ + protected function setContentMD5($contentMD5) + { + $this->_contentMD5 = $contentMD5; + } + + /** + * Gets the offset at which the block was committed, in bytes. + * + * @return int + */ + public function getAppendOffset() + { + return $this->_appendOffset; + } + + /** + * Sets the offset at which the block was committed, in bytes. + * + * @param int $appendOffset append offset, in bytes. + * + * @return void + */ + protected function setAppendOffset($appendOffset) + { + $this->_appendOffset = $appendOffset; + } + + /** + * Gets the number of committed blocks present in the blob. + * + * @return int + */ + public function getCommittedBlockCount() + { + return $this->_committedBlockCount; + } + + /** + * Sets the number of committed blocks present in the blob. + * + * @param int $committedBlockCount the number of committed blocks present in the blob. + * + * @return void + */ + protected function setCommittedBlockCount($committedBlockCount) + { + $this->_committedBlockCount = $committedBlockCount; + } +} diff --git a/src/Blob/Models/Blob.php b/src/Blob/Models/Blob.php index 0e6824187..1fa490b20 100644 --- a/src/Blob/Models/Blob.php +++ b/src/Blob/Models/Blob.php @@ -36,29 +36,10 @@ */ class Blob { - /** - * @var string - */ private $_name; - - /** - * @var string - */ private $_url; - - /** - * @var string - */ private $_snapshot; - - /** - * @var array - */ private $_metadata; - - /** - * @var BlobProperties - */ private $_properties; /** diff --git a/src/Blob/Models/BlobBlockType.php b/src/Blob/Models/BlobBlockType.php index b8892a2ee..92f91b4dc 100644 --- a/src/Blob/Models/BlobBlockType.php +++ b/src/Blob/Models/BlobBlockType.php @@ -45,6 +45,8 @@ class BlobBlockType * * @param string $type The entry type. * + * @internal + * * @return boolean */ public static function isValid($type) diff --git a/src/Blob/Models/BlobPrefix.php b/src/Blob/Models/BlobPrefix.php index 9cc6810e9..10a9ea2d5 100644 --- a/src/Blob/Models/BlobPrefix.php +++ b/src/Blob/Models/BlobPrefix.php @@ -36,9 +36,6 @@ */ class BlobPrefix { - /** - * @var string - */ private $_name; /** diff --git a/src/Blob/Models/BlobProperties.php b/src/Blob/Models/BlobProperties.php index 06acb710e..95e0a5776 100644 --- a/src/Blob/Models/BlobProperties.php +++ b/src/Blob/Models/BlobProperties.php @@ -40,71 +40,27 @@ */ class BlobProperties { - /** - * @var \DateTime - */ private $_lastModified; - - /** - * @var string - */ private $_etag; - - /** - * @var string - */ private $_contentType; - - /** - * @var integer - */ private $_contentLength; - - /** - * @var string - */ private $_contentEncoding; - - /** - * @var string - */ private $_contentLanguage; - - /** - * @var string - */ private $_contentMD5; - - /** - * @var string - */ private $_contentRange; - - /** - * @var string - */ private $_cacheControl; - - /** - * @var string - */ private $_blobType; - - /** - * @var string - */ private $_leaseStatus; - - /** - * @var integer - */ private $_sequenceNumber; + private $_committedBlockCount; /** * Creates BlobProperties object from $parsed response in array representation * * @param array $parsed parsed response in array format. * + * @internal + * * @return BlobProperties */ public static function create(array $parsed) @@ -160,6 +116,9 @@ public static function create(array $parsed) $result->setContentType( Utilities::tryGetValue($clean, Resources::CONTENT_TYPE) ); + $result->setCommittedBlockCount( + intval(Utilities::tryGetValue($clean, Resources::X_MS_BLOB_COMMITTED_BLOCK_COUNT)) + ); return $result; } @@ -430,4 +389,26 @@ public function setSequenceNumber($sequenceNumber) Validate::isInteger($sequenceNumber, 'sequenceNumber'); $this->_sequenceNumber = $sequenceNumber; } + + /** + * Gets the number of committed blocks present in the blob. + * + * @return int + */ + public function getCommittedBlockCount() + { + return $this->_committedBlockCount; + } + + /** + * Sets the number of committed blocks present in the blob. + * + * @param int $committedBlockCount the number of committed blocks present in the blob. + * + * @return void + */ + public function setCommittedBlockCount($committedBlockCount) + { + $this->_committedBlockCount = $committedBlockCount; + } } diff --git a/src/Blob/Models/BlobServiceOptions.php b/src/Blob/Models/BlobServiceOptions.php index 947b6954f..9a3c39e6b 100644 --- a/src/Blob/Models/BlobServiceOptions.php +++ b/src/Blob/Models/BlobServiceOptions.php @@ -24,7 +24,7 @@ namespace MicrosoftAzure\Storage\Blob\Models; -use MicrosoftAzure\Storage\Common\ServiceOptionsBase; +use MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase; /** * Blob service options. diff --git a/src/Blob/Models/BlobType.php b/src/Blob/Models/BlobType.php index 9a2b24d44..ec318a1eb 100644 --- a/src/Blob/Models/BlobType.php +++ b/src/Blob/Models/BlobType.php @@ -38,4 +38,5 @@ class BlobType { const BLOCK_BLOB = 'BlockBlob'; const PAGE_BLOB = 'PageBlob'; + const APPEND_BLOB = 'AppendBlob'; } diff --git a/src/Blob/Models/Block.php b/src/Blob/Models/Block.php index ad4c0a39c..ff8e7a87d 100644 --- a/src/Blob/Models/Block.php +++ b/src/Blob/Models/Block.php @@ -36,14 +36,7 @@ */ class Block { - /** - * @var string - */ private $_blockId; - - /** - * @var string - */ private $_type; /** diff --git a/src/Blob/Models/BlockList.php b/src/Blob/Models/BlockList.php index 154cb488c..356c57431 100644 --- a/src/Blob/Models/BlockList.php +++ b/src/Blob/Models/BlockList.php @@ -40,16 +40,13 @@ */ class BlockList { - /** - * @var array - */ private $_entries; - public static $xmlRootName = 'BlockList'; + private static $xmlRootName = 'BlockList'; /** * Creates block list from array of blocks. * - * @param array $array The blocks array. + * @param Block[] The blocks array. * * @return BlockList */ @@ -143,7 +140,7 @@ public function getEntry($blockId) /** * Gets all blob block entries. * - * @return string + * @return Block[] */ public function getEntries() { @@ -155,6 +152,8 @@ public function getEntries() * * @param XmlSerializer $xmlSerializer The XML serializer. * + * @internal + * * @return string */ public function toXml(XmlSerializer $xmlSerializer) diff --git a/src/Blob/Models/BreakLeaseResult.php b/src/Blob/Models/BreakLeaseResult.php index 73ed896dc..d51d2df65 100644 --- a/src/Blob/Models/BreakLeaseResult.php +++ b/src/Blob/Models/BreakLeaseResult.php @@ -39,9 +39,6 @@ */ class BreakLeaseResult { - /** - * @var string - */ private $_leaseTime; /** diff --git a/src/Blob/Models/CommitBlobBlocksOptions.php b/src/Blob/Models/CommitBlobBlocksOptions.php index d9b48ef25..9d1a37966 100644 --- a/src/Blob/Models/CommitBlobBlocksOptions.php +++ b/src/Blob/Models/CommitBlobBlocksOptions.php @@ -38,44 +38,13 @@ */ class CommitBlobBlocksOptions extends BlobServiceOptions { - /** - * @var string - */ private $_blobContentType; - - /** - * @var string - */ private $_blobContentEncoding; - - /** - * @var string - */ private $_blobContentLanguage; - - /** - * @var string - */ private $_blobContentMD5; - - /** - * @var string - */ private $_blobCacheControl; - - /** - * @var array - */ private $_metadata; - - /** - * @var string - */ private $_leaseId; - - /** - * @var AccessCondition - */ private $_accessCondition; /** @@ -258,6 +227,8 @@ public function setLeaseId($leaseId) * Create a instance using the given options * @param mixed $options Input options * + * @internal + * * @return self */ public static function create($options) diff --git a/src/Blob/Models/Container.php b/src/Blob/Models/Container.php index bd3e4bf4b..fa142b5bd 100644 --- a/src/Blob/Models/Container.php +++ b/src/Blob/Models/Container.php @@ -39,24 +39,9 @@ */ class Container { - /** - * @var string - */ private $_name; - - /** - * @var string - */ private $_url; - - /** - * @var array - */ private $_metadata; - - /** - * @var ContainerProperties - */ private $_properties; /** diff --git a/src/Blob/Models/ContainerACL.php b/src/Blob/Models/ContainerACL.php index 3f5f4e17b..d803297df 100644 --- a/src/Blob/Models/ContainerACL.php +++ b/src/Blob/Models/ContainerACL.php @@ -24,13 +24,13 @@ namespace MicrosoftAzure\Storage\Blob\Models; -use MicrosoftAzure\Storage\Common\Internal\Utilities; use MicrosoftAzure\Storage\Common\Internal\Validate; use MicrosoftAzure\Storage\Common\Internal\Resources; -use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; +use MicrosoftAzure\Storage\Common\Internal\ACLBase; +use MicrosoftAzure\Storage\Blob\Models\PublicAccessType; /** - * Holds conatiner ACL members. + * Holds container ACL members. * * @category Microsoft * @package MicrosoftAzure\Storage\Blob\Models @@ -39,82 +39,43 @@ * @license https://github.com/azure/azure-storage-php/LICENSE * @link https://github.com/azure/azure-storage-php */ -class ContainerACL +class ContainerACL extends ACLBase { - /** - * All available types can be found in PublicAccessType - * - * @var string - */ - private $_publicAccess; + private $publicAccess; /** - * @var array + * Constructor. */ - private $_signedIdentifiers = array(); - - /* - * The root name of XML elemenet representation. - * - * @var string - */ - public static $xmlRootName = 'SignedIdentifiers'; - + public function __construct() + { + //setting the resource type to a default value. + $this->setResourceType(Resources::RESOURCE_TYPE_CONTAINER); + } /** - * Parses the given array into signed identifiers. + * Parses the given array into signed identifiers and create an instance of + * ContainerACL * * @param string $publicAccess The container public access. * @param array $parsed The parsed response into array representation. * + * @internal + * * @return ContainerACL */ public static function create($publicAccess, array $parsed = null) { - $result = new ContainerAcl(); - $result->_publicAccess = $publicAccess; - $result->_signedIdentifiers = array(); - - if (!empty($parsed) && is_array($parsed['SignedIdentifier'])) { - $entries = $parsed['SignedIdentifier']; - $temp = Utilities::getArray($entries); - - foreach ($temp as $value) { - $startString = urldecode($value['AccessPolicy']['Start']); - $expiryString = urldecode($value['AccessPolicy']['Expiry']); - $start = Utilities::convertToDateTime($startString); - $expiry = Utilities::convertToDateTime($expiryString); - $permission = $value['AccessPolicy']['Permission']; - $id = $value['Id']; - $result->addSignedIdentifier($id, $start, $expiry, $permission); - } - } + Validate::isTrue( + PublicAccessType::isValid($publicAccess), + Resources::INVALID_BLOB_PAT_MSG + ); + $result = new ContainerAcl(); + $result->fromXmlArray($parsed); + $result->setPublicAccess($publicAccess); return $result; } - /** - * Gets container signed modifiers. - * - * @return array - */ - public function getSignedIdentifiers() - { - return $this->_signedIdentifiers; - } - - /** - * Sets container signed modifiers. - * - * @param array $signedIdentifiers value. - * - * @return void - */ - public function setSignedIdentifiers(array $signedIdentifiers) - { - $this->_signedIdentifiers = $signedIdentifiers; - } - /** * Gets container publicAccess. * @@ -122,7 +83,7 @@ public function setSignedIdentifiers(array $signedIdentifiers) */ public function getPublicAccess() { - return $this->_publicAccess; + return $this->publicAccess; } /** @@ -138,81 +99,57 @@ public function setPublicAccess($publicAccess) PublicAccessType::isValid($publicAccess), Resources::INVALID_BLOB_PAT_MSG ); - $this->_publicAccess = $publicAccess; + $this->publicAccess = $publicAccess; + $this->setResourceType( + self::getResourceTypeByPublicAccess($publicAccess) + ); } /** - * Adds new signed modifier - * - * @param string $id a unique id for this modifier - * @param \DateTime $start The time at which the Shared Access Signature - * becomes valid. If omitted, start time for this call is assumed to be - * the time when the Blob service receives the request. - * @param \DateTime $expiry The time at which the Shared Access Signature - * becomes invalid. This field may be omitted if it has been specified as - * part of a container-level access policy. - * @param string $permission The permissions associated with the Shared - * Access Signature. The user is restricted to operations allowed by the - * permissions. Valid permissions values are read (r), write (w), delete (d) and - * list (l). - * - * @return void + * Gets the resource type according to the given public access. Default + * value is Resources::RESOURCE_TYPE_CONTAINER. * - * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh508996.aspx - */ - public function addSignedIdentifier( - $id, - \DateTime $start, - \DateTime $expiry, - $permission - ) { - Validate::isString($id, 'id'); - Validate::isDate($start); - Validate::isDate($expiry); - Validate::isString($permission, 'permission'); - - $accessPolicy = new AccessPolicy(); - $accessPolicy->setStart($start); - $accessPolicy->setExpiry($expiry); - $accessPolicy->setPermission($permission); - - $signedIdentifier = new SignedIdentifier(); - $signedIdentifier->setId($id); - $signedIdentifier->setAccessPolicy($accessPolicy); - - $this->_signedIdentifiers[] = $signedIdentifier; - } - - /** - * Converts this object to array representation for XML serialization + * @param string $publicAccess The public access that determines the + * resource type. * - * @return array + * @return string */ - public function toArray() + private static function getResourceTypeByPublicAccess($publicAccess) { - $array = array(); - - foreach ($this->_signedIdentifiers as $value) { - $array[] = $value->toArray(); + $result = ''; + + switch ($publicAccess) { + case PublicAccessType::BLOBS_ONLY: + $result = Resources::RESOURCE_TYPE_BLOB; + break; + case PublicAccessType::CONTAINER_AND_BLOBS: + $result = Resources::RESOURCE_TYPE_CONTAINER; + break; + default: + $result = Resources::RESOURCE_TYPE_CONTAINER; + break; } - - return $array; + + return $result; } - + /** - * Converts this current object to XML representation. + * Validate if the resource type for the class. * - * @param XmlSerializer $xmlSerializer The XML serializer. + * @param string $resourceType the resource type to be validated. * - * @return string + * @throws \InvalidArgumentException + * + * @internal + * + * @return void */ - public function toXml(XmlSerializer $xmlSerializer) + protected static function validateResourceType($resourceType) { - $properties = array( - XmlSerializer::DEFAULT_TAG => 'SignedIdentifier', - XmlSerializer::ROOT_NAME => self::$xmlRootName + Validate::isTrue( + $resourceType == Resources::RESOURCE_TYPE_BLOB || + $resourceType == Resources::RESOURCE_TYPE_CONTAINER, + Resources::INVALID_RESOURCE_TYPE ); - - return $xmlSerializer->serialize($this->toArray(), $properties); } } diff --git a/src/Blob/Models/ContainerProperties.php b/src/Blob/Models/ContainerProperties.php index 2ab8a3c75..b9ee8df69 100644 --- a/src/Blob/Models/ContainerProperties.php +++ b/src/Blob/Models/ContainerProperties.php @@ -36,14 +36,7 @@ */ class ContainerProperties { - /** - * @var \DateTime - */ private $_lastModified; - - /** - * @var string - */ private $_etag; /** diff --git a/src/Blob/Models/CopyBlobOptions.php b/src/Blob/Models/CopyBlobOptions.php index 2abeed60f..59fe98c40 100644 --- a/src/Blob/Models/CopyBlobOptions.php +++ b/src/Blob/Models/CopyBlobOptions.php @@ -38,35 +38,11 @@ */ class CopyBlobOptions extends BlobServiceOptions { - - /** - * @var AccessCondition - */ private $_accessCondition; - - /** - * @var AccessCondition - */ private $_sourceAccessCondition; - - /** - * @var array - */ private $_metadata; - - /** - * @var string - */ private $_sourceSnapshot; - - /** - * @var string - */ - private $_leaseId; - - /** - * @var string - */ + private $_leaseId; private $_sourceLeaseId; /** diff --git a/src/Blob/Models/CopyBlobResult.php b/src/Blob/Models/CopyBlobResult.php index bc9f77e5c..d8c043f86 100644 --- a/src/Blob/Models/CopyBlobResult.php +++ b/src/Blob/Models/CopyBlobResult.php @@ -39,14 +39,7 @@ */ class CopyBlobResult { - /** - * @var string - */ private $_etag; - - /** - * @var \DateTime - */ private $_lastModified; /** @@ -54,6 +47,8 @@ class CopyBlobResult * * @param array $headers The HTTP response headers in array representation. * + * @internal + * * @return CopyBlobResult */ public static function create(array $headers) diff --git a/src/Blob/Models/CreateBlobBlockOptions.php b/src/Blob/Models/CreateBlobBlockOptions.php index a0a2b5c15..7b8037f92 100644 --- a/src/Blob/Models/CreateBlobBlockOptions.php +++ b/src/Blob/Models/CreateBlobBlockOptions.php @@ -36,19 +36,8 @@ */ class CreateBlobBlockOptions extends BlobServiceOptions { - /** - * @var string - */ private $_contentMD5; - - /** - * @var string - */ private $_leaseId; - - /** - * @var int - */ private $_numberOfConcurrency; /** diff --git a/src/Blob/Models/CreateBlobOptions.php b/src/Blob/Models/CreateBlobOptions.php index dc47070bc..36da0969a 100644 --- a/src/Blob/Models/CreateBlobOptions.php +++ b/src/Blob/Models/CreateBlobOptions.php @@ -38,89 +38,22 @@ */ class CreateBlobOptions extends BlobServiceOptions { - /** - * @var string - */ private $_contentType; - - /** - * @var string - */ private $_contentEncoding; - - /** - * @var string - */ private $_contentLanguage; - - /** - * @var string - */ private $_contentMD5; - - /** - * @var string - */ private $_cacheControl; - - /** - * @var string - */ private $_blobContentType; - - /** - * @var string - */ private $_blobContentEncoding; - - /** - * @var string - */ private $_blobContentLanguage; - - /** - * @var integer - */ private $_blobContentLength; - - /** - * @var string - */ private $_blobContentMD5; - - /** - * @var string - */ private $_blobCacheControl; - - /** - * @var array - */ private $_metadata; - - /** - * @var string - */ private $_leaseId; - - /** - * @var integer - */ private $_sequenceNumber; - - /** - * @var string - */ private $_sequenceNumberAction; - - /** - * @var AccessCondition - */ private $_accessCondition; - - /** - * @var int - */ private $_numberOfConcurrency; /** diff --git a/src/Blob/Models/CreateBlobPagesOptions.php b/src/Blob/Models/CreateBlobPagesOptions.php index 1cd43b51e..7327e5be7 100644 --- a/src/Blob/Models/CreateBlobPagesOptions.php +++ b/src/Blob/Models/CreateBlobPagesOptions.php @@ -36,19 +36,8 @@ */ class CreateBlobPagesOptions extends BlobServiceOptions { - /** - * @var string - */ private $_contentMD5; - - /** - * @var string - */ private $_leaseId; - - /** - * @var AccessCondition - */ private $_accessCondition; /** diff --git a/src/Blob/Models/CreateBlobPagesResult.php b/src/Blob/Models/CreateBlobPagesResult.php index 3e9801b9e..e89a79792 100644 --- a/src/Blob/Models/CreateBlobPagesResult.php +++ b/src/Blob/Models/CreateBlobPagesResult.php @@ -40,24 +40,9 @@ */ class CreateBlobPagesResult { - /** - * @var \DateTime - */ private $_lastModified; - - /** - * @var string - */ private $_etag; - - /** - * @var integer - */ private $_sequenceNumber; - - /** - * @var string - */ private $_contentMD5; /** @@ -66,6 +51,8 @@ class CreateBlobPagesResult * * @param array $headers HTTP response headers * + * @internal + * * @return CreateBlobPagesResult */ public static function create(array $headers) diff --git a/src/Blob/Models/CreateBlobSnapshotOptions.php b/src/Blob/Models/CreateBlobSnapshotOptions.php index fba3706ab..bda29409c 100644 --- a/src/Blob/Models/CreateBlobSnapshotOptions.php +++ b/src/Blob/Models/CreateBlobSnapshotOptions.php @@ -36,19 +36,8 @@ */ class CreateBlobSnapshotOptions extends BlobServiceOptions { - /** - * @var array - */ private $_metadata; - - /** - * @var AccessCondition - */ private $_accessCondition; - - /** - * @var string - */ private $_leaseId; /** diff --git a/src/Blob/Models/CreateBlobSnapshotResult.php b/src/Blob/Models/CreateBlobSnapshotResult.php index d5cd98539..6b60e5bb1 100644 --- a/src/Blob/Models/CreateBlobSnapshotResult.php +++ b/src/Blob/Models/CreateBlobSnapshotResult.php @@ -40,22 +40,8 @@ */ class CreateBlobSnapshotResult { - /** - * A DateTime value which uniquely identifies the snapshot. - * @var string - */ private $_snapshot; - - /** - * The ETag for the destination blob. - * @var string - */ private $_etag; - - /** - * The date/time that the copy operation to the destination blob completed. - * @var \DateTime - */ private $_lastModified; /** @@ -64,6 +50,8 @@ class CreateBlobSnapshotResult * * @param array $headers The HTTP response headers in array representation. * + * @internal + * * @return CreateBlobSnapshotResult */ public static function create(array $headers) diff --git a/src/Blob/Models/CreateContainerOptions.php b/src/Blob/Models/CreateContainerOptions.php index fe4adc58f..1f1e4c48c 100644 --- a/src/Blob/Models/CreateContainerOptions.php +++ b/src/Blob/Models/CreateContainerOptions.php @@ -38,14 +38,7 @@ */ class CreateContainerOptions extends BlobServiceOptions { - /** - * @var string - */ private $_publicAccess; - - /** - * @var array - */ private $_metadata; /** diff --git a/src/Blob/Models/DeleteBlobOptions.php b/src/Blob/Models/DeleteBlobOptions.php index 4c56aba17..5111d53ab 100644 --- a/src/Blob/Models/DeleteBlobOptions.php +++ b/src/Blob/Models/DeleteBlobOptions.php @@ -38,24 +38,9 @@ */ class DeleteBlobOptions extends BlobServiceOptions { - /** - * @var string - */ private $_leaseId; - - /** - * @var string - */ private $_snapshot; - - /** - * @var AccessCondition - */ private $_accessCondition; - - /** - * @var boolean - */ private $_deleteSnaphotsOnly; /** diff --git a/src/Blob/Models/DeleteContainerOptions.php b/src/Blob/Models/DeleteContainerOptions.php index dfaf9b1ac..d57dbde4e 100644 --- a/src/Blob/Models/DeleteContainerOptions.php +++ b/src/Blob/Models/DeleteContainerOptions.php @@ -36,9 +36,6 @@ */ class DeleteContainerOptions extends BlobServiceOptions { - /** - * @var AccessCondition - */ private $_accessCondition; /** diff --git a/src/Blob/Models/GetBlobMetadataOptions.php b/src/Blob/Models/GetBlobMetadataOptions.php index f24795dca..55a41e1a8 100644 --- a/src/Blob/Models/GetBlobMetadataOptions.php +++ b/src/Blob/Models/GetBlobMetadataOptions.php @@ -36,19 +36,8 @@ */ class GetBlobMetadataOptions extends BlobServiceOptions { - /** - * @var string - */ private $_leaseId; - - /** - * @var string - */ private $_snapshot; - - /** - * @var AccessCondition - */ private $_accessCondition; /** diff --git a/src/Blob/Models/GetBlobMetadataResult.php b/src/Blob/Models/GetBlobMetadataResult.php index 26f97c77f..0d977d993 100644 --- a/src/Blob/Models/GetBlobMetadataResult.php +++ b/src/Blob/Models/GetBlobMetadataResult.php @@ -40,20 +40,8 @@ */ class GetBlobMetadataResult { - - /** - * @var \DateTime - */ private $_lastModified; - - /** - * @var string - */ private $_etag; - - /** - * @var array - */ private $_metadata; /** diff --git a/src/Blob/Models/GetBlobOptions.php b/src/Blob/Models/GetBlobOptions.php index d0501465f..aa9aa26c7 100644 --- a/src/Blob/Models/GetBlobOptions.php +++ b/src/Blob/Models/GetBlobOptions.php @@ -38,34 +38,11 @@ */ class GetBlobOptions extends BlobServiceOptions { - /** - * @var string - */ private $_leaseId; - - /** - * @var string - */ private $_snapshot; - - /** - * @var AccessCondition - */ private $_accessCondition; - - /** - * @var boolean - */ private $_computeRangeMD5; - - /** - * @var integer - */ private $_rangeStart; - - /** - * @var integer - */ private $_rangeEnd; /** diff --git a/src/Blob/Models/GetBlobPropertiesOptions.php b/src/Blob/Models/GetBlobPropertiesOptions.php index acf6e7569..a58ad2eea 100644 --- a/src/Blob/Models/GetBlobPropertiesOptions.php +++ b/src/Blob/Models/GetBlobPropertiesOptions.php @@ -36,19 +36,8 @@ */ class GetBlobPropertiesOptions extends BlobServiceOptions { - /** - * @var string - */ private $_leaseId; - - /** - * @var string - */ private $_snapshot; - - /** - * @var AccessCondition - */ private $_accessCondition; /** diff --git a/src/Blob/Models/GetBlobPropertiesResult.php b/src/Blob/Models/GetBlobPropertiesResult.php index 8f32dc18a..41209fbb4 100644 --- a/src/Blob/Models/GetBlobPropertiesResult.php +++ b/src/Blob/Models/GetBlobPropertiesResult.php @@ -40,14 +40,7 @@ */ class GetBlobPropertiesResult { - /** - * @var BlobProperties - */ private $_properties; - - /** - * @var array - */ private $_metadata; /** @@ -99,6 +92,8 @@ protected function setProperties($properties) * * @param array $headers response headers parsed in an array * + * @internal + * * @return GetBlobPropertiesResult */ public static function create(array $headers) @@ -155,6 +150,12 @@ public static function create(array $headers) ); } + if (array_key_exists(Resources::X_MS_BLOB_COMMITTED_BLOCK_COUNT, $headers)) { + $properties->setCommittedBlockCount( + intval($headers[Resources::X_MS_BLOB_COMMITTED_BLOCK_COUNT]) + ); + } + $properties->setBlobType($blobType); $properties->setCacheControl($cacheControl); $properties->setContentEncoding($contentEncoding); diff --git a/src/Blob/Models/GetBlobResult.php b/src/Blob/Models/GetBlobResult.php index 48707d722..21bfbe8f8 100644 --- a/src/Blob/Models/GetBlobResult.php +++ b/src/Blob/Models/GetBlobResult.php @@ -40,19 +40,8 @@ */ class GetBlobResult { - /** - * @var BlobProperties - */ private $_properties; - - /** - * @var array - */ private $_metadata; - - /** - * @var resource - */ private $_contentStream; /** @@ -62,6 +51,8 @@ class GetBlobResult * @param StreamInterface $body The response body. * @param array $metadata The blob metadata. * + * @internal + * * @return GetBlobResult */ public static function create( diff --git a/src/Blob/Models/GetContainerACLResult.php b/src/Blob/Models/GetContainerACLResult.php index 18340de05..fb74ffc53 100644 --- a/src/Blob/Models/GetContainerACLResult.php +++ b/src/Blob/Models/GetContainerACLResult.php @@ -36,19 +36,9 @@ */ class GetContainerACLResult { - /** - * @var ContainerAcl - */ private $_containerACL; - - /** - * @var \DateTime - */ private $_lastModified; - /** - * @var string - */ private $_etag; /** @@ -60,6 +50,8 @@ class GetContainerACLResult * @param array $parsed parsed response into array * representation * + * @internal + * * @return self */ public static function create( diff --git a/src/Blob/Models/GetContainerPropertiesResult.php b/src/Blob/Models/GetContainerPropertiesResult.php index 940265ee3..5b738ebf3 100644 --- a/src/Blob/Models/GetContainerPropertiesResult.php +++ b/src/Blob/Models/GetContainerPropertiesResult.php @@ -40,19 +40,8 @@ */ class GetContainerPropertiesResult { - /** - * @var \DateTime - */ private $_lastModified; - - /** - * @var string - */ private $_etag; - - /** - * @var array - */ private $_metadata; /** @@ -130,6 +119,8 @@ protected function setMetadata(array $metadata) * * @param array $responseHeaders The array contains all the response headers * + * @internal + * * @return GetContainerPropertiesResult */ public static function create(array $responseHeaders) diff --git a/src/Blob/Models/LeaseBlobResult.php b/src/Blob/Models/LeaseBlobResult.php index 4ed6db068..39ded4985 100644 --- a/src/Blob/Models/LeaseBlobResult.php +++ b/src/Blob/Models/LeaseBlobResult.php @@ -39,9 +39,6 @@ */ class LeaseBlobResult { - /** - * @var string - */ private $_leaseId; /** @@ -49,6 +46,8 @@ class LeaseBlobResult * * @param array $headers response headers * + * @internal + * * @return \MicrosoftAzure\Storage\Blob\Models\LeaseBlobResult */ public static function create(array $headers) diff --git a/src/Blob/Models/ListBlobBlocksOptions.php b/src/Blob/Models/ListBlobBlocksOptions.php index 5e62da98e..2712fde44 100644 --- a/src/Blob/Models/ListBlobBlocksOptions.php +++ b/src/Blob/Models/ListBlobBlocksOptions.php @@ -38,32 +38,10 @@ */ class ListBlobBlocksOptions extends BlobServiceOptions { - /** - * @var string - */ private $_leaseId; - - /** - * @var string - */ private $_snapshot; - - /** - * @var boolean - */ private $_includeUncommittedBlobs; - - /** - * @var boolean - */ private $_includeCommittedBlobs; - - /** - * Holds result of list type. You can access it by this order: - * $_listType[$this->_includeUncommittedBlobs][$this->_includeCommittedBlobs] - * - * @var array - */ private static $_listType; /** diff --git a/src/Blob/Models/ListBlobBlocksResult.php b/src/Blob/Models/ListBlobBlocksResult.php index 867230adf..f27b132c5 100644 --- a/src/Blob/Models/ListBlobBlocksResult.php +++ b/src/Blob/Models/ListBlobBlocksResult.php @@ -40,34 +40,11 @@ */ class ListBlobBlocksResult { - /** - * @var \DateTime - */ private $_lastModified; - - /** - * @var string - */ private $_etag; - - /** - * @var string - */ private $_contentType; - - /** - * @var integer - */ private $_contentLength; - - /** - * @var array - */ private $_committedBlocks; - - /** - * @var array - */ private $_uncommittedBlocks; /** @@ -106,6 +83,8 @@ private static function _getEntries(array $parsed, $type) * @param array $headers HTTP response headers * @param array $parsed HTTP response body in array representation * + * @internal + * * @return ListBlobBlocksResult */ public static function create(array $headers, array $parsed) diff --git a/src/Blob/Models/ListBlobsOptions.php b/src/Blob/Models/ListBlobsOptions.php index b1ba513da..5f4f46f5b 100644 --- a/src/Blob/Models/ListBlobsOptions.php +++ b/src/Blob/Models/ListBlobsOptions.php @@ -38,39 +38,12 @@ */ class ListBlobsOptions extends BlobServiceOptions { - /** - * @var string - */ private $_prefix; - - /** - * @var string - */ private $_marker; - - /** - * @var string - */ private $_delimiter; - - /** - * @var integer - */ private $_maxResults; - - /** - * @var boolean - */ private $_includeMetadata; - - /** - * @var boolean - */ private $_includeSnapshots; - - /** - * @var boolean - */ private $_includeUncommittedBlobs; /** diff --git a/src/Blob/Models/ListBlobsResult.php b/src/Blob/Models/ListBlobsResult.php index 7b119fbca..4a8e87131 100644 --- a/src/Blob/Models/ListBlobsResult.php +++ b/src/Blob/Models/ListBlobsResult.php @@ -27,7 +27,7 @@ use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Blob\Models\Blob; use MicrosoftAzure\Storage\Common\Internal\Utilities; -use MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException; +use MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException; /** * Hold result of calliing listBlobs wrapper. @@ -41,44 +41,13 @@ */ class ListBlobsResult { - /** - * @var array - */ private $_blobPrefixes; - - /** - * @var Blob[] - */ private $_blobs; - - /** - * @var string - */ private $_delimiter; - - /** - * @var string - */ private $_prefix; - - /** - * @var string - */ private $_marker; - - /** - * @var string - */ private $_nextMarker; - - /** - * @var integer - */ private $_maxResults; - - /** - * @var string - */ private $_containerName; /** @@ -86,6 +55,8 @@ class ListBlobsResult * * @param array $parsed XML response parsed into array. * + * @internal + * * @return ListBlobsResult */ public static function create(array $parsed) diff --git a/src/Blob/Models/ListContainersOptions.php b/src/Blob/Models/ListContainersOptions.php index 6d9992597..89d2164d6 100644 --- a/src/Blob/Models/ListContainersOptions.php +++ b/src/Blob/Models/ListContainersOptions.php @@ -39,45 +39,14 @@ */ class ListContainersOptions extends BlobServiceOptions { - /** - * Filters the results to return only containers whose name begins with the - * specified prefix. - * - * @var string - */ private $_prefix; - - /** - * Identifies the portion of the list to be returned with the next list operation - * The operation returns a marker value within the - * response body if the list returned was not complete. The marker value may - * then be used in a subsequent call to request the next set of list items. - * The marker value is opaque to the client. - * - * @var string - */ private $_marker; - - /** - * Specifies the maximum number of containers to return. If the request does not - * specify maxresults, or specifies a value greater than 5,000, the server will - * return up to 5,000 items. If the parameter is set to a value less than or - * equal to zero, the server will return status code 400 (Bad Request). - * - * @var string - */ private $_maxResults; - - /** - * Include this parameter to specify that the container's metadata be returned - * as part of the response body. - * - * @var bool - */ private $_includeMetadata; /** - * Gets prefix. + * Gets prefix - filters the results to return only containers whose name + * begins with the specified prefix. * * @return string */ @@ -87,7 +56,8 @@ public function getPrefix() } /** - * Sets prefix. + * Sets prefix - filters the results to return only containers whose name + * begins with the specified prefix. * * @param string $prefix value. * @@ -100,7 +70,11 @@ public function setPrefix($prefix) } /** - * Gets marker. + * Gets marker which identifies the portion of the list to be returned with + * the next list operation. The operation returns a marker value within the + * response body if the list returned was not complete. The marker value may + * then be used in a subsequent call to request the next set of list items. + * The marker value is opaque to the client. * * @return string */ @@ -110,7 +84,11 @@ public function getMarker() } /** - * Sets marker. + * Sets marker which identifies the portion of the list to be returned with + * the next list operation. The operation returns a marker value within the + * response body if the list returned was not complete. The marker value may + * then be used in a subsequent call to request the next set of list items. + * The marker value is opaque to the client. * * @param string $marker value. * @@ -123,7 +101,11 @@ public function setMarker($marker) } /** - * Gets max results. + * Gets max results which specifies the maximum number of containers to return. + * If the request does not specify maxresults, or specifies a value + * greater than 5,000, the server will return up to 5,000 items. + * If the parameter is set to a value less than or equal to zero, + * the server will return status code 400 (Bad Request). * * @return string */ @@ -133,7 +115,11 @@ public function getMaxResults() } /** - * Sets max results. + * Sets max results which specifies the maximum number of containers to return. + * If the request does not specify maxresults, or specifies a value + * greater than 5,000, the server will return up to 5,000 items. + * If the parameter is set to a value less than or equal to zero, + * the server will return status code 400 (Bad Request). * * @param string $maxResults value. * diff --git a/src/Blob/Models/ListContainersResult.php b/src/Blob/Models/ListContainersResult.php index c0eabc087..86154ce7d 100644 --- a/src/Blob/Models/ListContainersResult.php +++ b/src/Blob/Models/ListContainersResult.php @@ -41,34 +41,11 @@ */ class ListContainersResult { - /** - * @var array - */ private $_containers; - - /** - * @var string - */ private $_prefix; - - /** - * @var string - */ private $_marker; - - /** - * @var string - */ private $_nextMarker; - - /** - * @var integer - */ private $_maxResults; - - /** - * @var string - */ private $_accountName; /** @@ -76,6 +53,8 @@ class ListContainersResult * * @param array $parsedResponse XML response parsed into array. * + * @internal + * * @return ListContainersResult */ public static function create(array $parsedResponse) diff --git a/src/Blob/Models/ListPageBlobRangesOptions.php b/src/Blob/Models/ListPageBlobRangesOptions.php index 50ed983d4..f3822408c 100644 --- a/src/Blob/Models/ListPageBlobRangesOptions.php +++ b/src/Blob/Models/ListPageBlobRangesOptions.php @@ -38,29 +38,10 @@ */ class ListPageBlobRangesOptions extends BlobServiceOptions { - /** - * @var string - */ private $_leaseId; - - /** - * @var string - */ private $_snapshot; - - /** - * @var integer - */ private $_rangeStart; - - /** - * @var integer - */ private $_rangeEnd; - - /** - * @var AccessCondition - */ private $_accessCondition; /** diff --git a/src/Blob/Models/ListPageBlobRangesResult.php b/src/Blob/Models/ListPageBlobRangesResult.php index aec47c70d..f4612749c 100644 --- a/src/Blob/Models/ListPageBlobRangesResult.php +++ b/src/Blob/Models/ListPageBlobRangesResult.php @@ -41,24 +41,9 @@ */ class ListPageBlobRangesResult { - /** - * @var \DateTime - */ private $_lastModified; - - /** - * @var string - */ private $_etag; - - /** - * @var integer - */ private $_contentLength; - - /** - * @var array - */ private $_pageRanges; /** @@ -67,6 +52,8 @@ class ListPageBlobRangesResult * @param array $headers HTTP response headers * @param array $parsed parsed response in array format. * + * @internal + * * @return ListPageBlobRangesResult */ public static function create(array $headers, array $parsed = null) diff --git a/src/Blob/Models/PageRange.php b/src/Blob/Models/PageRange.php index 875b5d944..fe27a93cf 100644 --- a/src/Blob/Models/PageRange.php +++ b/src/Blob/Models/PageRange.php @@ -36,14 +36,7 @@ */ class PageRange { - /** - * @var integer - */ private $_start; - - /** - * @var integer - */ private $_end; /** diff --git a/src/Blob/Models/PublicAccessType.php b/src/Blob/Models/PublicAccessType.php index 628b042a0..efebf3b09 100644 --- a/src/Blob/Models/PublicAccessType.php +++ b/src/Blob/Models/PublicAccessType.php @@ -47,6 +47,8 @@ class PublicAccessType * * @param string $type The public access type. * + * @internal + * * @return boolean */ public static function isValid($type) diff --git a/src/Blob/Models/PutBlobResult.php b/src/Blob/Models/PutBlobResult.php index 39b18caaa..8ac8eb350 100644 --- a/src/Blob/Models/PutBlobResult.php +++ b/src/Blob/Models/PutBlobResult.php @@ -39,19 +39,8 @@ */ class PutBlobResult { - /** - * @var string - */ private $_etag; - - /** - * @var \DateTime - */ private $_lastModified; - - /** - * @var string - */ private $_contentMD5; /** @@ -59,6 +48,8 @@ class PutBlobResult * * @param array $headers The HTTP response headers in array representation. * + * @internal + * * @return PutBlobResult */ public static function create(array $headers) diff --git a/src/Blob/Models/PutBlockResult.php b/src/Blob/Models/PutBlockResult.php index c6ede61f0..b500b0b0d 100644 --- a/src/Blob/Models/PutBlockResult.php +++ b/src/Blob/Models/PutBlockResult.php @@ -39,9 +39,6 @@ */ class PutBlockResult { - /** - * @var string - */ private $_contentMD5; /** @@ -49,6 +46,8 @@ class PutBlockResult * * @param array $headers The HTTP response headers in array representation. * + * @internal + * * @return PutBlockResult */ public static function create(array $headers) diff --git a/src/Blob/Models/SetBlobMetadataOptions.php b/src/Blob/Models/SetBlobMetadataOptions.php index 5677a839d..328de2c3e 100644 --- a/src/Blob/Models/SetBlobMetadataOptions.php +++ b/src/Blob/Models/SetBlobMetadataOptions.php @@ -36,14 +36,7 @@ */ class SetBlobMetadataOptions extends BlobServiceOptions { - /** - * @var string - */ private $_leaseId; - - /** - * @var AccessCondition - */ private $_accessCondition; /** diff --git a/src/Blob/Models/SetBlobMetadataResult.php b/src/Blob/Models/SetBlobMetadataResult.php index 5c637549a..5b9803c43 100644 --- a/src/Blob/Models/SetBlobMetadataResult.php +++ b/src/Blob/Models/SetBlobMetadataResult.php @@ -40,15 +40,7 @@ */ class SetBlobMetadataResult { - - /** - * @var \DateTime - */ private $_lastModified; - - /** - * @var string - */ private $_etag; /** @@ -56,6 +48,8 @@ class SetBlobMetadataResult * * @param array $headers response headers * + * @internal + * * @return SetBlobMetadataResult */ public static function create(array $headers) diff --git a/src/Blob/Models/SetBlobPropertiesOptions.php b/src/Blob/Models/SetBlobPropertiesOptions.php index 3514a73c7..da3db6c23 100644 --- a/src/Blob/Models/SetBlobPropertiesOptions.php +++ b/src/Blob/Models/SetBlobPropertiesOptions.php @@ -38,24 +38,9 @@ */ class SetBlobPropertiesOptions extends BlobServiceOptions { - /** - * @var BlobProperties - */ private $_blobProperties; - - /** - * @var string - */ private $_leaseId; - - /** - * @var string - */ private $_sequenceNumberAction; - - /** - * @var AccessCondition - */ private $_accessCondition; /** diff --git a/src/Blob/Models/SetBlobPropertiesResult.php b/src/Blob/Models/SetBlobPropertiesResult.php index 1fa5ac22d..1653208f4 100644 --- a/src/Blob/Models/SetBlobPropertiesResult.php +++ b/src/Blob/Models/SetBlobPropertiesResult.php @@ -40,19 +40,8 @@ */ class SetBlobPropertiesResult { - /** - * @var \DateTime - */ private $_lastModified; - - /** - * @var string - */ private $_etag; - - /** - * @var integer - */ private $_sequenceNumber; /** @@ -60,6 +49,8 @@ class SetBlobPropertiesResult * * @param array $headers response headers * + * @internal + * * @return SetBlobPropertiesResult */ public static function create(array $headers) diff --git a/src/Blob/Models/SetContainerMetadataOptions.php b/src/Blob/Models/SetContainerMetadataOptions.php index 66e770360..3d58e5e54 100644 --- a/src/Blob/Models/SetContainerMetadataOptions.php +++ b/src/Blob/Models/SetContainerMetadataOptions.php @@ -39,9 +39,6 @@ */ class SetContainerMetadataOptions extends BlobServiceOptions { - /** - * @var AccessCondition - */ private $_accessCondition; /** diff --git a/src/Common/CloudConfigurationManager.php b/src/Common/CloudConfigurationManager.php index c6432c8dd..c52762d27 100644 --- a/src/Common/CloudConfigurationManager.php +++ b/src/Common/CloudConfigurationManager.php @@ -41,16 +41,7 @@ */ class CloudConfigurationManager { - /** - * @var boolean - */ private static $_isInitialized = false; - - /** - * The list of connection string sources. - * - * @var array - */ private static $_sources; /** diff --git a/src/Common/Internal/InvalidArgumentTypeException.php b/src/Common/Exceptions/InvalidArgumentTypeException.php similarity index 91% rename from src/Common/Internal/InvalidArgumentTypeException.php rename to src/Common/Exceptions/InvalidArgumentTypeException.php index 4709dffc0..8aca35fc7 100644 --- a/src/Common/Internal/InvalidArgumentTypeException.php +++ b/src/Common/Exceptions/InvalidArgumentTypeException.php @@ -15,14 +15,14 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common\Exceptions * @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 */ -namespace MicrosoftAzure\Storage\Common\Internal; +namespace MicrosoftAzure\Storage\Common\Exceptions; use MicrosoftAzure\Storage\Common\Internal\Resources; @@ -30,7 +30,7 @@ * Exception thrown if an argument type does not match with the expected type. * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common\Exceptions * @author Azure Storage PHP SDK * @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE diff --git a/src/Common/ServiceException.php b/src/Common/Exceptions/ServiceException.php similarity index 95% rename from src/Common/ServiceException.php rename to src/Common/Exceptions/ServiceException.php index 37beaa810..f609bebfd 100644 --- a/src/Common/ServiceException.php +++ b/src/Common/Exceptions/ServiceException.php @@ -15,14 +15,14 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Common + * @package MicrosoftAzure\Storage\Common\Exceptions * @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 */ -namespace MicrosoftAzure\Storage\Common; +namespace MicrosoftAzure\Storage\Common\Exceptions; use MicrosoftAzure\Storage\Common\Internal\Serialization\XMLSerializer; use MicrosoftAzure\Storage\Common\Internal\Resources; @@ -32,7 +32,7 @@ * Fires when the response code is incorrect. * * @category Microsoft - * @package MicrosoftAzure\Storage\Common + * @package MicrosoftAzure\Storage\Common\Exceptions * @author Azure Storage PHP SDK * @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -50,6 +50,8 @@ class ServiceException extends \LogicException * @param ResponseInterface $response The response received that causes the * exception. * + * @internal + * * @return ServiceException */ public function __construct(ResponseInterface $response) @@ -73,6 +75,8 @@ public function __construct(ResponseInterface $response) * * @param ResponseInterface $response The response with a response body. * + * @internal + * * @return string */ protected static function parseErrorMessage(ResponseInterface $response) diff --git a/src/Common/Internal/ACLBase.php b/src/Common/Internal/ACLBase.php new file mode 100644 index 000000000..e0a2dabf6 --- /dev/null +++ b/src/Common/Internal/ACLBase.php @@ -0,0 +1,256 @@ + + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ + +namespace MicrosoftAzure\Storage\Common\Internal; + +use MicrosoftAzure\Storage\Common\Internal\Utilities; +use MicrosoftAzure\Storage\Common\Internal\Validate; +use MicrosoftAzure\Storage\Common\Internal\Resources; +use MicrosoftAzure\Storage\Common\Models\AccessPolicy; +use MicrosoftAzure\Storage\Common\Models\SignedIdentifier; +use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; + +/** + * Provide base class for service ACLs. + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Common\Models + * @author Azure Storage PHP SDK + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +abstract class ACLBase +{ + private $signedIdentifiers = array(); + private $resourceType = ''; + + /** + * Validate if the resource type for the class. + * + * @param string $resourceType the resource type to be validated. + * + * @throws \InvalidArgumentException + * + * @internal + * + * @return void + */ + abstract protected static function validateResourceType($resourceType); + + /** + * Converts signed identifiers to array representation for XML serialization + * + * @internal + * + * @return array + */ + public function toArray() + { + $array = array(); + + foreach ($this->getSignedIdentifiers() as $value) { + $array[] = $value->toArray(); + } + + return $array; + } + + /** + * Converts this signed identifiers to XML representation. + * + * @param XmlSerializer $xmlSerializer The XML serializer. + * + * @internal + * + * @return string + */ + public function toXml(XmlSerializer $serializer) + { + $properties = array( + XmlSerializer::DEFAULT_TAG => Resources::XTAG_SIGNED_IDENTIFIER, + XmlSerializer::ROOT_NAME => Resources::XTAG_SIGNED_IDENTIFIERS + ); + + return $serializer->serialize($this->toArray(), $properties); + } + + /** + * Construct the signed identifiers from a given parsed XML in array + * representation. + * + * @param array|null $parsed The parsed XML into array representation. + * + * @internal + * + * @return void + */ + public function fromXmlArray(array $parsed = null) + { + $this->setSignedIdentifiers(array()); + + // Initialize signed identifiers. + if (!empty($parsed) && + is_array($parsed[Resources::XTAG_SIGNED_IDENTIFIER]) + ) { + $entries = $parsed[Resources::XTAG_SIGNED_IDENTIFIER]; + $temp = Utilities::getArray($entries); + + foreach ($temp as $value) { + $accessPolicy = $value[Resources::XTAG_ACCESS_POLICY]; + $startString = urldecode( + $accessPolicy[Resources::XTAG_SIGNED_START] + ); + $expiryString = urldecode( + $accessPolicy[Resources::XTAG_SIGNED_EXPIRY] + ); + $start = Utilities::convertToDateTime($startString); + $expiry = Utilities::convertToDateTime($expiryString); + $permission = $accessPolicy[Resources::XTAG_SIGNED_PERMISSION]; + $id = $value[Resources::XTAG_SIGNED_ID]; + $this->addSignedIdentifier($id, $start, $expiry, $permission); + } + } + } + + /** + * Get the type of resource this ACL relate to. + * + * @internal + * + * @return string + */ + protected function getResourceType() + { + return $this->resourceType; + } + + /** + * Set the type of resource this ACL relate to. + * + * @internal + * + * @return void + */ + protected function setResourceType($resourceType) + { + static::validateResourceType($resourceType); + $this->resourceType = $resourceType; + } + + /** + * Add a signed identifier to the ACL. + * + * @param string $id A unique id for this signed identifier. + * @param \DateTime $start The time at which the Shared Access + * Signature becomes valid. If omitted, start + * time for this call is assumed to be the + * time when the service receives the + * request. + * @param \DateTime $expiry The time at which the Shared Access + * Signature becomes invalid. + * @param string $permissions The permissions associated with the Shared + * Access Signature. The user is restricted to + * operations allowed by the permissions. + * + * @return void + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/establishing-a-stored-access-policy + */ + public function addSignedIdentifier( + $id, + \DateTime $start, + \DateTime $expiry, + $permissions + ) { + Validate::isString($id, 'id'); + if ($start != null) { + Validate::isDate($start); + } + Validate::isDate($expiry); + Validate::isString($permissions, 'permissions'); + + $accessPolicy = new AccessPolicy($this->getResourceType()); + $accessPolicy->setStart($start); + $accessPolicy->setExpiry($expiry); + $accessPolicy->setPermission($permissions); + + $signedIdentifier = new SignedIdentifier(); + $signedIdentifier->setId($id); + $signedIdentifier->setAccessPolicy($accessPolicy); + + // Remove the signed identifier with the same ID. + $this->removeSignedIdentifier($id); + + // There can be no more than 5 signed identifiers at the same time. + Validate::isTrue( + count($this->getSignedIdentifiers()) < 5, + Resources::ERROR_TOO_MANY_SIGNED_IDENTIFIERS + ); + + $this->signedIdentifiers[] = $signedIdentifier; + } + + /** + * Remove the signed identifier with given ID. + * + * @param string $id The ID of the signed identifier to be removed. + * + * @return boolean + */ + public function removeSignedIdentifier($id) + { + Validate::isString($id, 'id'); + //var_dump($this->signedIdentifiers); + for ($i = 0; $i < count($this->signedIdentifiers); ++$i) { + if ($this->signedIdentifiers[$i]->getId() == $id) { + array_splice($this->signedIdentifiers, $i, 1); + return true; + } + } + + return false; + } + + /** + * Gets signed identifiers. + * + * @return array + */ + public function getSignedIdentifiers() + { + return $this->signedIdentifiers; + } + + public function setSignedIdentifiers(array $signedIdentifiers) + { + // There can be no more than 5 signed identifiers at the same time. + Validate::isTrue( + count($signedIdentifiers) <= 5, + Resources::ERROR_TOO_MANY_SIGNED_IDENTIFIERS + ); + $this->signedIdentifiers = $signedIdentifiers; + } +} diff --git a/src/Common/Internal/Authentication/IAuthScheme.php b/src/Common/Internal/Authentication/IAuthScheme.php index 581a12e6c..be50dc8d7 100644 --- a/src/Common/Internal/Authentication/IAuthScheme.php +++ b/src/Common/Internal/Authentication/IAuthScheme.php @@ -29,6 +29,7 @@ /** * Interface for azure authentication schemes. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal\Authentication * @author Azure Storage PHP SDK diff --git a/src/Common/Internal/Authentication/SharedAccessSignatureAuthScheme.php b/src/Common/Internal/Authentication/SharedAccessSignatureAuthScheme.php index be47a9d09..f661a17ed 100644 --- a/src/Common/Internal/Authentication/SharedAccessSignatureAuthScheme.php +++ b/src/Common/Internal/Authentication/SharedAccessSignatureAuthScheme.php @@ -30,6 +30,7 @@ /** * Base class for azure authentication schemes. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal\Authentication * @author Azure Storage PHP SDK @@ -39,6 +40,9 @@ */ class SharedAccessSignatureAuthScheme implements IAuthScheme { + /** + * The sas token + */ protected $sasToken; /** diff --git a/src/Common/Internal/Authentication/SharedKeyAuthScheme.php b/src/Common/Internal/Authentication/SharedKeyAuthScheme.php index 7e29fc556..f9b8f6809 100644 --- a/src/Common/Internal/Authentication/SharedKeyAuthScheme.php +++ b/src/Common/Internal/Authentication/SharedKeyAuthScheme.php @@ -26,7 +26,7 @@ use GuzzleHttp\Psr7\Request; use MicrosoftAzure\Storage\Common\Internal\Authentication\IAuthScheme; -use MicrosoftAzure\Storage\Common\Internal\HttpFormatter; +use MicrosoftAzure\Storage\Common\Internal\Http\HttpFormatter; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Utilities; @@ -34,6 +34,7 @@ * Provides shared key authentication scheme for blob and queue. For more info * check: http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal\Authentication * @author Azure Storage PHP SDK @@ -43,8 +44,19 @@ */ class SharedKeyAuthScheme implements IAuthScheme { + /** + * The account name + */ protected $accountName; + + /** + * The account key + */ protected $accountKey; + + /** + * The included headers + */ protected $includedHeaders; /** diff --git a/src/Common/Internal/Authentication/TableSharedKeyLiteAuthScheme.php b/src/Common/Internal/Authentication/TableSharedKeyLiteAuthScheme.php index eb557cfd9..08e1213d0 100644 --- a/src/Common/Internal/Authentication/TableSharedKeyLiteAuthScheme.php +++ b/src/Common/Internal/Authentication/TableSharedKeyLiteAuthScheme.php @@ -32,6 +32,7 @@ * Provides shared key authentication scheme for blob and queue. For more info * check: http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal\Authentication * @author Azure Storage PHP SDK @@ -41,6 +42,9 @@ */ class TableSharedKeyLiteAuthScheme extends SharedKeyAuthScheme { + /** + * The invaluded headers + */ protected $includedHeaders; /** diff --git a/src/Common/Internal/ConnectionStringParser.php b/src/Common/Internal/ConnectionStringParser.php index a388e5b0e..4f8869415 100644 --- a/src/Common/Internal/ConnectionStringParser.php +++ b/src/Common/Internal/ConnectionStringParser.php @@ -29,6 +29,7 @@ * strings are defined here: * www.connectionstrings.com/articles/show/important-rules-for-connection-strings * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal * @author Azure Storage PHP SDK @@ -43,24 +44,9 @@ class ConnectionStringParser const EXPECT_VALUE = 'ExpectValue'; const EXPECT_SEPARATOR = 'ExpectSeparator'; - /** - * @var string - */ private $_argumentName; - - /** - * @var string - */ private $_value; - - /** - * @var integer - */ private $_pos; - - /** - * @var string - */ private $_state; /** @@ -71,8 +57,6 @@ class ConnectionStringParser * @param string $connectionString Connection string. * * @return array - * - * @static */ public static function parseConnectionString($argumentName, $connectionString) { diff --git a/src/Common/Internal/ConnectionStringSource.php b/src/Common/Internal/ConnectionStringSource.php index f357b7f5b..0ba83ffe7 100644 --- a/src/Common/Internal/ConnectionStringSource.php +++ b/src/Common/Internal/ConnectionStringSource.php @@ -27,6 +27,7 @@ /** * Holder for default connection string sources used in CloudConfigurationManager. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal * @author Azure Storage PHP SDK @@ -36,21 +37,8 @@ */ class ConnectionStringSource { - /** - * The list of all sources which comes as default. - * - * @var type - */ private static $_defaultSources; - - /** - * @var boolean - */ private static $_isInitialized; - - /** - * Environment variable source name. - */ const ENVIRONMENT_SOURCE = 'environment_source'; /** diff --git a/src/Common/Internal/Http/HttpCallContext.php b/src/Common/Internal/Http/HttpCallContext.php index 6cbab7e16..bcea3dd03 100644 --- a/src/Common/Internal/Http/HttpCallContext.php +++ b/src/Common/Internal/Http/HttpCallContext.php @@ -31,6 +31,7 @@ /** * Holds basic elements for making HTTP call. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal\Http * @author Azure Storage PHP SDK @@ -40,65 +41,14 @@ */ class HttpCallContext { - /** - * The HTTP method used to make this call. - * - * @var string - */ private $_method; - - /** - * HTTP request headers. - * - * @var array - */ private $_headers; - - /** - * The URI query parameters. - * - * @var array - */ private $_queryParams; - - /** - * The HTTP POST parameters. - * - * @var array - */ private $_postParameters; - - /** - * @var string - */ private $_uri; - - /** - * The URI path. - * - * @var string - */ private $_path; - - /** - * The expected status codes. - * - * @var array - */ private $_statusCodes; - - /** - * The HTTP request body. - * - * @var string - */ private $_body; - - /** - * The request option this context will be sent with - * - * @var array - */ private $_requestOptions; /** diff --git a/src/Common/Internal/HttpFormatter.php b/src/Common/Internal/Http/HttpFormatter.php similarity index 74% rename from src/Common/Internal/HttpFormatter.php rename to src/Common/Internal/Http/HttpFormatter.php index adbbf77e3..bfb83dfdd 100644 --- a/src/Common/Internal/HttpFormatter.php +++ b/src/Common/Internal/Http/HttpFormatter.php @@ -14,15 +14,26 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common\Internal\Http * @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 */ -namespace MicrosoftAzure\Storage\Common\Internal; +namespace MicrosoftAzure\Storage\Common\Internal\Http; +/** + * Helper class to format the http headers + * + * @ignore + * @category Microsoft + * @package MicrosoftAzure\Storage\Common\Internal\Http + * @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 HttpFormatter { /** diff --git a/src/Common/Internal/Middlewares/CommonRequestMiddleware.php b/src/Common/Internal/Middlewares/CommonRequestMiddleware.php index 4ff878e47..f2621aa0a 100644 --- a/src/Common/Internal/Middlewares/CommonRequestMiddleware.php +++ b/src/Common/Internal/Middlewares/CommonRequestMiddleware.php @@ -24,7 +24,7 @@ namespace MicrosoftAzure\Storage\Common\Internal\Middlewares; -use MicrosoftAzure\Storage\Common\Internal\Middlewares\MiddlewareBase; +use MicrosoftAzure\Storage\Common\Middlewares\MiddlewareBase; use MicrosoftAzure\Storage\Common\Internal\Authentication\IAuthScheme; use MicrosoftAzure\Storage\Common\Internal\Resources; use Psr\Http\Message\RequestInterface; @@ -34,6 +34,7 @@ * and to sign the request with provided authentication scheme. This middleware * is by default applied to each of the request. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal * @author Azure Storage PHP SDK @@ -44,25 +45,9 @@ */ class CommonRequestMiddleware extends MiddlewareBase { - - /** - * @var MicrosoftAzure\Storage\Common\Internal\Authentication\IAuthScheme - */ private $authenticationScheme; - - /** - * @var array - */ private $headers; - - /** - * @var string - */ private $msVersion; - - /** - * @var string - */ private $userAgent; /** diff --git a/src/Common/Internal/Resources.php b/src/Common/Internal/Resources.php index 43614fed4..af855c5ce 100644 --- a/src/Common/Internal/Resources.php +++ b/src/Common/Internal/Resources.php @@ -27,6 +27,7 @@ /** * Project resources. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal * @author Azure Storage PHP SDK @@ -80,6 +81,7 @@ class Resources const BATCH_ENTITY_DEL_MSG = 'The entity was deleted successfully.'; const INVALID_PROP_VAL_MSG = "'%s' property value must satisfy %s."; const INVALID_PARAM_MSG = "The provided variable '%s' should be of type '%s'"; + const INVALID_VALUE_MSG = "The provided variable '%s' has unexpected value. Reason: '%s'"; const INVALID_STRING_LENGTH = "The provided variable '%s' should be of %s characters long"; const INVALID_BTE_MSG = "The blob block type must exist in %s"; const INVALID_BLOB_PAT_MSG = 'The provided access type is invalid.'; @@ -97,6 +99,7 @@ class Resources const INVALID_CONNECTION_STRING_SETTING_KEY = "The setting key '%s' is not found in the expected configuration setting keys:\n%s"; const INVALID_CERTIFICATE_PATH = "The provided certificate path '%s' is invalid."; const INSTANCE_TYPE_VALIDATION_MSG = 'The type of %s is %s but is expected to be %s.'; + const INVALID_MESSAGE_OBJECT_TO_SERIALIZE = 'The given object does not have required methods, so it could not be serialized.'; const MISSING_CONNECTION_STRING_CHAR = "Missing %s character"; const ERROR_PARSING_STRING = "'%s' at position %d."; const INVALID_CONNECTION_STRING = "Argument '%s' is not a valid connection string: '%s'"; @@ -122,9 +125,14 @@ class Resources const INVALID_NEGATIVE_PARAM = 'The provided parameter \'%s\' should be positive number.'; const SIGNED_SERVICE_INVALID_VALIDATION_MSG = 'The signed service should only be a combination of the letters b(lob) q(ueue) t(able) or f(ile).'; const SIGNED_RESOURCE_TYPE_INVALID_VALIDATION_MSG = 'The signed resource type should only be a combination of the letters s(ervice) c(container) or o(bject).'; - const SIGNED_PERMISSIONS_INVALID_VALIDATION_MSG = 'The signed permissions should only be a combination of the letters r, w, d, l, a, c, u, p.'; + const STRING_NOT_WITH_GIVEN_COMBINATION = 'The string should only be a combination of the letters %s.'; const SIGNED_PROTOCOL_INVALID_VALIDATION_MSG = 'The signed protocol is invalid: possible values are https or https,http.'; - + const ERROR_RESOURCE_TYPE_NOT_SUPPORTED = 'The given resource type cannot be recognized or is not supported.'; + const ERROR_TOO_MANY_SIGNED_IDENTIFIERS = 'There can be at most 5 signed identifiers at the same time.'; + const INVALID_PERMISSION_PROVIDED = 'Invalid permission provided, the permission of resource type \'%s\' can only be of \'%s\''; + const INVALID_RESOURCE_TYPE = 'Provided resource type is invalid.'; + const ERROR_KEY_NOT_EXIST = "The key '%s' does not exist in the given array."; + // HTTP Headers const X_MS_HEADER_PREFIX = 'x-ms-'; const X_MS_META_HEADER_PREFIX = 'x-ms-meta-'; @@ -143,6 +151,10 @@ class Resources const X_MS_BLOB_CONTENT_MD5 = 'x-ms-blob-content-md5'; const X_MS_BLOB_CACHE_CONTROL = 'x-ms-blob-cache-control'; const X_MS_BLOB_CONTENT_LENGTH = 'x-ms-blob-content-length'; + const X_MS_BLOB_CONDITION_MAXSIZE = 'x-ms-blob-condition-maxsize'; + const X_MS_BLOB_CONDITION_APPENDPOS = 'x-ms-blob-condition-appendpos'; + const X_MS_BLOB_APPEND_OFFSET = 'x-ms-blob-append-offset'; + const X_MS_BLOB_COMMITTED_BLOCK_COUNT = 'x-ms-blob-committed-block-count'; const X_MS_COPY_SOURCE = 'x-ms-copy-source'; const X_MS_RANGE = 'x-ms-range'; const X_MS_RANGE_GET_CONTENT_MD5 = 'x-ms-range-get-content-md5'; @@ -243,7 +255,7 @@ class Resources const DEAFULT_RETRY_INTERVAL = 1000;//Milliseconds // Header values - const SDK_VERSION = '0.13.0'; + const SDK_VERSION = '0.14.0'; const STORAGE_API_LATEST_VERSION = '2015-04-05'; const DATA_SERVICE_VERSION_VALUE = '1.0;NetFx'; const MAX_DATA_SERVICE_VERSION_VALUE = '2.0;NetFx'; @@ -303,90 +315,106 @@ class Resources const MULTIPART_MIXED_TYPE = 'multipart/mixed'; // Common used XML tags - const XTAG_ATTRIBUTES = '@attributes'; - const XTAG_NAMESPACE = '@namespace'; - const XTAG_LABEL = 'Label'; - const XTAG_NAME = 'Name'; - const XTAG_DESCRIPTION = 'Description'; - const XTAG_LOCATION = 'Location'; - const XTAG_AFFINITY_GROUP = 'AffinityGroup'; - const XTAG_HOSTED_SERVICES = 'HostedServices'; - const XTAG_STORAGE_SERVICES = 'StorageServices'; - const XTAG_STORAGE_SERVICE = 'StorageService'; - const XTAG_DISPLAY_NAME = 'DisplayName'; - const XTAG_SERVICE_NAME = 'ServiceName'; - const XTAG_URL = 'Url'; - const XTAG_ID = 'ID'; - const XTAG_STATUS = 'Status'; - const XTAG_HTTP_STATUS_CODE = 'HttpStatusCode'; - const XTAG_CODE = 'Code'; - const XTAG_MESSAGE = 'Message'; - const XTAG_STORAGE_SERVICE_PROPERTIES = 'StorageServiceProperties'; - const XTAG_SERVICE_ENDPOINT = 'ServiceEndpoint'; - const XTAG_ENDPOINT = 'Endpoint'; - const XTAG_ENDPOINTS = 'Endpoints'; - const XTAG_PRIMARY = 'Primary'; - const XTAG_SECONDARY = 'Secondary'; - const XTAG_KEY_TYPE = 'KeyType'; - const XTAG_STORAGE_SERVICE_KEYS = 'StorageServiceKeys'; - const XTAG_ERROR = 'Error'; - const XTAG_HOSTED_SERVICE = 'HostedService'; - const XTAG_HOSTED_SERVICE_PROPERTIES = 'HostedServiceProperties'; - const XTAG_CREATE_HOSTED_SERVICE = 'CreateHostedService'; + const XTAG_ATTRIBUTES = '@attributes'; + const XTAG_NAMESPACE = '@namespace'; + const XTAG_LABEL = 'Label'; + const XTAG_NAME = 'Name'; + const XTAG_DESCRIPTION = 'Description'; + const XTAG_LOCATION = 'Location'; + const XTAG_AFFINITY_GROUP = 'AffinityGroup'; + const XTAG_HOSTED_SERVICES = 'HostedServices'; + const XTAG_STORAGE_SERVICES = 'StorageServices'; + const XTAG_STORAGE_SERVICE = 'StorageService'; + const XTAG_DISPLAY_NAME = 'DisplayName'; + const XTAG_SERVICE_NAME = 'ServiceName'; + const XTAG_URL = 'Url'; + const XTAG_ID = 'ID'; + const XTAG_STATUS = 'Status'; + const XTAG_HTTP_STATUS_CODE = 'HttpStatusCode'; + const XTAG_CODE = 'Code'; + const XTAG_MESSAGE = 'Message'; + const XTAG_STORAGE_SERVICE_PROPERTIES = 'StorageServiceProperties'; + const XTAG_SERVICE_ENDPOINT = 'ServiceEndpoint'; + const XTAG_ENDPOINT = 'Endpoint'; + const XTAG_ENDPOINTS = 'Endpoints'; + const XTAG_PRIMARY = 'Primary'; + const XTAG_SECONDARY = 'Secondary'; + const XTAG_KEY_TYPE = 'KeyType'; + const XTAG_STORAGE_SERVICE_KEYS = 'StorageServiceKeys'; + const XTAG_ERROR = 'Error'; + const XTAG_HOSTED_SERVICE = 'HostedService'; + const XTAG_HOSTED_SERVICE_PROPERTIES = 'HostedServiceProperties'; + const XTAG_CREATE_HOSTED_SERVICE = 'CreateHostedService'; const XTAG_CREATE_STORAGE_SERVICE_INPUT = 'CreateStorageServiceInput'; const XTAG_UPDATE_STORAGE_SERVICE_INPUT = 'UpdateStorageServiceInput'; - const XTAG_CREATE_AFFINITY_GROUP = 'CreateAffinityGroup'; - const XTAG_UPDATE_AFFINITY_GROUP = 'UpdateAffinityGroup'; - const XTAG_UPDATE_HOSTED_SERVICE = 'UpdateHostedService'; - const XTAG_PACKAGE_URL = 'PackageUrl'; - const XTAG_CONFIGURATION = 'Configuration'; - const XTAG_START_DEPLOYMENT = 'StartDeployment'; - const XTAG_TREAT_WARNINGS_AS_ERROR = 'TreatWarningsAsError'; - const XTAG_CREATE_DEPLOYMENT = 'CreateDeployment'; - const XTAG_DEPLOYMENT_SLOT = 'DeploymentSlot'; - const XTAG_PRIVATE_ID = 'PrivateID'; - const XTAG_ROLE_INSTANCE_LIST = 'RoleInstanceList'; - const XTAG_UPGRADE_DOMAIN_COUNT = 'UpgradeDomainCount'; - const XTAG_ROLE_LIST = 'RoleList'; - const XTAG_SDK_VERSION = 'SdkVersion'; - const XTAG_INPUT_ENDPOINT_LIST = 'InputEndpointList'; - const XTAG_LOCKED = 'Locked'; - const XTAG_ROLLBACK_ALLOWED = 'RollbackAllowed'; - const XTAG_UPGRADE_STATUS = 'UpgradeStatus'; - const XTAG_UPGRADE_TYPE = 'UpgradeType'; + const XTAG_CREATE_AFFINITY_GROUP = 'CreateAffinityGroup'; + const XTAG_UPDATE_AFFINITY_GROUP = 'UpdateAffinityGroup'; + const XTAG_UPDATE_HOSTED_SERVICE = 'UpdateHostedService'; + const XTAG_PACKAGE_URL = 'PackageUrl'; + const XTAG_CONFIGURATION = 'Configuration'; + const XTAG_START_DEPLOYMENT = 'StartDeployment'; + const XTAG_TREAT_WARNINGS_AS_ERROR = 'TreatWarningsAsError'; + const XTAG_CREATE_DEPLOYMENT = 'CreateDeployment'; + const XTAG_DEPLOYMENT_SLOT = 'DeploymentSlot'; + const XTAG_PRIVATE_ID = 'PrivateID'; + const XTAG_ROLE_INSTANCE_LIST = 'RoleInstanceList'; + const XTAG_UPGRADE_DOMAIN_COUNT = 'UpgradeDomainCount'; + const XTAG_ROLE_LIST = 'RoleList'; + const XTAG_SDK_VERSION = 'SdkVersion'; + const XTAG_INPUT_ENDPOINT_LIST = 'InputEndpointList'; + const XTAG_LOCKED = 'Locked'; + const XTAG_ROLLBACK_ALLOWED = 'RollbackAllowed'; + const XTAG_UPGRADE_STATUS = 'UpgradeStatus'; + const XTAG_UPGRADE_TYPE = 'UpgradeType'; const XTAG_CURRENT_UPGRADE_DOMAIN_STATE = 'CurrentUpgradeDomainState'; - const XTAG_CURRENT_UPGRADE_DOMAIN = 'CurrentUpgradeDomain'; - const XTAG_ROLE_NAME = 'RoleName'; - const XTAG_INSTANCE_NAME = 'InstanceName'; - const XTAG_INSTANCE_STATUS = 'InstanceStatus'; - const XTAG_INSTANCE_UPGRADE_DOMAIN = 'InstanceUpgradeDomain'; - const XTAG_INSTANCE_FAULT_DOMAIN = 'InstanceFaultDomain'; - const XTAG_INSTANCE_SIZE = 'InstanceSize'; - const XTAG_INSTANCE_STATE_DETAILS = 'InstanceStateDetails'; - const XTAG_INSTANCE_ERROR_CODE = 'InstanceErrorCode'; - const XTAG_OS_VERSION = 'OsVersion'; - const XTAG_ROLE_INSTANCE = 'RoleInstance'; - const XTAG_ROLE = 'Role'; - const XTAG_INPUT_ENDPOINT = 'InputEndpoint'; - const XTAG_VIP = 'Vip'; - const XTAG_PORT = 'Port'; - const XTAG_DEPLOYMENT = 'Deployment'; - const XTAG_DEPLOYMENTS = 'Deployments'; - const XTAG_REGENERATE_KEYS = 'RegenerateKeys'; - const XTAG_SWAP = 'Swap'; - const XTAG_PRODUCTION = 'Production'; - const XTAG_SOURCE_DEPLOYMENT = 'SourceDeployment'; - const XTAG_CHANGE_CONFIGURATION = 'ChangeConfiguration'; - const XTAG_MODE = 'Mode'; - const XTAG_UPDATE_DEPLOYMENT_STATUS = 'UpdateDeploymentStatus'; - const XTAG_ROLE_TO_UPGRADE = 'RoleToUpgrade'; - const XTAG_FORCE = 'Force'; - const XTAG_UPGRADE_DEPLOYMENT = 'UpgradeDeployment'; - const XTAG_UPGRADE_DOMAIN = 'UpgradeDomain'; - const XTAG_WALK_UPGRADE_DOMAIN = 'WalkUpgradeDomain'; - const XTAG_ROLLBACK_UPDATE_OR_UPGRADE = 'RollbackUpdateOrUpgrade'; - const XTAG_CONTAINER_NAME = 'ContainerName'; - const XTAG_ACCOUNT_NAME = 'AccountName'; + const XTAG_CURRENT_UPGRADE_DOMAIN = 'CurrentUpgradeDomain'; + const XTAG_ROLE_NAME = 'RoleName'; + const XTAG_INSTANCE_NAME = 'InstanceName'; + const XTAG_INSTANCE_STATUS = 'InstanceStatus'; + const XTAG_INSTANCE_UPGRADE_DOMAIN = 'InstanceUpgradeDomain'; + const XTAG_INSTANCE_FAULT_DOMAIN = 'InstanceFaultDomain'; + const XTAG_INSTANCE_SIZE = 'InstanceSize'; + const XTAG_INSTANCE_STATE_DETAILS = 'InstanceStateDetails'; + const XTAG_INSTANCE_ERROR_CODE = 'InstanceErrorCode'; + const XTAG_OS_VERSION = 'OsVersion'; + const XTAG_ROLE_INSTANCE = 'RoleInstance'; + const XTAG_ROLE = 'Role'; + const XTAG_INPUT_ENDPOINT = 'InputEndpoint'; + const XTAG_VIP = 'Vip'; + const XTAG_PORT = 'Port'; + const XTAG_DEPLOYMENT = 'Deployment'; + const XTAG_DEPLOYMENTS = 'Deployments'; + const XTAG_REGENERATE_KEYS = 'RegenerateKeys'; + const XTAG_SWAP = 'Swap'; + const XTAG_PRODUCTION = 'Production'; + const XTAG_SOURCE_DEPLOYMENT = 'SourceDeployment'; + const XTAG_CHANGE_CONFIGURATION = 'ChangeConfiguration'; + const XTAG_MODE = 'Mode'; + const XTAG_UPDATE_DEPLOYMENT_STATUS = 'UpdateDeploymentStatus'; + const XTAG_ROLE_TO_UPGRADE = 'RoleToUpgrade'; + const XTAG_FORCE = 'Force'; + const XTAG_UPGRADE_DEPLOYMENT = 'UpgradeDeployment'; + const XTAG_UPGRADE_DOMAIN = 'UpgradeDomain'; + const XTAG_WALK_UPGRADE_DOMAIN = 'WalkUpgradeDomain'; + const XTAG_ROLLBACK_UPDATE_OR_UPGRADE = 'RollbackUpdateOrUpgrade'; + const XTAG_CONTAINER_NAME = 'ContainerName'; + const XTAG_ACCOUNT_NAME = 'AccountName'; + const XTAG_LOGGING = 'Logging'; + const XTAG_HOUR_METRICS = 'HourMetrics'; + const XTAG_CORS = 'Cors'; + const XTAG_CORS_RULE = 'CorsRule'; + const XTAG_ALLOWED_ORIGINS = 'AllowedOrigins'; + const XTAG_ALLOWED_METHODS = 'AllowedMethods'; + const XTAG_ALLOWED_HEADERS = 'AllowedHeaders'; + const XTAG_EXPOSED_HEADERS = 'ExposedHeaders'; + const XTAG_MAX_AGE_IN_SECONDS = 'MaxAgeInSeconds'; + const XTAG_SIGNED_IDENTIFIERS = 'SignedIdentifiers'; + const XTAG_SIGNED_IDENTIFIER = 'SignedIdentifier'; + const XTAG_ACCESS_POLICY = 'AccessPolicy'; + const XTAG_SIGNED_START = 'Start'; + const XTAG_SIGNED_EXPIRY = 'Expiry'; + const XTAG_SIGNED_PERMISSION = 'Permission'; + const XTAG_SIGNED_ID = 'Id'; // PHP URL Keys const PHP_URL_SCHEME = 'scheme'; @@ -406,5 +434,11 @@ class Resources const STATUS_PARTIAL_CONTENT = 206; const STATUS_MOVED_PERMANENTLY = 301; + // Resource Types + const RESOURCE_TYPE_BLOB = 'Blob'; + const RESOURCE_TYPE_CONTAINER = 'Container'; + const RESOURCE_TYPE_QUEUE = 'Queue'; + const RESOURCE_TYPE_TABLE = 'Table'; + // @codingStandardsIgnoreEnd } diff --git a/src/Common/Internal/RestProxy.php b/src/Common/Internal/RestProxy.php index 29a6e1f3e..7379e1ec5 100644 --- a/src/Common/Internal/RestProxy.php +++ b/src/Common/Internal/RestProxy.php @@ -14,6 +14,7 @@ * * PHP version 5 * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal * @author Azure Storage PHP SDK @@ -27,6 +28,7 @@ use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Validate; use MicrosoftAzure\Storage\Common\Internal\IMiddleware; +use MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware; /** * Base class for all REST proxies. @@ -66,6 +68,8 @@ public function __construct(Serialization\ISerializer $dataSerializer = null, $u $this->middlewares = array(); $this->dataSerializer = $dataSerializer; $this->_uri = $uri; + //For logging the request and responses. + // $this->middlewares[] = new HistoryMiddleware('.\\messages.log'); } /** diff --git a/src/Common/Internal/Serialization/ISerializer.php b/src/Common/Internal/Serialization/ISerializer.php index a39be6f5b..9999536c9 100644 --- a/src/Common/Internal/Serialization/ISerializer.php +++ b/src/Common/Internal/Serialization/ISerializer.php @@ -27,6 +27,7 @@ /** * The serialization interface. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal\Serialization * @author Azure Storage PHP SDK @@ -36,7 +37,6 @@ */ interface ISerializer { - /** * Serialize an object into a XML. * diff --git a/src/Common/Internal/Serialization/JsonSerializer.php b/src/Common/Internal/Serialization/JsonSerializer.php index 231db746d..4fd731b0f 100644 --- a/src/Common/Internal/Serialization/JsonSerializer.php +++ b/src/Common/Internal/Serialization/JsonSerializer.php @@ -29,6 +29,7 @@ /** * Perform JSON serialization / deserialization * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal\Serialization * @author Azure Storage PHP SDK diff --git a/src/Common/Internal/Serialization/MessageSerializer.php b/src/Common/Internal/Serialization/MessageSerializer.php new file mode 100644 index 000000000..c942b42f0 --- /dev/null +++ b/src/Common/Internal/Serialization/MessageSerializer.php @@ -0,0 +1,179 @@ + + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ + +namespace MicrosoftAzure\Storage\Common\Internal\Serialization; + +use MicrosoftAzure\Storage\Common\Internal\Validate; +use MicrosoftAzure\Storage\Common\Internal\Resources; +use MicrosoftAzure\Storage\Common\Internal\Serialization\XMLSerializer; +use GuzzleHttp\Exception\RequestException; + +/** + * Provides functionality to serialize a message to a string. + * + * @ignore + * @category Microsoft + * @package MicrosoftAzure\Storage\Common\Internal\Serialization + * @author Azure Storage PHP SDK + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +class MessageSerializer +{ + /** + * Serialize a message to a string. The message object must be either a type + * of \Exception, or have following methods implemented. + * getHeaders() + * getProtocolVersion() + * (getUri() && getMethod()) || (getStatusCode() && getReasonPhrase()) + * + * @param object $message The message to be serialized. + * + * @return string + */ + public static function objectSerialize($targetObject) + { + //if the object is of exception type, serialize it using the methods + //without checking the methods. + if ($targetObject instanceof RequestException) { + return self::serializeRequestException($targetObject); + } elseif ($targetObject instanceof \Exception) { + return self::serializeException($targetObject); + } + + Validate::methodExists($targetObject, 'getHeaders', 'targetObject'); + Validate::methodExists($targetObject, 'getProtocolVersion', 'targetObject'); + + // Serialize according to the implemented method. + if (method_exists($targetObject, 'getUri') && + method_exists($targetObject, 'getMethod')) { + return self::serializeRequest($targetObject); + } elseif (method_exists($targetObject, 'getStatusCode') && + method_exists($targetObject, 'getReasonPhrase')) { + return self::serializeResponse($targetObject); + } else { + throw new \InvalidArgumentException( + Resources::INVALID_MESSAGE_OBJECT_TO_SERIALIZE + ); + } + } + + /** + * Serialize the request type that implemented the following methods: + * getHeaders() + * getProtocolVersion() + * getUri() + * getMethod() + * + * @param object $request The request to be serialized. + * + * @return string + */ + private static function serializeRequest($request) + { + $headers = $request->getHeaders(); + $version = $request->getProtocolVersion(); + $uri = $request->getUri(); + $method = $request->getMethod(); + + $resultString = "Request:\n"; + $resultString .= "URI: {$uri}\nHTTP Version: {$version}\nMethod: {$method}\n"; + $resultString .= self::serializeHeaders($headers); + + return $resultString; + } + + /** + * Serialize the response type that implemented the following methods: + * getHeaders() + * getProtocolVersion() + * getStatusCode() + * getReasonPhrase() + * + * @param object $response The response to be serialized + * + * @return string + */ + private static function serializeResponse($response) + { + $headers = $response->getHeaders(); + $version = $response->getProtocolVersion(); + $status = $response->getStatusCode(); + $reason = $response->getReasonPhrase(); + + $resultString = "Response:\n"; + $resultString .= "Status Code: {$status}\nReason: {$reason}\n"; + $resultString .= "HTTP Version: {$version}\n"; + $resultString .= self::serializeHeaders($headers); + + return $resultString; + } + + /** + * Serialize the message headers. + * + * @param array $headers The headers to be serialized. + * + * @return string + */ + private static function serializeHeaders(array $headers) + { + $resultString = "Headers:\n"; + foreach ($headers as $key => $value) { + $resultString .= sprintf("%s: %s\n", $key, $value[0]); + } + + return $resultString; + } + + /** + * Serialize the request exception. + * + * @param RequestException $e the request exception to be serialized. + * + * @return string + */ + private static function serializeRequestException(RequestException $e) + { + $resultString = sprintf("Reason:\n%s\n", $e); + if ($e->hasResponse()) { + $resultString .= self::serializeResponse($e->getResponse()); + } + + return $resultString; + } + + /** + * Serialize the general exception + * + * @param \Exception $e general exception to be serialized. + * + * @return string + */ + private static function serializeException(\Exception $e) + { + return sprintf("Reason:\n%s\n", $e); + } +} diff --git a/src/Common/Internal/Serialization/XmlSerializer.php b/src/Common/Internal/Serialization/XmlSerializer.php index 0ac5a8778..54c26f470 100644 --- a/src/Common/Internal/Serialization/XmlSerializer.php +++ b/src/Common/Internal/Serialization/XmlSerializer.php @@ -31,6 +31,7 @@ /** * Short description * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal\Serialization * @author Azure Storage PHP SDK diff --git a/src/Common/ServiceOptionsBase.php b/src/Common/Internal/ServiceOptionsBase.php similarity index 79% rename from src/Common/ServiceOptionsBase.php rename to src/Common/Internal/ServiceOptionsBase.php index b11551873..a1f418cf5 100644 --- a/src/Common/ServiceOptionsBase.php +++ b/src/Common/Internal/ServiceOptionsBase.php @@ -22,12 +22,13 @@ * @link https://github.com/azure/azure-storage-php */ -namespace MicrosoftAzure\Storage\Common; +namespace MicrosoftAzure\Storage\Common\Internal; /** * This class provides the base structure of service options, granting user to * send with different options for each individual API call. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal * @author Azure Storage PHP SDK @@ -39,17 +40,19 @@ class ServiceOptionsBase { /** - * @var array + * The request options + * @internal */ protected $requestOptions; - + /** - * @var string + * The getTimeout + * @internal */ protected $timeout; /** - * Gets timeout. + * Gets the timeout value * * @return string */ @@ -87,6 +90,15 @@ public function getRequestOptions() * Sets the request options * * @param array $requestOptions the request options to be set. + * it accepts the following + * options: + * - number_of_concurrency: integer the number of concurrency for upload/download APIs + * - handler: GuzzleHttp\HandlerStack the guzzle handler stack. refer to + * http://docs.guzzlephp.org/en/latest/handlers-and-middleware.html#handlerstack + * for detailed information + * - 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 * * @return void */ diff --git a/src/Common/Internal/ServiceRestProxy.php b/src/Common/Internal/ServiceRestProxy.php index 5d27558ad..6511f1e48 100644 --- a/src/Common/Internal/ServiceRestProxy.php +++ b/src/Common/Internal/ServiceRestProxy.php @@ -24,7 +24,7 @@ namespace MicrosoftAzure\Storage\Common\Internal; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Validate; use MicrosoftAzure\Storage\Common\Internal\Utilities; @@ -46,6 +46,7 @@ /** * Base class for all services rest proxies. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal * @author Azure Storage PHP SDK @@ -55,20 +56,8 @@ */ class ServiceRestProxy extends RestProxy { - /** - * @var string - */ private $_accountName; - - /** - * - * @var \Uri - */ private $_psrUri; - - /** - * @var array - */ private $_options; /** @@ -108,7 +97,7 @@ public function getAccountName() } /** - * Static helper function to create a usable client for the proxy. + * Helper function to create a usable client for the proxy. * The requestOptions can contain the following keys that will affect * the way retry handler is created and applied. * handler: HandlerStack, if set, this function will not @@ -124,6 +113,7 @@ protected function createClient(array $requestOptions) return (new \GuzzleHttp\Client( array_merge( + $requestOptions, $this->_options['http'], array( "defaults" => array( @@ -135,8 +125,7 @@ protected function createClient(array $requestOptions) 'verify' => true, // For testing with Fiddler //'proxy' => "localhost:8888", - ), - $requestOptions + ) ) )); } @@ -433,8 +422,6 @@ protected function sendContextAsync(HttpCallContext $context) * * @return void * - * @static - * * @throws ServiceException */ public static function throwIfError(ResponseInterface $response, $expected) diff --git a/src/Common/Internal/ServiceSettings.php b/src/Common/Internal/ServiceSettings.php index eecea2bd2..9c373ff04 100644 --- a/src/Common/Internal/ServiceSettings.php +++ b/src/Common/Internal/ServiceSettings.php @@ -14,6 +14,7 @@ * * PHP version 5 * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal * @author Azure Storage PHP SDK @@ -81,12 +82,12 @@ protected static function parseAndValidateKeys($connectionString) static::init(); static::$isInitialized = true; } - + $tokenizedSettings = ConnectionStringParser::parseConnectionString( 'connectionString', $connectionString ); - + // Assure that all given keys are valid. foreach ($tokenizedSettings as $key => $value) { if (!Utilities::inArrayInsensitive($key, static::$validSettingKeys)) { diff --git a/src/Common/Internal/StorageServiceSettings.php b/src/Common/Internal/StorageServiceSettings.php index 420945a98..6a2f2cec9 100644 --- a/src/Common/Internal/StorageServiceSettings.php +++ b/src/Common/Internal/StorageServiceSettings.php @@ -32,6 +32,7 @@ * service. For more information about storage service connection strings check this * page: http://msdn.microsoft.com/en-us/library/ee758697 * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal * @author Azure Storage PHP SDK @@ -41,126 +42,33 @@ */ class StorageServiceSettings extends ServiceSettings { - /** - * The storage service name. - * - * @var string - */ private $_name; - - /** - * A base64 representation. - * - * @var string - */ private $_key; - - /** - * The SAS token. - * - * @var string - */ private $_sas; - - /** - * The endpoint for the blob service. - * - * @var string - */ private $_blobEndpointUri; - - /** - * The endpoint for the queue service. - * - * @var string - */ private $_queueEndpointUri; - - /** - * The endpoint for the table service. - * - * @var string - */ private $_tableEndpointUri; - - /** - * @var StorageServiceSettings - */ + private static $_devStoreAccount; - - /** - * Validator for the UseDevelopmentStorage setting. Must be "true". - * - * @var array - */ private static $_useDevelopmentStorageSetting; - - /** - * Validator for the DevelopmentStorageProxyUri setting. Must be a valid Uri. - * - * @var array - */ private static $_developmentStorageProxyUriSetting; - - /** - * Validator for the DefaultEndpointsProtocol setting. Must be either "http" - * or "https". - * - * @var array - */ private static $_defaultEndpointsProtocolSetting; - - /** - * Validator for the AccountName setting. No restrictions. - * - * @var array - */ private static $_accountNameSetting; - - /** - * Validator for the AccountKey setting. Must be a valid base64 string. - * - * @var array - */ private static $_accountKeySetting; - - /** - * Validator for the SharedAccessSignature setting. Must be a valid URI query. - * - * @var array - */ private static $_sasTokenSetting; - - /** - * Validator for the BlobEndpoint setting. Must be a valid Uri. - * - * @var array - */ private static $_blobEndpointSetting; - - /** - * Validator for the QueueEndpoint setting. Must be a valid Uri. - * - * @var array - */ private static $_queueEndpointSetting; - - /** - * Validator for the TableEndpoint setting. Must be a valid Uri. - * - * @var array - */ private static $_tableEndpointSetting; - + /** - * @var boolean + * If initialized or not + * @internal */ protected static $isInitialized = false; /** - * Holds the expected setting keys. - * - * @var array + * Valid setting keys + * @internal */ protected static $validSettingKeys = array(); diff --git a/src/Common/Internal/Utilities.php b/src/Common/Internal/Utilities.php index f0de3112d..8f16d3ee2 100644 --- a/src/Common/Internal/Utilities.php +++ b/src/Common/Internal/Utilities.php @@ -14,6 +14,7 @@ * * PHP version 5 * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal * @author Azure Storage PHP SDK @@ -46,8 +47,6 @@ class Utilities * @param mixed $key The array key. * @param mixed $default The value to return if $key is not found in $array. * - * @static - * * @return mixed */ public static function tryGetValue($array, $key, $default = null) @@ -63,8 +62,6 @@ public static function tryGetValue($array, $key, $default = null) * @param string $url The URL. * @param string $scheme The scheme. By default HTTP * - * @static - * * @return string */ public static function tryAddUrlScheme($url, $scheme = 'http') @@ -83,8 +80,6 @@ public static function tryAddUrlScheme($url, $scheme = 'http') * * @param string $url The endpoint $url * - * @static - * * @return string */ public static function tryParseAccountNameFromUrl($url) @@ -103,8 +98,6 @@ public static function tryParseAccountNameFromUrl($url) * @param string $key The index name. * @param array $array The array object. * - * @static - * * @return array */ public static function tryGetArray($key, array $array) @@ -122,8 +115,6 @@ public static function tryGetArray($key, array $array) * @param string $value The value. * @param array &$array The array. If NULL will be used as array. * - * @static - * * @return void */ public static function addIfNotEmpty($key, $value, array &$array) @@ -143,8 +134,6 @@ public static function addIfNotEmpty($key, $value, array &$array) * * @param array $array Array to be used. * - * @static - * * @return mixed */ public static function tryGetKeysChainValue(array $array) @@ -176,8 +165,6 @@ public static function tryGetKeysChainValue(array $array) * @param boolean $ignoreCase true to ignore case during the comparison; * otherwise, false * - * @static - * * @return boolean */ public static function startsWith($string, $prefix, $ignoreCase = false) @@ -194,8 +181,6 @@ public static function startsWith($string, $prefix, $ignoreCase = false) * * @param array $var item to group * - * @static - * * @return array */ public static function getArray(array $var) @@ -222,8 +207,6 @@ public static function getArray(array $var) * * @param string $xml XML to be parsed. * - * @static - * * @return array */ public static function unserialize($xml) @@ -240,8 +223,6 @@ public static function unserialize($xml) * @param string $sxml SimpleXML object * @param array $arr Array into which to store results * - * @static - * * @return array */ private static function _sxml2arr($sxml, array $arr = null) @@ -266,8 +247,6 @@ private static function _sxml2arr($sxml, array $arr = null) * @param string $defaultTag default tag for non-tagged elements. * @param string $standalone adds 'standalone' header tag, values 'yes'/'no' * - * @static - * * @return string */ public static function serialize( @@ -304,8 +283,6 @@ public static function serialize( * @param array $data Array to be converted to XML * @param string $defaultTag Default XML tag to be used if none specified. * - * @static - * * @return void */ private static function _arr2xml( @@ -344,8 +321,6 @@ private static function _arr2xml( * * @param string $obj boolean value in string format. * - * @static - * * @return bool */ public static function toBoolean($obj) @@ -358,8 +333,6 @@ public static function toBoolean($obj) * * @param bool $obj boolean value to convert. * - * @static - * * @return string */ public static function booleanToString($obj) @@ -372,8 +345,6 @@ public static function booleanToString($obj) * * @param string $date windows azure date ins string represntation. * - * @static - * * @return \DateTime */ public static function rfc1123ToDateTime($date) @@ -390,8 +361,6 @@ public static function rfc1123ToDateTime($date) * @param int $timestamp The unix timestamp to convert * (for DateTime check date_timestamp_get). * - * @static - * * @return string */ public static function isoDate($timestamp = null) @@ -418,8 +387,6 @@ public static function isoDate($timestamp = null) * * @param mixed $value The datetime value. * - * @static - * * @return string */ public static function convertToEdmDateTime($value) @@ -444,8 +411,6 @@ public static function convertToEdmDateTime($value) * * @param string $value The string value to parse. * - * @static - * * @return \DateTime */ public static function convertToDateTime($value) @@ -466,8 +431,6 @@ public static function convertToDateTime($value) * * @param string $string The string contents. * - * @static - * * @return resource */ public static function stringToStream($string) @@ -503,8 +466,6 @@ public static function orderArray(array $array, array $order) * @param string $needle The searched value. * @param array $haystack The array. * - * @static - * * @return boolean */ public static function inArrayInsensitive($needle, array $haystack) @@ -519,8 +480,6 @@ public static function inArrayInsensitive($needle, array $haystack) * @param string $key The value to check. * @param array $search The array with keys to check. * - * @static - * * @return boolean */ public static function arrayKeyExistsInsensitive($key, array $search) @@ -537,8 +496,6 @@ public static function arrayKeyExistsInsensitive($key, array $search) * @param array $haystack The array to be used. * @param mixed $default The value to return if $key is not found in $array. * - * @static - * * @return mixed */ public static function tryGetValueInsensitive($key, $haystack, $default = null) @@ -558,8 +515,6 @@ public static function tryGetValueInsensitive($key, $haystack, $default = null) * Note: This function is available on all platforms, while the * com_create_guid() is only available for Windows. * - * @static - * * @return string A new GUID. */ public static function getGuid() @@ -593,8 +548,6 @@ public static function getGuid() * @param array $parsed The object in array representation * @param string $class The class name. Must have static method create. * - * @static - * * @return array */ public static function createInstanceList(array $parsed, $class) @@ -616,8 +569,6 @@ public static function createInstanceList(array $parsed, $class) * @param boolean $ignoreCase Set true to ignore case during the comparison; * otherwise, false * - * @static - * * @return boolean */ public static function endsWith($haystack, $needle, $ignoreCase = false) @@ -840,6 +791,7 @@ public static function validateMetadata(array $metadata = null) * Append the content to file. * @param string $path The file to append to. * @param string $content The content to append. + * * @return void */ public static function appendToFile($path, $content) @@ -850,4 +802,22 @@ public static function appendToFile($path, $content) fclose($resource); } } + + /** + * Check if all the bytes are zero. + * @param string $content The content. + */ + public static function allZero($content) + { + $size = strlen($content); + + // If all Zero, skip this range + for ($i = 0; $i < $size; $i++) { + if (ord($content[$i] != 0)) { + return false; + } + } + + return true; + } } diff --git a/src/Common/Internal/Validate.php b/src/Common/Internal/Validate.php index 2083d0a86..e0cf6153d 100644 --- a/src/Common/Internal/Validate.php +++ b/src/Common/Internal/Validate.php @@ -14,6 +14,7 @@ * * PHP version 5 * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Common\Internal * @author Azure Storage PHP SDK @@ -24,7 +25,7 @@ namespace MicrosoftAzure\Storage\Common\Internal; -use MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException; +use MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException; use MicrosoftAzure\Storage\Common\Internal\Resources; /** @@ -390,4 +391,33 @@ public static function isDateString($value, $name) ); } } + + /** + * Validate if the provided array has key, throw exception otherwise. + * + * @param string $key The key to be searched. + * @param string $name The name of the array. + * @param array $array The array to be validated. + * + * @throws \UnexpectedValueException + * @throws \InvalidArgumentException + * + * @return boolean + */ + public static function hasKey($key, $name, array $array) + { + Validate::isArray($array, $name); + + if (!array_key_exists($key, $array)) { + throw new \UnexpectedValueException( + sprintf( + Resources::INVALID_VALUE_MSG, + $name, + sprintf(Resources::ERROR_KEY_NOT_EXIST, $key) + ) + ); + } + + return true; + } } diff --git a/src/Common/Internal/Logger.php b/src/Common/Logger.php similarity index 90% rename from src/Common/Internal/Logger.php rename to src/Common/Logger.php index d7ca1510c..96f06e9d6 100644 --- a/src/Common/Internal/Logger.php +++ b/src/Common/Logger.php @@ -15,20 +15,20 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @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 */ -namespace MicrosoftAzure\Storage\Common\Internal; +namespace MicrosoftAzure\Storage\Common; /** * Logger class for debugging purpose. * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common * @author Azure Storage PHP SDK * @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -47,8 +47,6 @@ class Logger * @param mixed $var The data to log. * @param string $tip The help message. * - * @static - * * @return void */ public static function log($var, $tip = Resources::EMPTY_STRING) @@ -68,9 +66,6 @@ public static function log($var, $tip = Resources::EMPTY_STRING) * Sets file path to use. * * @param string $filePath The log file path. - * - * @static - * * @return void */ public static function setLogFile($filePath) diff --git a/src/Common/Internal/Middlewares/HistoryMiddleware.php b/src/Common/Middlewares/HistoryMiddleware.php similarity index 59% rename from src/Common/Internal/Middlewares/HistoryMiddleware.php rename to src/Common/Middlewares/HistoryMiddleware.php index 74806ac70..b3e4ae29a 100644 --- a/src/Common/Internal/Middlewares/HistoryMiddleware.php +++ b/src/Common/Middlewares/HistoryMiddleware.php @@ -15,43 +15,44 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE * @link https://github.com/azure/azure-storage-php */ -namespace MicrosoftAzure\Storage\Common\Internal\Middlewares; +namespace MicrosoftAzure\Storage\Common\Middlewares; use MicrosoftAzure\Storage\Common\Internal\Validate; +use MicrosoftAzure\Storage\Common\Internal\Utilities; +use MicrosoftAzure\Storage\Common\Internal\Serialization\MessageSerializer; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use GuzzleHttp\Promise\RejectedPromise; /** * This class provides the functionality to log the requests/options/responses. - * Logging large number of entries may exhaust the memory. + * Logging large number of entries without providing a file path may exhaust + * the memory. * * The middleware should be pushed into client options if the logging is * intended to persist between different API calls. * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE - * @version Release: 0.12.1 * @link https://github.com/azure/azure-storage-php */ class HistoryMiddleware extends MiddlewareBase { - /** - * The history of all the request/response pairs or request/reason pairs - * - * @var array - */ private $history; + private $path; + private $count; + + const TITLE_LENGTH = 120; /** * Gets the saved paried history. @@ -65,10 +66,18 @@ public function getHistory() /** * Constructor + * + * @param string $path the path to save the history. If path is provided, + * no data is going to be saved to memory and the + * entries are going to be serialized and saved to given + * path. + * */ - public function __construct() + public function __construct($path = '') { - $history = array(); + $this->history = array(); + $this->path = $path; + $this->count = 0; } /** @@ -78,14 +87,19 @@ public function __construct() */ public function addHistory(array $entry) { - Validate::isTrue( - array_key_exists('request', $entry) && - array_key_exists('options', $entry) && - (array_key_exists('response', $entry) || - array_key_exists('reason', $entry)), - 'Given history entry not in correct format' - ); - $this->history[] = $entry; + if ($this->path !== '') { + $this->appendNewEntryToPath($entry); + } else { + Validate::isTrue( + array_key_exists('request', $entry) && + array_key_exists('options', $entry) && + (array_key_exists('response', $entry) || + array_key_exists('reason', $entry)), + 'Given history entry not in correct format' + ); + $this->history[] = $entry; + } + ++$this->count; } /** @@ -96,6 +110,7 @@ public function addHistory(array $entry) public function clearHistory() { $this->history = array(); + $this->count = 0; } /** @@ -149,4 +164,37 @@ protected function onRejected(RequestInterface $request, array $options) return new RejectedPromise($reason); }; } + + /** + * Append the new entry to saved file path. + * + * @param array $entry the entry to be added. + * + * @return void + */ + private function appendNewEntryToPath(array $entry) + { + $entryNoString = "Entry " . $this->count; + $delimiter = str_pad( + $entryNoString, + self::TITLE_LENGTH, + '-', + STR_PAD_BOTH + ) . PHP_EOL; + $entryString = $delimiter; + $entryString .= sprintf( + "Time: %s\n", + (new \DateTime("now", new \DateTimeZone('UTC')))->format('Y-m-d H:i:s') + ); + $entryString .= MessageSerializer::objectSerialize($entry['request']); + if (array_key_exists('reason', $entry)) { + $entryString .= MessageSerializer::objectSerialize($entry['reason']); + } elseif (array_key_exists('response', $entry)) { + $entryString .= MessageSerializer::objectSerialize($entry['response']); + } + + $entryString .= $delimiter; + + Utilities::appendToFile($this->path, $entryString); + } } diff --git a/src/Common/Internal/IMiddleware.php b/src/Common/Middlewares/IMiddleware.php similarity index 64% rename from src/Common/Internal/IMiddleware.php rename to src/Common/Middlewares/IMiddleware.php index dafff3989..b4b3909cf 100644 --- a/src/Common/Internal/IMiddleware.php +++ b/src/Common/Middlewares/IMiddleware.php @@ -15,21 +15,21 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE * @link https://github.com/azure/azure-storage-php */ -namespace MicrosoftAzure\Storage\Common\Internal; +namespace MicrosoftAzure\Storage\Common\Middlewares; /** * IMiddleware is called before sending the request and after receiving the * response. * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -42,29 +42,30 @@ interface IMiddleware * This function will return a callable with $request and $options as * its parameters and returns a promise. The callable can modify the * request, fulfilled response or rejected reason when invoked with certain - * conditions. + * conditions. Sample middleware implementation: + * + * ``` + * return function ( + * RequestInterface $request, + * array $options + * ) use ($handler) { + * //do something prior to sending the request. + * $promise = $handler($request, $options); + * return $promise->then( + * function (ResponseInterface $response) use ($request, $options) { + * //do something + * return $response; + * }, + * function ($reason) use ($request, $options) { + * //do something + * return new GuzzleHttp\Promise\RejectedPromise($reason); + * } + * ); + * }; + * ``` * * @param callable $handler The next handler. * @return callable */ public function __invoke(callable $handler); - /* - return function ( - RequestInterface $request, - array $options - ) use ($handler) { - //do something prior to sending the request. - $promise = $handler($request, $options); - return $promise->then( - function (ResponseInterface $response) use ($request, $options) { - //do something - return $response; - }, - function ($reason) use ($request, $options) { - //do something - return new GuzzleHttp\Promise\RejectedPromise($reason); - } - ); - }; - */ } diff --git a/src/Common/Internal/Middlewares/MiddlewareBase.php b/src/Common/Middlewares/MiddlewareBase.php similarity index 83% rename from src/Common/Internal/Middlewares/MiddlewareBase.php rename to src/Common/Middlewares/MiddlewareBase.php index d766f1c86..f1da38abd 100644 --- a/src/Common/Internal/Middlewares/MiddlewareBase.php +++ b/src/Common/Middlewares/MiddlewareBase.php @@ -15,19 +15,18 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE * @link https://github.com/azure/azure-storage-php */ -namespace MicrosoftAzure\Storage\Common\Internal\Middlewares; +namespace MicrosoftAzure\Storage\Common\Middlewares; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use GuzzleHttp\Promise\RejectedPromise; -use MicrosoftAzure\Storage\Common\Internal\IMiddleware; /** * This class provides the base structure of middleware that can be used for @@ -35,7 +34,7 @@ * other behaviors like logging, retrying and debugging. * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -45,6 +44,17 @@ class MiddlewareBase implements IMiddleware { + /** + * Middleware augments the functionality of handlers by invoking them + * in the process of generating responses. And it returns a function + * that accepts the next handler to invoke. Refer to + * http://docs.guzzlephp.org/en/latest/handlers-and-middleware.html#middleware + * for more detailed information. + * + * @param callable The handler function. + * + * @return callable The function that accepts the next handler to invoke. + */ final public function __invoke(callable $handler) { $reflection = $this; diff --git a/src/Common/Internal/RetryMiddlewareFactory.php b/src/Common/Middlewares/RetryMiddlewareFactory.php similarity index 98% rename from src/Common/Internal/RetryMiddlewareFactory.php rename to src/Common/Middlewares/RetryMiddlewareFactory.php index 2e8d24804..11c30c3ae 100644 --- a/src/Common/Internal/RetryMiddlewareFactory.php +++ b/src/Common/Middlewares/RetryMiddlewareFactory.php @@ -15,14 +15,14 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common\Middlewares * @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 */ -namespace MicrosoftAzure\Storage\Common\Internal; +namespace MicrosoftAzure\Storage\Common\Middlewares; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Validate; @@ -34,7 +34,7 @@ * HTTP clients to handle retry policy. * * @category Microsoft - * @package MicrosoftAzure\Storage\Common\Internal + * @package MicrosoftAzure\Storage\Common\Middlewares * @author Azure Storage PHP SDK * @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE diff --git a/src/Common/Models/AccessPolicy.php b/src/Common/Models/AccessPolicy.php new file mode 100644 index 000000000..536f4f623 --- /dev/null +++ b/src/Common/Models/AccessPolicy.php @@ -0,0 +1,227 @@ + + * @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\Models; + +use MicrosoftAzure\Storage\Common\Internal\Utilities; +use MicrosoftAzure\Storage\Common\Internal\Validate; +use MicrosoftAzure\Storage\Common\Internal\Resources; + +/** + * Holds access policy elements + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Common\Models + * @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 AccessPolicy +{ + private $start; + private $expiry; + private $permission; + private $resourceType; + + /** + * Get the valid permissions for the given resource. + * This is not a constant array due to PHP does not support constant array + * until 5.6 + * + * @return array + */ + private static function getResourceValidPermissions() + { + return [ + Resources::RESOURCE_TYPE_BLOB => ['r', 'a', 'c', 'w', 'd'], + Resources::RESOURCE_TYPE_CONTAINER => ['r', 'a', 'c', 'w', 'd', 'l'], + Resources::RESOURCE_TYPE_QUEUE => ['r', 'a', 'u', 'p'], + Resources::RESOURCE_TYPE_TABLE => ['r', 'a', 'u', 'd'] + ]; + } + + /** + * Constructor + * + * @param string $resourceType the resource type of this access policy. + */ + public function __construct($resourceType = Resources::RESOURCE_TYPE_BLOB) + { + Validate::isString($resourceType, 'resourceType'); + Validate::isTrue( + $resourceType == Resources::RESOURCE_TYPE_BLOB || + $resourceType == Resources::RESOURCE_TYPE_CONTAINER || + $resourceType == Resources::RESOURCE_TYPE_QUEUE || + $resourceType == Resources::RESOURCE_TYPE_TABLE, + Resources::ERROR_RESOURCE_TYPE_NOT_SUPPORTED + ); + + $this->resourceType = $resourceType; + } + + /** + * Gets start. + * + * @return \DateTime. + */ + public function getStart() + { + return $this->start; + } + + /** + * Sets start. + * + * @param \DateTime $start value. + * + * @return void + */ + public function setStart(\DateTime $start = null) + { + if ($start != null) { + Validate::isDate($start); + } + $this->start = $start; + } + + /** + * Gets expiry. + * + * @return \DateTime. + */ + public function getExpiry() + { + return $this->expiry; + } + + /** + * Sets expiry. + * + * @param \DateTime $expiry value. + * + * @return void + */ + public function setExpiry($expiry) + { + Validate::isDate($expiry); + $this->expiry = $expiry; + } + + /** + * Gets permission. + * + * @return string. + */ + public function getPermission() + { + return $this->permission; + } + + /** + * Sets permission. + * + * @param string $permission value. + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPermission($permission) + { + $this->permission = $this->validatePermission($permission); + } + + /** + * Gets resource type. + * + * @return string. + */ + public function getResourceType() + { + return $this->resourceType; + } + + /** + * Validate the permission against its corresponding allowed permissions + * + * @param string $permission The permission to be validated. + * + * @throws \InvalidArgumentException + * + * @return string + */ + private function validatePermission($permission) + { + $validPermissions = + self::getResourceValidPermissions()[$this->getResourceType()]; + $result = ''; + foreach ($validPermissions as $validPermission) { + if (strpos($permission, $validPermission) !== false) { + //append the valid permission to result. + $result .= $validPermission; + //remove all the character that represents the permission. + $permission = str_replace( + $validPermission, + '', + $permission + ); + } + } + //After filtering all the permissions, if there is still characters + //left in the given permission, throw exception. + Validate::isTrue( + $permission == '', + sprintf( + Resources::INVALID_PERMISSION_PROVIDED, + $this->getResourceType(), + implode(', ', $validPermissions) + ) + ); + + return $result; + } + + /** + * Converts this current object to XML representation. + * + * @internal + * + * @return array + */ + public function toArray() + { + $array = array(); + + if ($this->getStart() != null) { + $array[Resources::XTAG_SIGNED_START] = + Utilities::convertToEdmDateTime($this->getStart()); + } + $array[Resources::XTAG_SIGNED_EXPIRY] = + Utilities::convertToEdmDateTime($this->getExpiry()); + $array[Resources::XTAG_SIGNED_PERMISSION] = $this->getPermission(); + + return $array; + } +} diff --git a/src/Common/Models/CORS.php b/src/Common/Models/CORS.php new file mode 100644 index 000000000..3d23bdb62 --- /dev/null +++ b/src/Common/Models/CORS.php @@ -0,0 +1,270 @@ + + * @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\Models; + +use MicrosoftAzure\Storage\Common\Internal\Utilities; +use MicrosoftAzure\Storage\Common\Internal\Resources; +use MicrosoftAzure\Storage\Common\Internal\Validate; + +/** + * Provides functionality and data structure for Cross-Origin Resource Sharing + * rules. + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Common\Models + * @author Azure Storage PHP SDK + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +class CORS +{ + private $allowedOrigins; + private $allowedMethods; + private $allowedHeaders; + private $exposedHeaders; + private $maxAgeInSeconds; + + /** + * Constructor of the class. + * + * @param string[] $allowedOrigins The origin domains that are permitted + * to make request against the storage + * service via CORS. + * @param string[] $allowedMethods The methods (HTTP request verbs) that + * the origin domain may use for a CORS + * request. + * @param string[] $allowedHeaders The request headers that the origin + * domain may specify on the CORS request. + * @param string[] $exposedHeaders The response headers that may be sent in + * the response to the CORS request and + * exposed by the browser to the request + * issuer. + * @param int $maxAgeInSeconds The maximum amount of time that a + * browser should cache the preflight + * OPTIONS request. + */ + public function __construct( + array $allowedOrigins, + array $allowedMethods, + array $allowedHeaders, + array $exposedHeaders, + $maxAgeInSeconds + ) { + $this->setAllowedOrigins($allowedOrigins); + $this->setAllowedMethods($allowedMethods); + $this->setAllowedHeaders($allowedHeaders); + $this->setExposedHeaders($exposedHeaders); + $this->setMaxedAgeInSeconds($maxAgeInSeconds); + } + + /** + * Create an instance with parsed XML response with 'CORS' root. + * + * @param array $parsedResponse The response used to create an instance. + * + * @internal + * + * @return CORS + */ + public static function create(array $parsedResponse) + { + Validate::hasKey( + Resources::XTAG_ALLOWED_ORIGINS, + 'parsedResponse', + $parsedResponse + ); + Validate::hasKey( + Resources::XTAG_ALLOWED_METHODS, + 'parsedResponse', + $parsedResponse + ); + Validate::hasKey( + Resources::XTAG_ALLOWED_HEADERS, + 'parsedResponse', + $parsedResponse + ); + Validate::hasKey( + Resources::XTAG_EXPOSED_HEADERS, + 'parsedResponse', + $parsedResponse + ); + Validate::hasKey( + Resources::XTAG_MAX_AGE_IN_SECONDS, + 'parsedResponse', + $parsedResponse + ); + + // Get the values from the parsed response. + $allowedOrigins = explode( + ',', + $parsedResponse[Resources::XTAG_ALLOWED_ORIGINS] + ); + $allowedMethods = explode( + ',', + $parsedResponse[Resources::XTAG_ALLOWED_METHODS] + ); + $allowedHeaders = explode( + ',', + $parsedResponse[Resources::XTAG_ALLOWED_HEADERS] + ); + $exposedHeaders = explode( + ',', + $parsedResponse[Resources::XTAG_EXPOSED_HEADERS] + ); + $maxAgeInSeconds = intval( + $parsedResponse[Resources::XTAG_MAX_AGE_IN_SECONDS] + ); + + return new CORS( + $allowedOrigins, + $allowedMethods, + $allowedHeaders, + $exposedHeaders, + $maxAgeInSeconds + ); + } + + /** + * Converts this object to array with XML tags + * + * @return array + */ + public function toArray() + { + return array( + Resources::XTAG_ALLOWED_ORIGINS => + implode(',', $this->getAllowedOrigins()), + Resources::XTAG_ALLOWED_METHODS => + implode(',', $this->getAllowedMethods()), + Resources::XTAG_ALLOWED_HEADERS => + implode(',', $this->getAllowedHeaders()), + Resources::XTAG_EXPOSED_HEADERS => + implode(',', $this->getExposedHeaders()), + Resources::XTAG_MAX_AGE_IN_SECONDS => + $this->getMaxedAgeInSeconds() + ); + } + + /** + * Setter for allowedOrigins + * + * @param string[] $allowedOrigins the allowed origins to be set. + */ + public function setAllowedOrigins(array $allowedOrigins) + { + $this->allowedOrigins = $allowedOrigins; + } + + /** + * Getter for allowedOrigins + * + * @return string[] + */ + public function getAllowedOrigins() + { + return $this->allowedOrigins; + } + + /** + * Setter for allowedMethods + * + * @param string[] $allowedMethods the allowed methods to be set. + */ + public function setAllowedMethods(array $allowedMethods) + { + $this->allowedMethods = $allowedMethods; + } + + /** + * Getter for allowedMethods + * + * @return string[] + */ + public function getAllowedMethods() + { + return $this->allowedMethods; + } + + /** + * Setter for allowedHeaders + * + * @param string[] $allowedHeaders the allowed headers to be set. + */ + public function setAllowedHeaders(array $allowedHeaders) + { + $this->allowedHeaders = $allowedHeaders; + } + + /** + * Getter for allowedHeaders + * + * @return string[] + */ + public function getAllowedHeaders() + { + return $this->allowedHeaders; + } + + /** + * Setter for exposedHeaders + * + * @param string[] $exposedHeaders the exposed headers to be set. + */ + public function setExposedHeaders(array $exposedHeaders) + { + $this->exposedHeaders = $exposedHeaders; + } + + /** + * Getter for exposedHeaders + * + * @return string[] + */ + public function getExposedHeaders() + { + return $this->exposedHeaders; + } + + /** + * Setter for maxAgeInSeconds + * + * @param int $maxAgeInSeconds the max age in seconds to be set. + */ + public function setMaxedAgeInSeconds($maxAgeInSeconds) + { + $this->maxAgeInSeconds = $maxAgeInSeconds; + } + + /** + * Getter for maxAgeInSeconds + * + * @return int + */ + public function getMaxedAgeInSeconds() + { + return $this->maxAgeInSeconds; + } +} diff --git a/src/Common/Models/GetServicePropertiesResult.php b/src/Common/Models/GetServicePropertiesResult.php index f42dfbc15..de755f9bd 100644 --- a/src/Common/Models/GetServicePropertiesResult.php +++ b/src/Common/Models/GetServicePropertiesResult.php @@ -43,6 +43,7 @@ class GetServicePropertiesResult /** * Creates object from $parsedResponse. * + * @internal * @param array $parsedResponse XML response parsed into array. * * @return \MicrosoftAzure\Storage\Common\Models\GetServicePropertiesResult diff --git a/src/Common/Models/Logging.php b/src/Common/Models/Logging.php index 2c7523df3..8448ab125 100644 --- a/src/Common/Models/Logging.php +++ b/src/Common/Models/Logging.php @@ -39,45 +39,16 @@ */ class Logging { - /** - * The version of Storage Analytics to configure - * - * @var string - */ private $_version; - - /** - * Applies only to logging configuration. Indicates whether all delete requests - * should be logged. - * - * @var bool - */ private $_delete; - - /** - * Applies only to logging configuration. Indicates whether all read requests - * should be logged. - * - * @var bool. - */ private $_read; - - /** - * Applies only to logging configuration. Indicates whether all write requests - * should be logged. - * - * @var bool - */ private $_write; - - /** - * @var RetentionPolicy - */ private $_retentionPolicy; /** * Creates object from $parsedResponse. * + * @internal * @param array $parsedResponse XML response parsed into array. * * @return Logging @@ -97,9 +68,9 @@ public static function create(array $parsedResponse) } /** - * Gets retention policy + * Gets the retention policy * - * @return RetentionPolicy + * @return MicrosoftAzure\Storage\Common\Models\RetentionPolicy * */ public function getRetentionPolicy() @@ -120,7 +91,7 @@ public function setRetentionPolicy(RetentionPolicy $policy) } /** - * Gets write + * Gets whether all write requests should be logged. * * @return bool. */ @@ -130,7 +101,7 @@ public function getWrite() } /** - * Sets write + * Sets whether all write requests should be logged. * * @param bool $write new value. * @@ -142,7 +113,7 @@ public function setWrite($write) } /** - * Gets read + * Gets whether all read requests should be logged. * * @return bool */ @@ -152,7 +123,7 @@ public function getRead() } /** - * Sets read + * Sets whether all read requests should be logged. * * @param bool $read new value. * @@ -164,7 +135,7 @@ public function setRead($read) } /** - * Gets delete + * Gets whether all delete requests should be logged. * * @return void */ @@ -174,7 +145,7 @@ public function getDelete() } /** - * Sets delete + * Sets whether all delete requests should be logged. * * @param bool $delete new value. * @@ -186,7 +157,7 @@ public function setDelete($delete) } /** - * Gets version + * Gets the version of Storage Analytics to configure * * @return string */ @@ -196,7 +167,7 @@ public function getVersion() } /** - * Sets version + * Sets the version of Storage Analytics to configure * * @param string $version new value. * @@ -210,6 +181,7 @@ public function setVersion($version) /** * Converts this object to array with XML tags * + * @internal * @return array */ public function toArray() diff --git a/src/Common/Models/Metrics.php b/src/Common/Models/Metrics.php index 59c62adba..578e4cfd2 100644 --- a/src/Common/Models/Metrics.php +++ b/src/Common/Models/Metrics.php @@ -38,35 +38,15 @@ */ class Metrics { - /** - * The version of Storage Analytics to configure - * - * @var string - */ private $_version; - - /** - * Indicates whether metrics is enabled for the storage service - * - * @var bool - */ private $_enabled; - - /** - * Indicates whether a retention policy is enabled for the storage service - * - * @var bool - */ private $_includeAPIs; - - /** - * @var RetentionPolicy - */ private $_retentionPolicy; /** * Creates object from $parsedResponse. * + * @internal * @param array $parsedResponse XML response parsed into array. * * @return Metrics @@ -180,6 +160,7 @@ public function setVersion($version) /** * Converts this object to array with XML tags * + * @internal * @return array */ public function toArray() diff --git a/src/Common/Models/RetentionPolicy.php b/src/Common/Models/RetentionPolicy.php index ad2f0506b..409406509 100644 --- a/src/Common/Models/RetentionPolicy.php +++ b/src/Common/Models/RetentionPolicy.php @@ -38,21 +38,7 @@ */ class RetentionPolicy { - /** - * Indicates whether a retention policy is enabled for the storage service - * - * @var bool. - */ private $_enabled; - - /** - * If $_enabled is true then this field indicates the number of days that metrics - * or logging data should be retained. All data older than this value will be - * deleted. The minimum value you can specify is 1; - * the largest value is 365 (one year) - * - * @var int - */ private $_days; /** @@ -60,6 +46,8 @@ class RetentionPolicy * * @param array $parsedResponse XML response parsed into array. * + * @internal + * * @return MicrosoftAzure\Storage\Common\Models\RetentionPolicy */ public static function create(array $parsedResponse = null) @@ -120,6 +108,8 @@ public function setDays($days) /** * Converts this object to array with XML tags * + * @internal + * * @return array */ public function toArray() diff --git a/src/Common/Models/ServiceProperties.php b/src/Common/Models/ServiceProperties.php index db2e6eba3..42756541e 100644 --- a/src/Common/Models/ServiceProperties.php +++ b/src/Common/Models/ServiceProperties.php @@ -25,8 +25,10 @@ namespace MicrosoftAzure\Storage\Common\Models; use MicrosoftAzure\Storage\Common\Internal\Utilities; +use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Models\Logging; use MicrosoftAzure\Storage\Common\Models\Metrics; +use MicrosoftAzure\Storage\Common\Models\CORS; use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; /** @@ -41,13 +43,16 @@ */ class ServiceProperties { - private $_logging; - private $_metrics; - public static $xmlRootName = 'StorageServiceProperties'; + private $logging; + private $metrics; + private $corses; + + private static $xmlRootName = 'StorageServiceProperties'; /** * Creates ServiceProperties object from parsed XML response. * + * @internal * @param array $parsedResponse XML response parsed into array. * * @return ServiceProperties. @@ -55,9 +60,29 @@ class ServiceProperties public static function create(array $parsedResponse) { $result = new ServiceProperties(); - $result->setLogging(Logging::create($parsedResponse['Logging'])); - $result->setMetrics(Metrics::create($parsedResponse['HourMetrics'])); - + $result->setLogging(Logging::create($parsedResponse[Resources::XTAG_LOGGING])); + $result->setMetrics(Metrics::create($parsedResponse[Resources::XTAG_HOUR_METRICS])); + if (array_key_exists(Resources::XTAG_CORS, $parsedResponse) && + $parsedResponse[Resources::XTAG_CORS] != null) { + //There could be multiple CORS rules, so need to extract them all. + $corses = array(); + $corsArray = + $parsedResponse[Resources::XTAG_CORS][Resources::XTAG_CORS_RULE]; + if (count(array_filter(array_keys($corsArray), 'is_string')) > 0) { + //single cors rule + $corses[] = CORS::create($corsArray); + } else { + //multiple cors rule + foreach ($corsArray as $cors) { + $corses[] = CORS::create($cors); + } + } + + $result->setCorses($corses); + } else { + $result->setCorses(array()); + } + return $result; } @@ -68,7 +93,7 @@ public static function create(array $parsedResponse) */ public function getLogging() { - return $this->_logging; + return $this->logging; } /** @@ -78,9 +103,9 @@ public function getLogging() * * @return void */ - public function setLogging($logging) + public function setLogging(Logging $logging) { - $this->_logging = clone $logging; + $this->logging = clone $logging; } /** @@ -90,7 +115,7 @@ public function setLogging($logging) */ public function getMetrics() { - return $this->_metrics; + return $this->metrics; } /** @@ -100,27 +125,80 @@ public function getMetrics() * * @return void */ - public function setMetrics($metrics) + public function setMetrics(Metrics $metrics) + { + $this->metrics = clone $metrics; + } + + /** + * Gets corses element. + * + * @return CORS[] + */ + public function getCorses() { - $this->_metrics = clone $metrics; + return $this->corses; + } + + /** + * Sets corses element. + * + * @param CORS[] $corses new elements. + * + * @return void + */ + public function setCorses(array $corses) + { + $this->corses = $corses; } /** * Converts this object to array with XML tags * + * @internal * @return array */ public function toArray() { + $corsesArray = $this->getCorsesArray(); return array( - 'Logging' => !empty($this->_logging) ? $this->_logging->toArray() : null, - 'HourMetrics' => !empty($this->_metrics) ? $this->_metrics->toArray() : null + Resources::XTAG_LOGGING + => !empty($this->getLogging()) ? + $this->getLogging()->toArray() : null, + Resources::XTAG_HOUR_METRICS + => !empty($this->getMetrics()) ? + $this->getMetrics()->toArray() : null, + Resources::XTAG_CORS + => !empty($corsesArray) ? $corsesArray : null + ); } + + /** + * Gets the array that contains all the CORSes. + * + * @return array + */ + private function getCorsesArray() + { + $corsesArray = array(); + if (count($this->getCorses()) == 1) { + $corsesArray = array( + Resources::XTAG_CORS_RULE => $this->getCorses()[0]->toArray() + ); + } elseif ($this->getCorses() != array()) { + foreach ($this->getCorses() as $cors) { + $corsesArray[] = [Resources::XTAG_CORS_RULE => $cors->toArray()]; + } + } + + return $corsesArray; + } /** * Converts this current object to XML representation. * + * @internal * @param XmlSerializer $xmlSerializer The XML serializer. * * @return string @@ -128,7 +206,6 @@ public function toArray() public function toXml(XmlSerializer $xmlSerializer) { $properties = array(XmlSerializer::ROOT_NAME => self::$xmlRootName); - return $xmlSerializer->serialize($this->toArray(), $properties); } } diff --git a/src/Blob/Models/SignedIdentifier.php b/src/Common/Models/SignedIdentifier.php similarity index 56% rename from src/Blob/Models/SignedIdentifier.php rename to src/Common/Models/SignedIdentifier.php index abc1fd110..a7180fbfa 100644 --- a/src/Blob/Models/SignedIdentifier.php +++ b/src/Common/Models/SignedIdentifier.php @@ -15,22 +15,24 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Blob\Models + * @package MicrosoftAzure\Storage\Common\Models * @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 */ -namespace MicrosoftAzure\Storage\Blob\Models; +namespace MicrosoftAzure\Storage\Common\Models; -use MicrosoftAzure\Storage\Blob\Models\AccessPolicy; +use MicrosoftAzure\Storage\Common\Models\AccessPolicy; +use MicrosoftAzure\Storage\Common\Internal\Validate; +use MicrosoftAzure\Storage\Common\Internal\Resources; /** - * Holds container signed identifiers. + * Holds signed identifiers. * * @category Microsoft - * @package MicrosoftAzure\Storage\Blob\Models + * @package MicrosoftAzure\Storage\Common\Models * @author Azure Storage PHP SDK * @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -38,9 +40,21 @@ */ class SignedIdentifier { - private $_id; - private $_accessPolicy; + private $id; + private $accessPolicy; + /** + * Constructor + * + * @param string $id The id of this signed identifier. + * @param AccessPolicy|null $accessPolicy The access policy. + */ + public function __construct($id = '', AccessPolicy $accessPolicy = null) + { + $this->setId($id); + $this->setAccessPolicy($accessPolicy); + } + /** * Gets id. * @@ -48,7 +62,7 @@ class SignedIdentifier */ public function getId() { - return $this->_id; + return $this->id; } /** @@ -60,42 +74,46 @@ public function getId() */ public function setId($id) { - $this->_id = $id; + $this->id = $id; } /** * Gets accessPolicy. * - * @return string + * @return AccessPolicy */ public function getAccessPolicy() { - return $this->_accessPolicy; + return $this->accessPolicy; } /** * Sets accessPolicy. * - * @param string $accessPolicy value. + * @param AccessPolicy|null $accessPolicy value. * * @return void */ - public function setAccessPolicy($accessPolicy) + public function setAccessPolicy(AccessPolicy $accessPolicy = null) { - $this->_accessPolicy = $accessPolicy; + $this->accessPolicy = $accessPolicy; } /** * Converts this current object to XML representation. * + * @internal + * * @return array */ public function toArray() { $array = array(); - - $array['SignedIdentifier']['Id'] = $this->_id; - $array['SignedIdentifier']['AccessPolicy'] = $this->_accessPolicy->toArray(); + $accessPolicyArray = array(); + $accessPolicyArray[Resources::XTAG_SIGNED_ID] = $this->getId(); + $accessPolicyArray[Resources::XTAG_ACCESS_POLICY] = + $this->getAccessPolicy()->toArray(); + $array[Resources::XTAG_SIGNED_IDENTIFIER] = $accessPolicyArray; return $array; } diff --git a/src/Common/ServicesBuilder.php b/src/Common/ServicesBuilder.php index 538119c7e..dec8fcb79 100644 --- a/src/Common/ServicesBuilder.php +++ b/src/Common/ServicesBuilder.php @@ -28,7 +28,7 @@ use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Validate; use MicrosoftAzure\Storage\Common\Internal\Utilities; -use MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException; +use MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException; use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; use MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureAuthScheme; use MicrosoftAzure\Storage\Common\Internal\Authentication\SharedKeyAuthScheme; @@ -52,14 +52,13 @@ */ class ServicesBuilder { - /** - * @var ServicesBuilder - */ private static $_instance = null; /** * Gets the serializer used in the REST services construction. * + * @internal + * * @return Internal\Serialization\ISerializer */ protected function serializer() @@ -70,6 +69,8 @@ protected function serializer() /** * Gets the MIME serializer used in the REST services construction. * + * @internal + * * @return \MicrosoftAzure\Storage\Table\Internal\IMimeReaderWriter */ protected function mimeSerializer() @@ -80,6 +81,8 @@ protected function mimeSerializer() /** * Gets the Atom serializer used in the REST services construction. * + * @internal + * * @return \MicrosoftAzure\Storage\Table\Internal\IAtomReaderWriter */ protected function atomSerializer() @@ -93,6 +96,8 @@ protected function atomSerializer() * @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) @@ -106,6 +111,8 @@ protected function queueAuthenticationScheme($accountName, $accountKey) * @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) @@ -119,6 +126,8 @@ protected function blobAuthenticationScheme($accountName, $accountKey) * @param string $accountName The account name. * @param string $accountKey The account key. * + * @internal + * * @return TableSharedKeyLiteAuthScheme */ protected function tableAuthenticationScheme($accountName, $accountKey) @@ -131,6 +140,8 @@ protected function tableAuthenticationScheme($accountName, $accountKey) * * @param string $sasToken The SAS token. * + * @internal + * * @return \MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureAuthScheme */ protected function sasAuthenticationScheme($sasToken) @@ -139,7 +150,14 @@ protected function sasAuthenticationScheme($sasToken) } /** - * Builds a queue object. + * 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 @@ -184,7 +202,14 @@ public function createQueueService($connectionString, array $options = []) } /** - * Builds a blob object. + * 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 @@ -228,7 +253,14 @@ public function createBlobService($connectionString, array $options = []) } /** - * Builds a table object. + * 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 diff --git a/src/Common/Internal/Authentication/SharedAccessSignatureHelper.php b/src/Common/SharedAccessSignatureHelper.php similarity index 69% rename from src/Common/Internal/Authentication/SharedAccessSignatureHelper.php rename to src/Common/SharedAccessSignatureHelper.php index bf2daa542..e0e00be4e 100644 --- a/src/Common/Internal/Authentication/SharedAccessSignatureHelper.php +++ b/src/Common/SharedAccessSignatureHelper.php @@ -22,8 +22,7 @@ * @link https://github.com/azure/azure-storage-php */ -namespace MicrosoftAzure\Storage\Common\Internal\Authentication; - +namespace MicrosoftAzure\Storage\Common; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Validate; @@ -38,12 +37,11 @@ * @license https://github.com/azure/azure-storage-php/LICENSE * @link https://github.com/azure/azure-storage-php */ -class SharedAccessSignatureHelper { - +class SharedAccessSignatureHelper +{ protected $accountName; protected $accountKey; - /** * Constructor. * @@ -51,7 +49,7 @@ class SharedAccessSignatureHelper { * @param string $accountKey the shared key of the storage account * * @return - * MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureHelper + * MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper */ public function __construct($accountName, $accountKey) { @@ -69,13 +67,23 @@ public function __construct($accountName, $accountKey) * Generates a shared access signature at the account level. * * @param string $signedVersion Specifies the signed version to use. - * @param string $signedPermissions Specifies the signed permissions for the account SAS. - * @param string $signedService Specifies the signed services accessible with the account SAS. - * @param string $signedResourceType Specifies the signed resource types that are accessible with the account SAS. - * @param string $signedExpiracy The time at which the shared access signature becomes invalid, in an ISO 8601 format. - * @param string $signedStart The time at which the SAS becomes valid, in an ISO 8601 format. - * @param string $signedIP Specifies an IP address or a range of IP addresses from which to accept requests. - * @param string $signedProtocol Specifies the protocol permitted for a request made with the account SAS. + * @param string $signedPermissions Specifies the signed permissions for + * the account SAS. + * @param string $signedService Specifies the signed services + * accessible with the account SAS. + * @param string $signedResourceType Specifies the signed resource types + * that are accessible with the account + * SAS. + * @param string $signedExpiracy The time at which the shared access + * signature becomes invalid, in an ISO + * 8601 format. + * @param string $signedStart The time at which the SAS becomes + * valid, in an ISO 8601 format. + * @param string $signedIP Specifies an IP address or a range + * of IP addresses from which to accept + * requests. + * @param string $signedProtocol Specifies the protocol permitted for + * a request made with the account SAS. * * @see Constructing an account SAS at * https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/constructing-an-account-sas @@ -113,8 +121,7 @@ public function generateAccountSharedAccessSignatureToken( // check that signed start is valid Validate::isString($signedStart, 'signedStart'); - if(strlen($signedStart) > 0) - { + if (strlen($signedStart) > 0) { Validate::isDateString($signedStart, 'signedStart'); } @@ -137,7 +144,7 @@ public function generateAccountSharedAccessSignatureToken( $parameters[] = urldecode($signedVersion); // implode the parameters into a string - $stringToSign = utf8_encode(implode("\n", $parameters)."\n"); + $stringToSign = utf8_encode(implode("\n", $parameters) . "\n"); // decode the account key from base64 $decodedAccountKey = base64_decode($this->accountKey); @@ -145,111 +152,108 @@ public function generateAccountSharedAccessSignatureToken( // create the signature with hmac sha256 $signature = hash_hmac("sha256", $stringToSign, $decodedAccountKey, true); - // encode the signature as base64 - $base64Signature = base64_encode($signature); + // encode the signature as base64 and url encode. + $sig = urlencode(base64_encode($signature)); + + //adding all the components for account SAS together. + $sas = 'sv=' . $signedVersion; + $sas .= '&ss=' . $signedService; + $sas .= '&srt=' . $signedResourceType; + $sas .= '&sp=' . $signedPermissions; + $sas .= '&se=' . $signedExpiracy; + $sas .= $signedStart === ''? '' : '&st=' . $signedStart; + $sas .= $signedIP === ''? '' : '&sip=' . $signedIP; + $sas .= '&spr=' . $signedProtocol; + $sas .= '&sig=' . $sig; // return the signature - return $base64Signature; + return $sas; } /** * Validates and sanitizes the signed service parameter * - * @param string $signedService Specifies the signed services accessible with the account SAS. + * @param string $signedService Specifies the signed services accessible + * with the account SAS. * * @return string */ - private function validateAndSanitizeSignedService($signedService) { + private function validateAndSanitizeSignedService($signedService) + { // validate signed service is not null or empty Validate::isString($signedService, 'signedService'); Validate::notNullOrEmpty($signedService, 'signedService'); - // sanitize signed service - $sanitizedSignedService = $this->removeDuplicateCharacters(strtolower($signedService)); - // The signed service should only be a combination of the letters b(lob) q(ueue) t(able) or f(ile) - $signedServiceIsValid = preg_match("/^[bqtf]*$/", $sanitizedSignedService); - if(!$signedServiceIsValid) { - throw new \InvalidArgumentException(Resources::SIGNED_SERVICE_INVALID_VALIDATION_MSG); - } + $validServices = ['b', 'q', 't', 'f']; - return $sanitizedSignedService; + return $this->validateAndSanitizeStringWithArray( + strtolower($signedService), + $validServices + ); } /** * Validates and sanitizes the signed resource type parameter * - * @param string $signedResourceType Specifies the signed resource types that are accessible with the account SAS. + * @param string $signedResourceType Specifies the signed resource types + * that are accessible with the account + * SAS. * * @return string */ - private function validateAndSanitizeSignedResourceType($signedResourceType) { + private function validateAndSanitizeSignedResourceType($signedResourceType) + { // validate signed resource type is not null or empty Validate::isString($signedResourceType, 'signedResourceType'); Validate::notNullOrEmpty($signedResourceType, 'signedResourceType'); - // sanitize signed resource type - $sanitizedSignedResourceType = $this->removeDuplicateCharacters(strtolower($signedResourceType)); - // The signed resource type should only be a combination of the letters s(ervice) c(container) or o(bject) - $signedResourceTypeIsValid = preg_match("/^[sco]*$/", $sanitizedSignedResourceType); - if(!$signedResourceTypeIsValid) { - throw new \InvalidArgumentException(Resources::SIGNED_RESOURCE_TYPE_INVALID_VALIDATION_MSG); - } + $validResourceTypes = ['s', 'c', 'o']; - return $sanitizedSignedResourceType; + return $this->validateAndSanitizeStringWithArray( + strtolower($signedResourceType), + $validResourceTypes + ); } /** * Validates and sanitizes the signed permissions parameter * - * @param string $signedPermissions Specifies the signed permissions for the account SAS. + * @param string $signedPermissions Specifies the signed permissions for the + * account SAS. * @return string */ - private function validateAndSanitizeSignedPermissions($signedPermissions) { + private function validateAndSanitizeSignedPermissions($signedPermissions) + { // validate signed permissions are not null or empty Validate::isString($signedPermissions, 'signedPermissions'); Validate::notNullOrEmpty($signedPermissions, 'signedPermissions'); - // sanitized signed permissions, service and resource type - $sanitizedSignedPermissions = $this->removeDuplicateCharacters(strtolower($signedPermissions)); - $validPermissions = ['r', 'w', 'd', 'l', 'a', 'c', 'u', 'p']; - $result = ''; - foreach ($validPermissions as $validPermission) { - if (strpos($sanitizedSignedPermissions, $validPermission) !== false) { - //append the valid permission to result. - $result .= $validPermission; - //remove all the character that represents the permission. - $sanitizedSignedPermissions = str_replace( - $validPermission, - '', - $sanitizedSignedPermissions - ); - } - } - if(strlen($result) == 0) { - throw new \InvalidArgumentException(Resources::SIGNED_PERMISSIONS_INVALID_VALIDATION_MSG); - } - - return $result; + return $this->validateAndSanitizeStringWithArray( + strtolower($signedPermissions), + $validPermissions + ); } /** * Validates and sanitizes the signed protocol parameter * - * @param string $signedProtocol Specifies the signed protocol for the account SAS. + * @param string $signedProtocol Specifies the signed protocol for the + * account SAS. * @return string */ - private function validateAndSanitizeSignedProtocol($signedProtocol) { + private function validateAndSanitizeSignedProtocol($signedProtocol) + { Validate::isString($signedProtocol, 'signedProtocol'); // sanitize string $sanitizedSignedProtocol = strtolower($signedProtocol); - if(strlen($sanitizedSignedProtocol) > 0) { - if(strcmp($sanitizedSignedProtocol,"https") != 0 && strcmp($sanitizedSignedProtocol, "https,http") != 0) { + if (strlen($sanitizedSignedProtocol) > 0) { + if (strcmp($sanitizedSignedProtocol, "https") != 0 && strcmp($sanitizedSignedProtocol, "https,http") != 0) { throw new \InvalidArgumentException(Resources::SIGNED_PROTOCOL_INVALID_VALIDATION_MSG); } } @@ -265,7 +269,8 @@ private function validateAndSanitizeSignedProtocol($signedProtocol) { * @return bool */ - private function strcontains($input, $toFind) { + private function strcontains($input, $toFind) + { return strpos($input, $toFind) !== false; } @@ -276,10 +281,29 @@ private function strcontains($input, $toFind) { * @return string */ - private function removeDuplicateCharacters($input) { - $inputAsArray = str_split($input); - $deduplicated = array_unique($inputAsArray); - $output = implode("", $deduplicated); - return $output; + private function validateAndSanitizeStringWithArray($input, array $array) + { + $result = ''; + foreach ($array as $value) { + if (strpos($input, $value) !== false) { + //append the valid permission to result. + $result .= $value; + //remove all the character that represents the permission. + $input = str_replace( + $value, + '', + $input + ); + } + } + + Validate::isTrue( + strlen($input) == '', + sprintf( + Resources::STRING_NOT_WITH_GIVEN_COMBINATION, + implode(', ', $array) + ) + ); + return $result; } } diff --git a/src/Queue/Internal/IQueue.php b/src/Queue/Internal/IQueue.php index 5ea41ed66..b5a738338 100644 --- a/src/Queue/Internal/IQueue.php +++ b/src/Queue/Internal/IQueue.php @@ -30,6 +30,7 @@ /** * This interface has all REST APIs provided by Windows Azure for queue service * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Queue\Internal * @author Azure Storage PHP SDK @@ -445,4 +446,68 @@ public function clearMessagesAsync( $queueName, QueueModels\QueueServiceOptions $options = null ); + + /** + * Gets the access control list (ACL) + * + * @param string $queue The queue name. + * @param QueueModels\QueueServiceOptions $options The optional parameters. + * + * @return QueueModels\QueueACL + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-queue-acl + */ + public function getQueueAcl( + $queue, + QueueModels\QueueServiceOptions $options = null + ); + + /** + * Creates the promise to gets the access control list (ACL) + * + * @param string $queue The queue name. + * @param QueueModels\QueueServiceOptions $options The optional parameters. + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-queue-acl + */ + public function getQueueAclAsync( + $queue, + QueueModels\QueueServiceOptions $options = null + ); + + /** + * Sets the ACL. + * + * @param string $queue name + * @param QueueModels\QueueACL $acl access control list + * @param QueueModels\QueueServiceOptions $options optional parameters + * + * @return void + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-queue-acl + */ + public function setQueueAcl( + $queue, + QueueModels\QueueACL $acl, + QueueModels\QueueServiceOptions $options = null + ); + + /** + * Creates promise to set the ACL + * + * @param string $queue name + * @param QueueModels\QueueACL $acl access control list + * @param QueueModels\QueueServiceOptions $options optional parameters + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-queue-acl + */ + public function setQueueAclAsync( + $queue, + QueueModels\QueueACL $acl, + QueueModels\QueueServiceOptions $options = null + ); } diff --git a/src/Queue/Models/CreateMessageOptions.php b/src/Queue/Models/CreateMessageOptions.php index b773947ef..daeb4a7ff 100644 --- a/src/Queue/Models/CreateMessageOptions.php +++ b/src/Queue/Models/CreateMessageOptions.php @@ -36,26 +36,7 @@ */ class CreateMessageOptions extends QueueServiceOptions { - /** - * If specified, the request must be made using an x-ms-version - * of 2011-08-18 or newer. If not specified, the default value is 0. - * Specifies the new visibility timeout value, in seconds, relative to server - * time. The new value must be larger than or equal to 0, and cannot be - * larger than 7 days. The visibility timeout of a message cannot be set to a - * value later than the expiry time. visibilitytimeout should be set to a - * value smaller than the time-to-live value. - * - * @var integer - */ private $_visibilityTimeoutInSeconds; - - /** - * Specifies the time-to-live interval for the message, in seconds. - * The maximum time-to-live allowed is 7 days. If this parameter is omitted, - * the default time-to-live is 7 days. - * - * @var integer - */ private $_timeToLiveInSeconds; /** diff --git a/src/Queue/Models/GetQueueMetadataResult.php b/src/Queue/Models/GetQueueMetadataResult.php index 857f9db8f..07afe1fb2 100644 --- a/src/Queue/Models/GetQueueMetadataResult.php +++ b/src/Queue/Models/GetQueueMetadataResult.php @@ -36,18 +36,7 @@ */ class GetQueueMetadataResult { - /** - * Indicates the approximate number of messages in the queue - * - * @var integer - */ private $_approximateMessageCount; - - /** - * A user-defined name/value pair - * - * @var array - */ private $_metadata; /** @@ -55,6 +44,8 @@ class GetQueueMetadataResult * * @param integer $approximateMessageCount Approximate number of queue messages. * @param array $metadata user defined metadata. + * + * @internal */ public function __construct($approximateMessageCount, array $metadata) { @@ -77,6 +68,8 @@ public function getApproximateMessageCount() * * @param integer $approximateMessageCount value to use. * + * @internal + * * @return void */ protected function setApproximateMessageCount($approximateMessageCount) @@ -99,6 +92,8 @@ public function getMetadata() * * @param array $metadata value to use. * + * @internal + * * @return void */ protected function setMetadata(array $metadata) diff --git a/src/Queue/Models/ListMessagesOptions.php b/src/Queue/Models/ListMessagesOptions.php index f904d486b..4d4854cf5 100644 --- a/src/Queue/Models/ListMessagesOptions.php +++ b/src/Queue/Models/ListMessagesOptions.php @@ -36,26 +36,7 @@ */ class ListMessagesOptions extends QueueServiceOptions { - /** - * A nonzero integer value that specifies the number of messages to retrieve - * from the queue, up to a maximum of 32. If fewer are visible, - * the visible messages are returned. By default, a single message is retrieved - * from the queue with this operation. - * - * @var integer - */ private $_numberOfMessages; - - /** - * Specifies the new visibility timeout value, in seconds, - * relative to server time. The new value must be larger than or equal to - * 1 second, and cannot be larger than 7 days, or larger than 2 hours on - * REST protocol versions prior to version 2011-08-18. - * The visibility timeout of a message can be set to a value later than the - * expiry time. - * - * @var integer - */ private $_visibilityTimeoutInSeconds; /** diff --git a/src/Queue/Models/ListMessagesResult.php b/src/Queue/Models/ListMessagesResult.php index be851fd93..d68b15216 100644 --- a/src/Queue/Models/ListMessagesResult.php +++ b/src/Queue/Models/ListMessagesResult.php @@ -39,11 +39,6 @@ */ class ListMessagesResult { - /** - * Holds all message entries. - * - * @var array - */ private $_queueMessages; /** @@ -51,6 +46,8 @@ class ListMessagesResult * * @param array $parsedResponse XML response parsed into array. * + * @internal + * * @return ListMessagesResult */ public static function create(array $parsedResponse = null) @@ -86,6 +83,8 @@ public function getQueueMessages() * * @param integer $queueMessages value to use. * + * @internal + * * @return void */ protected function setQueueMessages($queueMessages) diff --git a/src/Queue/Models/ListQueuesResult.php b/src/Queue/Models/ListQueuesResult.php index f6d9f4d93..225e7d828 100644 --- a/src/Queue/Models/ListQueuesResult.php +++ b/src/Queue/Models/ListQueuesResult.php @@ -52,6 +52,8 @@ class ListQueuesResult * * @param array $parsedResponse XML response parsed into array. * + * @internal + * * @return ListQueuesResult */ public static function create(array $parsedResponse) @@ -113,6 +115,8 @@ public function getQueues() * * @param array $queues list of queues * + * @internal + * * @return void */ protected function setQueues(array $queues) @@ -138,6 +142,8 @@ public function getPrefix() * * @param string $prefix value. * + * @internal + * * @return void */ protected function setPrefix($prefix) @@ -160,6 +166,8 @@ public function getMarker() * * @param string $marker value. * + * @internal + * * @return void */ protected function setMarker($marker) @@ -182,6 +190,8 @@ public function getMaxResults() * * @param string $maxResults value. * + * @internal + * * @return void */ protected function setMaxResults($maxResults) @@ -204,6 +214,8 @@ public function getNextMarker() * * @param string $nextMarker value. * + * @internal + * * @return void */ protected function setNextMarker($nextMarker) @@ -226,6 +238,8 @@ public function getAccountName() * * @param string $accountName value. * + * @internal + * * @return void */ protected function setAccountName($accountName) diff --git a/src/Queue/Models/MicrosoftAzureQueueMessage.php b/src/Queue/Models/MicrosoftAzureQueueMessage.php index 2f1dc8a80..99ca8f6f3 100644 --- a/src/Queue/Models/MicrosoftAzureQueueMessage.php +++ b/src/Queue/Models/MicrosoftAzureQueueMessage.php @@ -38,56 +38,12 @@ */ class MicrosoftAzureQueueMessage { - /** - * GUID value that identifies the message in the queue - * - * @var string - */ private $_messageId; - - /** - * insertion date of the message. - * - * @var \DateTime - */ private $_insertionDate; - - /** - * expiration date of the message. - * - * @var \DateTime - */ private $_expirationDate; - - /** - * The value of PopReceipt is opaque to the client and its only purpose is to - * ensure that a message may be deleted with the delete message operation. - * - * @var string - */ private $_popReceipt; - - /** - * next visibility time of the message. - * - * @var \DateTime - */ private $_timeNextVisible; - - /** - * Dequeues count for this message. Note that this element is returned in the - * response body only if the queue was created with version 2009-09-19 of - * the Queue service. - * - * @var integer - */ private $_dequeueCount; - - /** - * message contents. - * - * @var string - */ private $_messageText; /** @@ -96,6 +52,8 @@ class MicrosoftAzureQueueMessage * * @param array $parsedResponse XML response parsed into array. * + * @internal + * * @return MicrosoftAzureQueueMessage */ public static function createFromListMessages(array $parsedResponse) @@ -116,6 +74,8 @@ public static function createFromListMessages(array $parsedResponse) * * @param array $parsedResponse XML response parsed into array. * + * @internal + * * @return MicrosoftAzureQueueMessage */ public static function createFromPeekMessages(array $parsedResponse) @@ -197,6 +157,8 @@ public function getInsertionDate() * * @param \DateTime $insertionDate message contents. * + * @internal + * * @return void */ public function setInsertionDate(\DateTime $insertionDate) @@ -285,6 +247,8 @@ public function getDequeueCount() * * @param integer $dequeueCount number of dequeues for that message. * + * @internal + * * @return void */ public function setDequeueCount($dequeueCount) diff --git a/src/Queue/Models/PeekMessagesOptions.php b/src/Queue/Models/PeekMessagesOptions.php index 3b7c5a79e..b525cbb6b 100644 --- a/src/Queue/Models/PeekMessagesOptions.php +++ b/src/Queue/Models/PeekMessagesOptions.php @@ -36,13 +36,6 @@ */ class PeekMessagesOptions extends QueueServiceOptions { - /** - * A nonzero integer value that specifies the number of messages to peek from - * the queue, up to a maximum of 32. By default, a single message is peeked - * from the queue with this operation. - * - * @var integer - */ private $_numberOfMessages; /** diff --git a/src/Queue/Models/PeekMessagesResult.php b/src/Queue/Models/PeekMessagesResult.php index e25b21cfd..87e24f9cb 100644 --- a/src/Queue/Models/PeekMessagesResult.php +++ b/src/Queue/Models/PeekMessagesResult.php @@ -40,11 +40,6 @@ */ class PeekMessagesResult { - /** - * Holds all message entries. - * - * @var array - */ private $_queueMessages; /** @@ -52,6 +47,8 @@ class PeekMessagesResult * * @param array $parsedResponse XML response parsed into array. * + * @internal + * * @return PeekMessagesResult */ public static function create($parsedResponse) @@ -95,6 +92,8 @@ public function getQueueMessages() * * @param integer $queueMessages value to use. * + * @internal + * * @return void */ protected function setQueueMessages($queueMessages) diff --git a/src/Queue/Models/QueueACL.php b/src/Queue/Models/QueueACL.php new file mode 100644 index 000000000..b4c592167 --- /dev/null +++ b/src/Queue/Models/QueueACL.php @@ -0,0 +1,88 @@ + + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ + +namespace MicrosoftAzure\Storage\Queue\Models; + +use MicrosoftAzure\Storage\Common\Internal\Validate; +use MicrosoftAzure\Storage\Common\Internal\Resources; +use MicrosoftAzure\Storage\Common\Internal\ACLBase; + +/** + * Holds queue ACL members. + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Queue\Models + * @author Azure Storage PHP SDK + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +class QueueACL extends ACLBase +{ + /** + * Constructor. + */ + public function __construct() + { + //setting the resource type to a default value. + $this->setResourceType(Resources::RESOURCE_TYPE_QUEUE); + } + + /** + * Parses the given array into signed identifiers and create an instance of + * QueueACL + * + * @param array $parsed The parsed response into array representation. + * + * @internal + * + * @return QueueACL + */ + public static function create(array $parsed = null) + { + $result = new QueueACL(); + $result->fromXmlArray($parsed); + + return $result; + } + + /** + * Validate if the resource type for the class. + * + * @param string $resourceType the resource type to be validated. + * + * @throws \InvalidArgumentException + * + * @internal + * + * @return void + */ + protected static function validateResourceType($resourceType) + { + Validate::isTrue( + $resourceType == Resources::RESOURCE_TYPE_QUEUE, + Resources::INVALID_RESOURCE_TYPE + ); + } +} diff --git a/src/Queue/Models/QueueMessage.php b/src/Queue/Models/QueueMessage.php index 8d9aab2cd..957c3b6ca 100644 --- a/src/Queue/Models/QueueMessage.php +++ b/src/Queue/Models/QueueMessage.php @@ -40,7 +40,7 @@ class QueueMessage { private $_messageText; - public static $xmlRootName = 'QueueMessage'; + private static $xmlRootName = 'QueueMessage'; /** * Gets message text field. @@ -69,6 +69,8 @@ public function setMessageText($messageText) * * @param XmlSerializer $xmlSerializer The XML serializer. * + * @internal + * * @return string */ public function toXml(XmlSerializer $xmlSerializer) diff --git a/src/Queue/Models/QueueServiceOptions.php b/src/Queue/Models/QueueServiceOptions.php index 1afda22ae..6c60fa774 100644 --- a/src/Queue/Models/QueueServiceOptions.php +++ b/src/Queue/Models/QueueServiceOptions.php @@ -24,7 +24,7 @@ namespace MicrosoftAzure\Storage\Queue\Models; -use MicrosoftAzure\Storage\Common\ServiceOptionsBase; +use MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase; /** * Queue service options. diff --git a/src/Queue/Models/UpdateMessageResult.php b/src/Queue/Models/UpdateMessageResult.php index 46f82c0ad..4068aadc3 100644 --- a/src/Queue/Models/UpdateMessageResult.php +++ b/src/Queue/Models/UpdateMessageResult.php @@ -40,20 +40,7 @@ */ class UpdateMessageResult { - /** - * The value of PopReceipt is opaque to the client and its only purpose is to - * ensure that a message may be deleted with the delete message operation. - * - * @var string - */ private $_popReceipt; - - /** - * A UTC date/time value that represents when the message will be visible on the - * queue. - * - * @var \DateTime - */ private $_timeNextVisible; /** @@ -61,6 +48,8 @@ class UpdateMessageResult * * @param array $headers The response headers used to create the instance. * + * @internal + * * @return UpdateMessageResult */ public static function create(array $headers) @@ -96,6 +85,8 @@ public function getTimeNextVisible() * @param \DateTime $timeNextVisible A UTC date/time value that represents when * the message will be visible on the queue. * + * @internal + * * @return void */ protected function setTimeNextVisible(\DateTime $timeNextVisible) @@ -120,6 +111,8 @@ public function getPopReceipt() * * @param string $popReceipt The pop receipt of the queue message. * + * @internal + * * @return void */ protected function setPopReceipt($popReceipt) diff --git a/src/Queue/QueueRestProxy.php b/src/Queue/QueueRestProxy.php index b78516809..394b562af 100644 --- a/src/Queue/QueueRestProxy.php +++ b/src/Queue/QueueRestProxy.php @@ -37,13 +37,14 @@ use MicrosoftAzure\Storage\Queue\Models\QueueServiceOptions; use MicrosoftAzure\Storage\Queue\Models\GetQueueMetadataResult; use MicrosoftAzure\Storage\Queue\Models\CreateMessageOptions; +use MicrosoftAzure\Storage\Queue\Models\QueueACL; use MicrosoftAzure\Storage\Queue\Models\QueueMessage; use MicrosoftAzure\Storage\Queue\Models\ListMessagesOptions; use MicrosoftAzure\Storage\Queue\Models\ListMessagesResult; use MicrosoftAzure\Storage\Queue\Models\PeekMessagesOptions; use MicrosoftAzure\Storage\Queue\Models\PeekMessagesResult; use MicrosoftAzure\Storage\Queue\Models\UpdateMessageResult; -use MicrosoftAzure\Storage\Common\Internal\HttpFormatter; +use MicrosoftAzure\Storage\Common\Internal\Http\HttpFormatter; /** * This class constructs HTTP requests and receive HTTP responses for queue @@ -1037,4 +1038,151 @@ public function updateMessageAsync( return UpdateMessageResult::create($responseHeaders); }, null); } + + /** + * Gets the access control list (ACL) + * + * @param string $queue The queue name. + * @param Models\QueueServiceOptions $options The optional parameters. + * + * @return Models\QueueACL + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-queue-acl + */ + public function getQueueAcl( + $queue, + Models\QueueServiceOptions $options = null + ) { + return $this->getQueueAclAsync($queue, $options)->wait(); + } + + /** + * Creates the promise to gets the access control list (ACL) + * + * @param string $queue The queue name. + * @param Models\QueueServiceOptions $options The optional parameters. + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-queue-acl + */ + public function getQueueAclAsync( + $queue, + Models\QueueServiceOptions $options = null + ) { + Validate::isString($queue, 'queue'); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_OK; + $path = $queue; + + if (is_null($options)) { + $options = new QueueServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'acl' + ); + + $dataSerializer = $this->dataSerializer; + + $promise = $this->sendAsync( + $method, + $headers, + $queryParams, + $postParams, + $path, + Resources::STATUS_OK, + Resources::EMPTY_STRING, + $options->getRequestOptions() + ); + + return $promise->then(function ($response) use ($dataSerializer) { + $parsed = $dataSerializer->unserialize($response->getBody()); + return QueueACL::create($parsed); + }, null); + } + + /** + * Sets the ACL. + * + * @param string $queue name + * @param Models\QueueACL $acl access control list for Queue + * @param Models\QueueServiceOptions $options optional parameters + * + * @return void + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-queue-acl + */ + public function setQueueAcl( + $queue, + Models\QueueACL $acl, + Models\QueueServiceOptions $options = null + ) { + $this->setQueueAclAsync($queue, $acl, $options)->wait(); + } + + /** + * Creates promise to set the ACL + * + * @param string $queue name + * @param Models\QueueACL $acl access control list for Queue + * @param Models\QueueServiceOptions $options optional parameters + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-queue-acl + */ + public function setQueueAclAsync( + $queue, + Models\QueueACL $acl, + Models\QueueServiceOptions $options = null + ) { + Validate::isString($queue, 'queue'); + Validate::notNullOrEmpty($acl, 'acl'); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $body = $acl->toXml($this->dataSerializer); + $path = $queue; + + if (is_null($options)) { + $options = new QueueServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'acl' + ); + + return $this->sendAsync( + $method, + $headers, + $queryParams, + $postParams, + $path, + Resources::STATUS_NO_CONTENT, + $body, + $options->getRequestOptions() + ); + } } diff --git a/src/Table/Internal/AtomReaderWriter.php b/src/Table/Internal/AtomReaderWriter.php index 24e1b98d0..fc3e3eced 100644 --- a/src/Table/Internal/AtomReaderWriter.php +++ b/src/Table/Internal/AtomReaderWriter.php @@ -32,6 +32,7 @@ /** * Serializes and unserializes results from table wrapper calls * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Table\Internal * @author Azure Storage PHP SDK @@ -41,39 +42,12 @@ */ class AtomReaderWriter implements IAtomReaderWriter { - /** - * @var string - */ private $_atomNamespaceName; - - /** - * @var string - */ private $_dataServicesNamespaceName; - - /** - * @var string - */ private $_dataServicesMetadataNamespaceName; - - /** - * @var string - */ private $_xmlVersion; - - /** - * @var string - */ private $_xmlEncoding; - - /** - * @var string - */ private $_dataServicesPrefix; - - /** - * @var string - */ private $_dataServicesMetadataPrefix; /** diff --git a/src/Table/Internal/IAtomReaderWriter.php b/src/Table/Internal/IAtomReaderWriter.php index 04ecfb3a3..60c8f0507 100644 --- a/src/Table/Internal/IAtomReaderWriter.php +++ b/src/Table/Internal/IAtomReaderWriter.php @@ -27,6 +27,7 @@ /** * Defines how to serialize and unserialize table wrapper xml * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Table\Internal * @author Azure Storage PHP SDK diff --git a/src/Table/Internal/IMimeReaderWriter.php b/src/Table/Internal/IMimeReaderWriter.php index a901885ae..e86ab6abf 100644 --- a/src/Table/Internal/IMimeReaderWriter.php +++ b/src/Table/Internal/IMimeReaderWriter.php @@ -27,6 +27,7 @@ /** * Interface for MIME reading and writing. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Table\Internal * @author Azure Storage PHP SDK diff --git a/src/Table/Internal/ITable.php b/src/Table/Internal/ITable.php index c10392756..35fb0cbc4 100644 --- a/src/Table/Internal/ITable.php +++ b/src/Table/Internal/ITable.php @@ -30,6 +30,7 @@ /** * This interface has all REST APIs provided by Windows Azure for Table service. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Table\Internal * @author Azure Storage PHP SDK @@ -516,4 +517,68 @@ public function batchAsync( TableModels\BatchOperations $batchOperations, TableModels\TableServiceOptions $options = null ); + + /** + * Gets the access control list (ACL) + * + * @param string $table The container name. + * @param TableModels\TableServiceOptions $options The optional parameters. + * + * @return TableModels\TableACL + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-table-acl + */ + public function getTableAcl( + $table, + TableModels\TableServiceOptions $options = null + ); + + /** + * Creates the promise to gets the access control list (ACL) + * + * @param string $table The container name. + * @param TableModels\TableServiceOptions $options The optional parameters. + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-table-acl + */ + public function getTableAclAsync( + $table, + TableModels\TableServiceOptions $options = null + ); + + /** + * Sets the ACL. + * + * @param string $table name + * @param TableModels\TableACL $acl access control list + * @param TableModels\TableServiceOptions $options optional parameters + * + * @return void + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-table-acl + */ + public function setTableAcl( + $table, + TableModels\TableACL $acl, + TableModels\TableServiceOptions $options = null + ); + + /** + * Creates promise to set the ACL + * + * @param string $table name + * @param TableModels\TableACL $acl access control list + * @param TableModels\TableServiceOptions $options optional parameters + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-table-acl + */ + public function setTableAclAsync( + $table, + TableModels\TableACL $acl, + TableModels\TableServiceOptions $options = null + ); } diff --git a/src/Table/Internal/MimeReaderWriter.php b/src/Table/Internal/MimeReaderWriter.php index 17106986f..a26dd24fa 100644 --- a/src/Table/Internal/MimeReaderWriter.php +++ b/src/Table/Internal/MimeReaderWriter.php @@ -30,6 +30,7 @@ /** * Reads and writes MIME for batch API. * + * @ignore * @category Microsoft * @package MicrosoftAzure\Storage\Table\Internal * @author Azure Storage PHP SDK diff --git a/src/Table/Models/BatchError.php b/src/Table/Models/BatchError.php index 6bd59a30b..21a558f6c 100644 --- a/src/Table/Models/BatchError.php +++ b/src/Table/Models/BatchError.php @@ -27,7 +27,7 @@ use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Utilities; use MicrosoftAzure\Storage\Common\Internal\Validate; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; /** * Represents an error returned from call to batch API. @@ -41,21 +41,17 @@ */ class BatchError { - /** - * @var \MicrosoftAzure\Storage\Common\ServiceException - */ private $_error; - - /** - * @var integer - */ private $_contentId; /** * Creates BatchError object. * - * @param \MicrosoftAzure\Storage\Common\ServiceException $error The error object. - * @param array $headers The response headers. + * @param \MicrosoftAzure\Storage\Common\Exceptions\ServiceException $error + * The error object. + * @param array $headers The response headers. + * + * @internal * * @return \MicrosoftAzure\Storage\Table\Models\BatchError */ @@ -80,7 +76,7 @@ public static function create($error, array $headers) /** * Gets the error. * - * @return MicrosoftAzure\Storage\Common\ServiceException + * @return MicrosoftAzure\Storage\Common\Exceptions\ServiceException */ public function getError() { @@ -90,7 +86,8 @@ public function getError() /** * Sets the error. * - * @param \MicrosoftAzure\Storage\Common\ServiceException $error The error object. + * @param \MicrosoftAzure\Storage\Common\Exceptions\ServiceException $error + * The error object. * * @return void */ diff --git a/src/Table/Models/BatchOperation.php b/src/Table/Models/BatchOperation.php index 7a10ef615..48dba2a0f 100644 --- a/src/Table/Models/BatchOperation.php +++ b/src/Table/Models/BatchOperation.php @@ -40,14 +40,7 @@ */ class BatchOperation { - /** - * @var string - */ private $_type; - - /** - * @var array - */ private $_params; /** diff --git a/src/Table/Models/BatchOperationParameterName.php b/src/Table/Models/BatchOperationParameterName.php index 095d8cdc4..98d8ad9e8 100644 --- a/src/Table/Models/BatchOperationParameterName.php +++ b/src/Table/Models/BatchOperationParameterName.php @@ -47,6 +47,8 @@ class BatchOperationParameterName * * @param string $paramName The batch operation parameter name. * + * @internal + * * @return boolean */ public static function isValid($paramName) diff --git a/src/Table/Models/BatchOperationType.php b/src/Table/Models/BatchOperationType.php index 8d17f0b32..0ac7b9599 100644 --- a/src/Table/Models/BatchOperationType.php +++ b/src/Table/Models/BatchOperationType.php @@ -48,6 +48,8 @@ class BatchOperationType * * @param string $type The operation type. * + * @internal + * * @return boolean */ public static function isValid($type) diff --git a/src/Table/Models/BatchOperations.php b/src/Table/Models/BatchOperations.php index bcb07f0d8..4437fce2e 100644 --- a/src/Table/Models/BatchOperations.php +++ b/src/Table/Models/BatchOperations.php @@ -39,9 +39,6 @@ */ class BatchOperations { - /** - * @var array - */ private $_operations; /** diff --git a/src/Table/Models/BatchResult.php b/src/Table/Models/BatchResult.php index 76b82a07c..e768e3340 100644 --- a/src/Table/Models/BatchResult.php +++ b/src/Table/Models/BatchResult.php @@ -26,8 +26,8 @@ use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Utilities; -use MicrosoftAzure\Storage\Common\Internal\HttpFormatter; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Internal\Http\HttpFormatter; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Common\Internal\ServiceRestProxy; use MicrosoftAzure\Storage\Table\Models\BatchError; use MicrosoftAzure\Storage\Table\Models\InsertEntityResult; @@ -48,11 +48,6 @@ */ class BatchResult { - /** - * Each entry represents change set result. - * - * @var array - */ private $_entries; /** diff --git a/src/Table/Models/DeleteEntityOptions.php b/src/Table/Models/DeleteEntityOptions.php index f7c26c708..f4a88b2c8 100644 --- a/src/Table/Models/DeleteEntityOptions.php +++ b/src/Table/Models/DeleteEntityOptions.php @@ -39,9 +39,6 @@ */ class DeleteEntityOptions extends TableServiceOptions { - /** - * @var string - */ private $_etag; /** diff --git a/src/Table/Models/EdmType.php b/src/Table/Models/EdmType.php index 0fc27b586..344d3aed1 100644 --- a/src/Table/Models/EdmType.php +++ b/src/Table/Models/EdmType.php @@ -56,6 +56,8 @@ class EdmType * * @param string $type The Edm type * + * @internal + * * @return string */ public static function processType($type) @@ -73,6 +75,8 @@ public static function processType($type) * @param mixed $value The EDM value. * @param string &$condition The error message. * + * @internal + * * @return boolean * * @throws \InvalidArgumentException @@ -96,7 +100,7 @@ public static function validateEdmValue($type, $value, &$condition = null) case EdmType::DOUBLE: $condition = 'is_double'; - return is_double($value); + return is_double($value) || is_int($value); case EdmType::INT32: $condition = 'is_int'; @@ -122,6 +126,8 @@ public static function validateEdmValue($type, $value, &$condition = null) * @param string $type The EDM type. * @param mixed $value The EDM value. * + * @internal + * * @return string * * @throws \InvalidArgumentException @@ -158,6 +164,8 @@ public static function serializeValue($type, $value) * @param string $type The EDM type. * @param mixed $value The EDM value. * + * @internal + * * @return string * * @throws \InvalidArgumentException @@ -201,6 +209,8 @@ public static function serializeQueryValue($type, $value) * @param string $type The edm type. * @param string $value The edm value. * + * @internal + * * @return mixed * * @throws \InvalidArgumentException @@ -246,6 +256,8 @@ public static function unserializeQueryValue($type, $value) * * @param string $type The type string to check. * + * @internal + * * @return boolean */ public static function isValid($type) diff --git a/src/Table/Models/Entity.php b/src/Table/Models/Entity.php index a0fa40136..68e062aba 100644 --- a/src/Table/Models/Entity.php +++ b/src/Table/Models/Entity.php @@ -40,14 +40,7 @@ */ class Entity { - /** - * @var string - */ private $_etag; - - /** - * @var array - */ private $_properties; /** @@ -269,6 +262,8 @@ public function addProperty($name, $edmType, $value) * * @param string &$msg The error message. * + * @internal + * * @return boolean */ public function isValid(&$msg = null) diff --git a/src/Table/Models/Filters/BinaryFilter.php b/src/Table/Models/Filters/BinaryFilter.php index 961064e9a..e832d2b34 100644 --- a/src/Table/Models/Filters/BinaryFilter.php +++ b/src/Table/Models/Filters/BinaryFilter.php @@ -36,19 +36,8 @@ */ class BinaryFilter extends Filter { - /** - * @var string - */ private $_operator; - - /** - * @var Filter - */ private $_left; - - /** - * @var Filter - */ private $_right; /** diff --git a/src/Table/Models/Filters/ConstantFilter.php b/src/Table/Models/Filters/ConstantFilter.php index d75e26887..5aaf07d57 100644 --- a/src/Table/Models/Filters/ConstantFilter.php +++ b/src/Table/Models/Filters/ConstantFilter.php @@ -38,14 +38,7 @@ */ class ConstantFilter extends Filter { - /** - * @var mixed - */ private $_value; - - /** - * @var string - */ private $_edmType; /** diff --git a/src/Table/Models/Filters/PropertyNameFilter.php b/src/Table/Models/Filters/PropertyNameFilter.php index d42c87ebf..24dd205e1 100644 --- a/src/Table/Models/Filters/PropertyNameFilter.php +++ b/src/Table/Models/Filters/PropertyNameFilter.php @@ -25,7 +25,7 @@ namespace MicrosoftAzure\Storage\Table\Models\Filters; /** - * Constant filter + * Property name filter * * @category Microsoft * @package MicrosoftAzure\Storage\Table\Models\Filters @@ -36,9 +36,6 @@ */ class PropertyNameFilter extends Filter { - /** - * @var string - */ private $_propertyName; /** diff --git a/src/Table/Models/Filters/UnaryFilter.php b/src/Table/Models/Filters/UnaryFilter.php index 5b791393f..0104f9343 100644 --- a/src/Table/Models/Filters/UnaryFilter.php +++ b/src/Table/Models/Filters/UnaryFilter.php @@ -36,14 +36,7 @@ */ class UnaryFilter extends Filter { - /** - * @var string - */ private $_operator; - - /** - * @var Filter - */ private $_operand; /** diff --git a/src/Table/Models/GetEntityResult.php b/src/Table/Models/GetEntityResult.php index d0a920398..c017f10e2 100644 --- a/src/Table/Models/GetEntityResult.php +++ b/src/Table/Models/GetEntityResult.php @@ -38,9 +38,6 @@ */ class GetEntityResult { - /** - * @var Entity - */ private $_entity; /** @@ -65,6 +62,16 @@ protected function setEntity($entity) $this->_entity = $entity; } + /** + * Create GetEntityResult object from HTTP response parts. + * + * @param string $body The HTTP response body. + * @param IAtomReaderWriter $atomSerializer The atom reader and writer. + * + * @internal + * + * @return GetEntityResult + */ public static function create($body, IAtomReaderWriter $serializer) { $result = new GetEntityResult(); diff --git a/src/Table/Models/GetTableResult.php b/src/Table/Models/GetTableResult.php index 39ba10e7d..e7fdbb5b3 100644 --- a/src/Table/Models/GetTableResult.php +++ b/src/Table/Models/GetTableResult.php @@ -39,9 +39,6 @@ */ class GetTableResult { - /** - * @var string - */ private $_name; /** @@ -50,6 +47,8 @@ class GetTableResult * @param string $body The HTTP response body. * @param AtomReaderWriter $atomSerializer The Atom reader and writer. * + * @internal + * * @return GetTableResult */ public static function create($body, $atomSerializer) diff --git a/src/Table/Models/InsertEntityResult.php b/src/Table/Models/InsertEntityResult.php index f17afd948..faac79467 100644 --- a/src/Table/Models/InsertEntityResult.php +++ b/src/Table/Models/InsertEntityResult.php @@ -40,9 +40,6 @@ */ class InsertEntityResult { - /** - * @var Entity - */ private $_entity; /** @@ -52,9 +49,9 @@ class InsertEntityResult * @param array $headers The HTTP response headers. * @param IAtomReaderWriter $atomSerializer The atom reader and writer. * - * @return InsertEntityResult + * @internal * - * @static + * @return InsertEntityResult */ public static function create($body, $headers, $atomSerializer) { diff --git a/src/Table/Models/Property.php b/src/Table/Models/Property.php index adbc705df..5361ad402 100644 --- a/src/Table/Models/Property.php +++ b/src/Table/Models/Property.php @@ -40,14 +40,7 @@ */ class Property { - /** - * @var string - */ private $_edmType; - - /** - * @var mixed - */ private $_value; /** diff --git a/src/Table/Models/Query.php b/src/Table/Models/Query.php index 71cd3b4ee..8444b647a 100644 --- a/src/Table/Models/Query.php +++ b/src/Table/Models/Query.php @@ -36,19 +36,8 @@ */ class Query { - /** - * @var array - */ private $_selectFields; - - /** - * @var Filters\Filter - */ private $_filter; - - /** - * @var integer - */ private $_top; /** diff --git a/src/Table/Models/QueryEntitiesOptions.php b/src/Table/Models/QueryEntitiesOptions.php index 0c0b61039..9461f5936 100644 --- a/src/Table/Models/QueryEntitiesOptions.php +++ b/src/Table/Models/QueryEntitiesOptions.php @@ -36,19 +36,8 @@ */ class QueryEntitiesOptions extends TableServiceOptions { - /** - * @var Query - */ private $_query; - - /** - * @var string - */ private $_nextPartitionKey; - - /** - * @var string - */ private $_nextRowKey; /** diff --git a/src/Table/Models/QueryEntitiesResult.php b/src/Table/Models/QueryEntitiesResult.php index 4ca7ccb20..7ee422210 100644 --- a/src/Table/Models/QueryEntitiesResult.php +++ b/src/Table/Models/QueryEntitiesResult.php @@ -39,19 +39,8 @@ */ class QueryEntitiesResult { - /** - * @var Query - */ private $_nextRowKey; - - /** - * @var string - */ private $_nextPartitionKey; - - /** - * @var array - */ private $_entities; /** @@ -60,6 +49,8 @@ class QueryEntitiesResult * @param array $headers The HTTP response headers. * @param array $entities The entities. * + * @internal + * * @return QueryEntitiesResult */ public static function create(array $headers, array $entities) diff --git a/src/Table/Models/QueryTablesOptions.php b/src/Table/Models/QueryTablesOptions.php index 0eefba1fb..cf86e7b5e 100644 --- a/src/Table/Models/QueryTablesOptions.php +++ b/src/Table/Models/QueryTablesOptions.php @@ -36,19 +36,8 @@ */ class QueryTablesOptions extends TableServiceOptions { - /** - * @var string - */ private $_nextTableName; - - /** - * @var Query - */ private $_query; - - /** - * @var string - */ private $_prefix; /** diff --git a/src/Table/Models/QueryTablesResult.php b/src/Table/Models/QueryTablesResult.php index c279ac2d6..40f76c905 100644 --- a/src/Table/Models/QueryTablesResult.php +++ b/src/Table/Models/QueryTablesResult.php @@ -39,14 +39,7 @@ */ class QueryTablesResult { - /** - * @var string - */ private $_nextTableName; - - /** - * @var array - */ private $_tables; /** @@ -55,6 +48,8 @@ class QueryTablesResult * @param array $headers The HTTP response headers * @param array $entries The table entriess * + * @internal + * * @return QueryTablesResult */ public static function create(array $headers, array $entries) diff --git a/src/Table/Models/TableACL.php b/src/Table/Models/TableACL.php new file mode 100644 index 000000000..ff7e0281b --- /dev/null +++ b/src/Table/Models/TableACL.php @@ -0,0 +1,88 @@ + + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ + +namespace MicrosoftAzure\Storage\Table\Models; + +use MicrosoftAzure\Storage\Common\Internal\Validate; +use MicrosoftAzure\Storage\Common\Internal\Resources; +use MicrosoftAzure\Storage\Common\Internal\ACLBase; + +/** + * Holds table ACL members. + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Table\Models + * @author Azure Storage PHP SDK + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +class TableACL extends ACLBase +{ + /** + * Constructor. + */ + public function __construct() + { + //setting the resource type to a default value. + $this->setResourceType(Resources::RESOURCE_TYPE_TABLE); + } + + /** + * Parses the given array into signed identifiers and create an instance of + * TableACL + * + * @param array $parsed The parsed response into array representation. + * + * @internal + * + * @return TableACL + */ + public static function create(array $parsed = null) + { + $result = new TableACL(); + $result->fromXmlArray($parsed); + + return $result; + } + + /** + * Validate if the resource type for the class. + * + * @param string $resourceType the resource type to be validated. + * + * @throws \InvalidArgumentException + * + * @internal + * + * @return void + */ + protected static function validateResourceType($resourceType) + { + Validate::isTrue( + $resourceType == Resources::RESOURCE_TYPE_TABLE, + Resources::INVALID_RESOURCE_TYPE + ); + } +} diff --git a/src/Table/Models/TableServiceOptions.php b/src/Table/Models/TableServiceOptions.php index d530a2fb5..292043481 100644 --- a/src/Table/Models/TableServiceOptions.php +++ b/src/Table/Models/TableServiceOptions.php @@ -24,7 +24,7 @@ namespace MicrosoftAzure\Storage\Table\Models; -use MicrosoftAzure\Storage\Common\ServiceOptionsBase; +use MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase; /** * Table service options. diff --git a/src/Table/Models/UpdateEntityResult.php b/src/Table/Models/UpdateEntityResult.php index 0068a2f78..6d7249e57 100644 --- a/src/Table/Models/UpdateEntityResult.php +++ b/src/Table/Models/UpdateEntityResult.php @@ -39,9 +39,6 @@ */ class UpdateEntityResult { - /** - * @var string - */ private $_etag; /** @@ -49,6 +46,8 @@ class UpdateEntityResult * * @param array $headers The HTTP response headers. * + * @internal + * * @return UpdateEntityResult */ public static function create(array $headers) diff --git a/src/Table/TableRestProxy.php b/src/Table/TableRestProxy.php index bb2081863..1b70de5d7 100644 --- a/src/Table/TableRestProxy.php +++ b/src/Table/TableRestProxy.php @@ -53,7 +53,8 @@ use MicrosoftAzure\Storage\Table\Models\BatchOperationType; use MicrosoftAzure\Storage\Table\Models\BatchOperationParameterName; use MicrosoftAzure\Storage\Table\Models\BatchResult; -use MicrosoftAzure\Storage\Common\Internal\HttpFormatter; +use MicrosoftAzure\Storage\Table\Models\TableACL; +use MicrosoftAzure\Storage\Common\Internal\Http\HttpFormatter; use MicrosoftAzure\Storage\Table\Internal\IAtomReaderWriter; use MicrosoftAzure\Storage\Table\Internal\IMimeReaderWriter; use MicrosoftAzure\Storage\Common\Internal\Serialization\ISerializer; @@ -1684,4 +1685,151 @@ public function batchAsync( ); }, null); } + + /** + * Gets the access control list (ACL) + * + * @param string $table The table name. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return Models\TableACL + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-table-acl + */ + public function getTableAcl( + $table, + Models\TableServiceOptions $options = null + ) { + return $this->getTableAclAsync($table, $options)->wait(); + } + + /** + * Creates the promise to gets the access control list (ACL) + * + * @param string $table The table name. + * @param Models\TableServiceOptions $options The optional parameters. + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-table-acl + */ + public function getTableAclAsync( + $table, + Models\TableServiceOptions $options = null + ) { + Validate::isString($table, 'table'); + + $method = Resources::HTTP_GET; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $statusCode = Resources::STATUS_OK; + $path = $table; + + if (is_null($options)) { + $options = new TableServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'acl' + ); + + $dataSerializer = $this->dataSerializer; + + $promise = $this->sendAsync( + $method, + $headers, + $queryParams, + $postParams, + $path, + Resources::STATUS_OK, + Resources::EMPTY_STRING, + $options->getRequestOptions() + ); + + return $promise->then(function ($response) use ($dataSerializer) { + $parsed = $dataSerializer->unserialize($response->getBody()); + return TableACL::create($parsed); + }, null); + } + + /** + * Sets the ACL. + * + * @param string $table name + * @param Models\TableACL $acl access control list for Table + * @param Models\TableServiceOptions $options optional parameters + * + * @return void + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-table-acl + */ + public function setTableAcl( + $table, + Models\TableACL $acl, + Models\TableServiceOptions $options = null + ) { + $this->setTableAclAsync($table, $acl, $options)->wait(); + } + + /** + * Creates promise to set the ACL + * + * @param string $table name + * @param Models\TableACL $acl access control list for Table + * @param Models\TableServiceOptions $options optional parameters + * + * @return \GuzzleHttp\Promise\PromiseInterface + * + * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-table-acl + */ + public function setTableAclAsync( + $table, + Models\TableACL $acl, + Models\TableServiceOptions $options = null + ) { + Validate::isString($table, 'table'); + Validate::notNullOrEmpty($acl, 'acl'); + + $method = Resources::HTTP_PUT; + $headers = array(); + $postParams = array(); + $queryParams = array(); + $body = $acl->toXml($this->dataSerializer); + $path = $table; + + if (is_null($options)) { + $options = new TableServiceOptions(); + } + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_TIMEOUT, + $options->getTimeout() + ); + + $this->addOptionalQueryParam( + $queryParams, + Resources::QP_COMP, + 'acl' + ); + + return $this->sendAsync( + $method, + $headers, + $queryParams, + $postParams, + $path, + Resources::STATUS_NO_CONTENT, + $body, + $options->getRequestOptions() + ); + } } diff --git a/tests/framework/BlobServiceRestProxyTestBase.php b/tests/framework/BlobServiceRestProxyTestBase.php index b4809dcd9..40a87e7c9 100644 --- a/tests/framework/BlobServiceRestProxyTestBase.php +++ b/tests/framework/BlobServiceRestProxyTestBase.php @@ -27,7 +27,7 @@ use MicrosoftAzure\Storage\Tests\Framework\ServiceRestProxyTestBase; use MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions; use MicrosoftAzure\Storage\Blob\Models\ListContainersOptions; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; /** * TestBase class for each unit test class. diff --git a/tests/framework/ReflectionTestBase.php b/tests/framework/ReflectionTestBase.php index 5f807b33c..6174c0978 100644 --- a/tests/framework/ReflectionTestBase.php +++ b/tests/framework/ReflectionTestBase.php @@ -32,4 +32,12 @@ protected static function getMethod($name, $object) $method->setAccessible(true); return $method; } + + protected static function setProperty($name, $object, $value) + { + $reflection = new \ReflectionClass($object); + $reflection_property = $reflection->getProperty($name); + $reflection_property->setAccessible(true); + $reflection_property->setValue($object, $value); + } } diff --git a/tests/framework/RestProxyTestBase.php b/tests/framework/RestProxyTestBase.php index 50ce2d606..604d89fbb 100644 --- a/tests/framework/RestProxyTestBase.php +++ b/tests/framework/RestProxyTestBase.php @@ -24,7 +24,7 @@ namespace MicrosoftAzure\Storage\Tests\framework; -use MicrosoftAzure\Storage\Common\Internal\Logger; +use MicrosoftAzure\Storage\Common\Logger; use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; use MicrosoftAzure\Storage\Common\ServicesBuilder; diff --git a/tests/framework/TestResources.php b/tests/framework/TestResources.php index 9f997eace..f7f3b5c72 100644 --- a/tests/framework/TestResources.php +++ b/tests/framework/TestResources.php @@ -51,7 +51,7 @@ class TestResources const KEY1 = 'key1'; const KEY2 = 'key2'; const KEY3 = 'key3'; - const KEY4 = 'AhlzsbLRkjfwObuqff3xrhB2yWJNh1EMptmcmxFJ6fvPTVX3PZXwrG2YtYWf5DPMVgNsteKStM5iBLlknYFVoA=='; + const KEY4 = 'AhlzsbLRkjfwObuqff3xrhB2yWJNh1EMptmcmxFJ6fvPTVX3PZXwrG2YtYWf5DPMVgNsteKStM5iBLlknYFVoA=='; //Faked although looks real. const VALUE1 = 'value1'; const VALUE2 = 'value2'; const VALUE3 = 'value3'; @@ -109,6 +109,98 @@ class TestResources const STATUS_PRECONDITION_FAILED = 412; const STATUS_INTERNAL_SERVER_ERROR = 500; + public static function getInterestingName($prefix) + { + $rint = mt_rand(0, 1000000); + return $prefix . $rint . 'ft'; + } + + public static function getSASInterestingUTCases() + { + $testCases = array(); + + // The SAS token is all generated with fake key. + $testCases[] = [ + "2016-05-31", // signedVersion + "rwdlacup", // signedPermission + "bfqt", // signedService + "sco", // signedResourceType + "2017-03-24T21:14:01Z", // signedExpiracy + "2017-03-17T13:14:01Z", // signedStart + "", // signedIP + "https", // signedProtocol + "sv%3D2016-05-31%26ss%3Dbqtf%26srt%3Dsco%26sp%3Drwdlacup%26se%3D2017-03-24T21%3A14%3A01Z%26st%3D2017-03-17T13%3A14%3A01Z%26spr%3Dhttps%26sig%3DiApmwEEGPc6EqjvBCekfEons2NRs7aGC1frKyWEO8g8%253D" // expectedSignature + ]; + + $testCases[] = [ + "2016-05-31", // signedVersion + "rwdlacup", // signedPermission + "bfqt", // signedService + "sco", // signedResourceType + "2017-03-24T21:14:01Z", // signedExpiracy + "2017-03-17T13:14:01Z", // signedStart + "168.1.5.65", // signedIP + "https,http", // signedProtocol + "sv%3D2016-05-31%26ss%3Dbqtf%26srt%3Dsco%26sp%3Drwdlacup%26se%3D2017-03-24T21%3A14%3A01Z%26st%3D2017-03-17T13%3A14%3A01Z%26sip%3D168.1.5.65%26spr%3Dhttps%2Chttp%26sig%3D2FT%252FEl0rqE1uwVODaKzBNQKHJeJM3vUsGbr%252FQtwLVcs%253D" // expectedSignature + ]; + + $testCases[] = [ + "2016-05-31", // signedVersion + "rw", // signedPermission + "bf", // signedService + "s", // signedResourceType + "2017-03-24T00:00:00Z", // signedExpiracy + "2017-03-17T00:00:00Z", // signedStart + "", // signedIP + "https", // signedProtocol + "sv%3D2016-05-31%26ss%3Dbf%26srt%3Ds%26sp%3Drw%26se%3D2017-03-24T00%3A00%3A00Z%26st%3D2017-03-17T00%3A00%3A00Z%26spr%3Dhttps%26sig%3DoSxrFQuddGNRUJYab3jU7nhcoSgJaceA%252FFH9EY5istY%253D" // expectedSignature + ]; + + $testCases[] = [ + "2016-05-31", // signedVersion + "up", // signedPermission + "q", // signedService + "o", // signedResourceType + "2017-03-24T00:00:00Z", // signedExpiracy + "2017-03-17T00:00:00Z", // signedStart + "", // signedIP + "https", // signedProtocol + "sv%3D2016-05-31%26ss%3Dq%26srt%3Do%26sp%3Dup%26se%3D2017-03-24T00%3A00%3A00Z%26st%3D2017-03-17T00%3A00%3A00Z%26spr%3Dhttps%26sig%3D4fMFk%252BFE%252BE90wTPMCGY%252FF%252FplPrDM%252BO8veJi1GmY5wWA%253D" // expectedSignature + ]; + + return $testCases; + } + + public static function getValidAccessPermission() + { + $result = array(); + $result['Blob'][] = ['dwcar', 'racwd']; + $result['Blob'][] = ['waradadawadaca', 'racwd']; + $result['Container'][] = ['ldwcar', 'racwdl']; + $result['Container'][] = ['rcal', 'racl']; + $result['Table'][] = ['dar', 'rad']; + $result['Table'][] = ['duardduar', 'raud']; + $result['Queue'][] = ['puar', 'raup']; + $result['Queue'][] = ['ppap', 'ap']; + + return $result; + } + + public static function getInvalidAccessPermission() + { + $result = array(); + $result['Blob'][] = 'dwcarl'; + $result['Blob'][] = 'waradadawadacap'; + $result['Container'][] = 'ldwcarsdf'; + $result['Container'][] = 'rcalfds'; + $result['Table'][] = 'darwer'; + $result['Table'][] = 'duardduaras'; + $result['Queue'][] = 'puarzxcv'; + $result['Queue'][] = '!ppap!'; + + return $result; + } + public static function getWindowsAzureStorageServicesConnectionString() { $connectionString = getenv('AZURE_STORAGE_CONNECTION_STRING'); @@ -228,6 +320,21 @@ private static function getEnvironmentVariable($name, $required = true) return $value; } + public static function getCORSSingle() + { + $sample = array(); + $sample['AllowedOrigins'] = + 'http://www.microsoft.com,http://www.bing.com'; + $sample['AllowedMethods'] = 'GET,PUT'; + $sample['MaxAgeInSeconds'] = '500'; + $sample['ExposedHeaders'] = + 'x-ms-meta-customheader0,x-ms-meta-data0*'; + $sample['AllowedHeaders'] = + 'x-ms-meta-customheader0,x-ms-meta-target0*'; + + return $sample; + } + public static function getServicePropertiesSample() { $sample = array(); @@ -242,6 +349,24 @@ public static function getServicePropertiesSample() $sample['HourMetrics']['IncludeAPIs'] = 'false'; $sample['HourMetrics']['RetentionPolicy']['Enabled'] = 'true'; $sample['HourMetrics']['RetentionPolicy']['Days'] = '20'; + //1st cors + $sample['Cors']['CorsRule'][0]['AllowedOrigins'] = + 'http://www.microsoft.com,http://www.bing.com'; + $sample['Cors']['CorsRule'][0]['AllowedMethods'] = 'GET,PUT'; + $sample['Cors']['CorsRule'][0]['MaxAgeInSeconds'] = '500'; + $sample['Cors']['CorsRule'][0]['ExposedHeaders'] = + 'x-ms-meta-customheader0,x-ms-meta-data0*'; + $sample['Cors']['CorsRule'][0]['AllowedHeaders'] = + 'x-ms-meta-customheader0,x-ms-meta-target0*'; + //2nd cors + $sample['Cors']['CorsRule'][1]['AllowedOrigins'] = + 'http://www.azure.com,http://www.office.com'; + $sample['Cors']['CorsRule'][1]['AllowedMethods'] = 'POST,HEAD'; + $sample['Cors']['CorsRule'][1]['MaxAgeInSeconds'] = '350'; + $sample['Cors']['CorsRule'][1]['ExposedHeaders'] = + 'x-ms-meta-customheader1,x-ms-meta-data1*'; + $sample['Cors']['CorsRule'][1]['AllowedHeaders'] = + 'x-ms-meta-customheader1,x-ms-meta-target1*'; return $sample; } @@ -260,6 +385,24 @@ public static function setServicePropertiesSample() $sample['HourMetrics']['IncludeAPIs'] = 'false'; $sample['HourMetrics']['RetentionPolicy']['Enabled'] = 'true'; $sample['HourMetrics']['RetentionPolicy']['Days'] = '10'; + //1st cors + $sample['Cors']['CorsRule'][0]['AllowedOrigins'] = + 'http://www.microsoft.com,http://www.bing.com'; + $sample['Cors']['CorsRule'][0]['AllowedMethods'] = 'GET,PUT'; + $sample['Cors']['CorsRule'][0]['MaxAgeInSeconds'] = '500'; + $sample['Cors']['CorsRule'][0]['ExposedHeaders'] = + 'x-ms-meta-customheader0,x-ms-meta-data0*'; + $sample['Cors']['CorsRule'][0]['AllowedHeaders'] = + 'x-ms-meta-customheader0,x-ms-meta-target0*'; + //2nd cors + $sample['Cors']['CorsRule'][1]['AllowedOrigins'] = + 'http://www.azure.com,http://www.office.com'; + $sample['Cors']['CorsRule'][1]['AllowedMethods'] = 'POST,HEAD'; + $sample['Cors']['CorsRule'][1]['MaxAgeInSeconds'] = '350'; + $sample['Cors']['CorsRule'][1]['ExposedHeaders'] = + 'x-ms-meta-customheader1,x-ms-meta-data1*'; + $sample['Cors']['CorsRule'][1]['AllowedHeaders'] = + 'x-ms-meta-customheader1,x-ms-meta-target1*'; return $sample; } @@ -398,8 +541,8 @@ public static function getContainerAclOneEntrySample() $sample['SignedIdentifiers'] = array('SignedIdentifier' => array( 'Id' => 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', 'AccessPolicy' => array( - 'Start' => '2009-09-28T08%3A49%3A37.0000000Z', - 'Expiry' => '2009-09-29T08%3A49%3A37.0000000Z', + 'Start' => Utilities::convertToEdmDateTime(self::getRandomEarlierTime()), + 'Expiry' => Utilities::convertToEdmDateTime(self::getRandomLaterTime()), 'Permission' => 'rwd') )); @@ -412,19 +555,167 @@ public static function getContainerAclMultipleEntriesSample() $sample['SignedIdentifiers'] = array( 'SignedIdentifier' => array( 0 => array('Id' => 'HYQzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', 'AccessPolicy' => array( - 'Start' => '2010-09-28T08%3A49%3A37.0000000Z', - 'Expiry' => '2010-09-29T08%3A49%3A37.0000000Z', + 'Start' => Utilities::convertToEdmDateTime(self::getRandomEarlierTime()), + 'Expiry' => Utilities::convertToEdmDateTime(self::getRandomLaterTime()), 'Permission' => 'wd')), 1 => array('Id' => 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', 'AccessPolicy' => array( - 'Start' => '2009-09-28T08%3A49%3A37.0000000Z', - 'Expiry' => '2009-09-29T08%3A49%3A37.0000000Z', + 'Start' => Utilities::convertToEdmDateTime(self::getRandomEarlierTime()), + 'Expiry' => Utilities::convertToEdmDateTime(self::getRandomLaterTime()), 'Permission' => 'rwd')) )); return $sample; } + public static function getQueueACLOneEntrySample() + { + $sample = array(); + $sample['SignedIdentifiers'] = array('SignedIdentifier' => array( + 'Id' => 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', + 'AccessPolicy' => array( + 'Start' => Utilities::convertToEdmDateTime(self::getRandomEarlierTime()), + 'Expiry' => Utilities::convertToEdmDateTime(self::getRandomLaterTime()), + 'Permission' => 'ap') + )); + + return $sample; + } + + public static function getQueueACLMultipleEntriesSample() + { + $sample = array(); + $sample['SignedIdentifiers'] = array( 'SignedIdentifier' => array( + 0 => array('Id' => 'HYQzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', + 'AccessPolicy' => array( + 'Start' => Utilities::convertToEdmDateTime(self::getRandomEarlierTime()), + 'Expiry' => Utilities::convertToEdmDateTime(self::getRandomLaterTime()), + 'Permission' => 'raup')), + 1 => array('Id' => 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', + 'AccessPolicy' => array( + 'Start' => Utilities::convertToEdmDateTime(self::getRandomEarlierTime()), + 'Expiry' => Utilities::convertToEdmDateTime(self::getRandomLaterTime()), + 'Permission' => 'ru')) + )); + + return $sample; + } + + public static function getQueueACLMultipleUnencodedEntriesSample() + { + $sample = array(); + $sample['SignedIdentifiers'] = array( 'SignedIdentifier' => array( + 0 => array('Id' => 'HYQzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', + 'AccessPolicy' => array( + 'Start' => Utilities::convertToEdmDateTime(self::getRandomEarlierTime()), + 'Expiry' => Utilities::convertToEdmDateTime(self::getRandomLaterTime()), + 'Permission' => 'raup')), + 1 => array('Id' => 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', + 'AccessPolicy' => array( + 'Start' => Utilities::convertToEdmDateTime(self::getRandomEarlierTime()), + 'Expiry' => Utilities::convertToEdmDateTime(self::getRandomLaterTime()), + 'Permission' => 'ru')) + )); + + return $sample; + } + + public static function getQueueACLMultipleArraySample() + { + $sample = array(); + $sample[] = [ + 'Id' => 'a', + 'AccessPolicy' => array( + 'Start' => self::getRandomEarlierTime(), + 'Expiry' => self::getRandomLaterTime(), + 'Permission' => 'raup') + ]; + $sample[] = [ + 'Id' => 'b', + 'AccessPolicy' => array( + 'Start' => self::getRandomEarlierTime(), + 'Expiry' => self::getRandomLaterTime(), + 'Permission' => 'raup') + ]; + $sample[] = [ + 'Id' => 'c', + 'AccessPolicy' => array( + 'Start' => self::getRandomEarlierTime(), + 'Expiry' => self::getRandomLaterTime(), + 'Permission' => 'raup') + ]; + $sample[] = [ + 'Id' => 'd', + 'AccessPolicy' => array( + 'Start' => self::getRandomEarlierTime(), + 'Expiry' => self::getRandomLaterTime(), + 'Permission' => 'raup') + ]; + $sample[] = [ + 'Id' => 'e', + 'AccessPolicy' => array( + 'Start' => self::getRandomEarlierTime(), + 'Expiry' => self::getRandomLaterTime(), + 'Permission' => 'raup') + ]; + $sample[] = [ + 'Id' => 'f', + 'AccessPolicy' => array( + 'Start' => self::getRandomEarlierTime(), + 'Expiry' => self::getRandomLaterTime(), + 'Permission' => 'raup') + ]; + + return $sample; + } + + public static function getTableACLOneEntrySample() + { + $sample = array(); + $sample['SignedIdentifiers'] = array('SignedIdentifier' => array( + 'Id' => 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', + 'AccessPolicy' => array( + 'Start' => Utilities::convertToEdmDateTime(self::getRandomEarlierTime()), + 'Expiry' => Utilities::convertToEdmDateTime(self::getRandomLaterTime()), + 'Permission' => 'ad') + )); + + return $sample; + } + + public static function getTableACLMultipleEntriesSample() + { + $sample = array(); + $sample['SignedIdentifiers'] = array( 'SignedIdentifier' => array( + 0 => array('Id' => 'HYQzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', + 'AccessPolicy' => array( + 'Start' => Utilities::convertToEdmDateTime(self::getRandomEarlierTime()), + 'Expiry' => Utilities::convertToEdmDateTime(self::getRandomLaterTime()), + 'Permission' => 'raud')), + 1 => array('Id' => 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', + 'AccessPolicy' => array( + 'Start' => Utilities::convertToEdmDateTime(self::getRandomEarlierTime()), + 'Expiry' => Utilities::convertToEdmDateTime(self::getRandomLaterTime()), + 'Permission' => 'ru')) + )); + + return $sample; + } + + public static function getRandomLaterTime() + { + $interval = mt_rand(10000, 65535); + $now = new \DateTime(); + return $now->add(\DateInterval::createFromDateString($interval . ' seconds')); + } + + public static function getRandomEarlierTime() + { + $interval = mt_rand(10000, 65535); + $now = new \DateTime(); + return $now->sub(\DateInterval::createFromDateString($interval . ' seconds')); + } + public static function listBlobsEmpty() { $sample = array(); @@ -599,7 +890,7 @@ public static function getTestEntity($partitionKey, $rowKey) $entity->addProperty('CustomerId', EdmType::INT32, 890); $entity->addProperty('CustomerName', null, 'John'); $entity->addProperty('IsNew', EdmType::BOOLEAN, true); - $entity->addProperty('JoinDate', EdmType::DATETIME, Utilities::convertToDateTime('2012-01-26T18:26:19.0000473Z')); + $entity->addProperty('JoinDate', EdmType::DATETIME, Utilities::convertToDateTime('2012-01-26T18:26:19.0000470Z')); return $entity; } @@ -613,7 +904,7 @@ public static function getExpectedTestEntity($partitionKey, $rowKey) $entity->addProperty('CustomerId', EdmType::INT32, 890); $entity->addProperty('CustomerName', EdmType::STRING, 'John'); $entity->addProperty('IsNew', EdmType::BOOLEAN, true); - $entity->addProperty('JoinDate', EdmType::DATETIME, Utilities::convertToDateTime('2012-01-26T18:26:19.0000473Z')); + $entity->addProperty('JoinDate', EdmType::DATETIME, Utilities::convertToDateTime('2012-01-26T18:26:19.0000470Z')); return $entity; } @@ -679,6 +970,39 @@ public static function getBatchOperations() return $operations; } + public static function getInterestingAccountSASTestCase( + $signedPermissions, + $signedService, + $signedResourceType, + $signedExpiracy = "", + $signedStart = "", + $signedIP = "" + ) { + if ($signedExpiracy == "") { + $signedExpiracy = (self::getRandomLaterTime()->format('Y-m-d\TH:i:s\Z')); + } + + if ($signedStart == "") { + $signedStart = (self::getRandomEarlierTime()->format('Y-m-d\TH:i:s\Z')); + } + + if ($signedIP == "") { + $signedIP = "0.0.0.0-255.255.255.255"; + } + + $result = array(); + $result['signedVersion'] = Resources::STORAGE_API_LATEST_VERSION; + $result['signedPermissions'] = $signedPermissions; + $result['signedService'] = $signedService; + $result['signedResourceType'] = $signedResourceType; + $result['signedExpiracy'] = $signedExpiracy; + $result['signedStart'] = $signedStart; + $result['signedIP'] = $signedIP; + $result['signedProtocol'] = 'https,http'; + + return $result; + } + public static function getExpectedBatchResultEntries() { $entityResult1 = UpdateEntityResult::create( diff --git a/tests/functional/Blob/BlobServiceFunctionalTest.php b/tests/functional/Blob/BlobServiceFunctionalTest.php index 5de8fafae..a465a2ca7 100644 --- a/tests/functional/Blob/BlobServiceFunctionalTest.php +++ b/tests/functional/Blob/BlobServiceFunctionalTest.php @@ -39,15 +39,16 @@ use MicrosoftAzure\Storage\Blob\Models\PublicAccessType; use MicrosoftAzure\Storage\Blob\Models\SetBlobMetadataOptions; use MicrosoftAzure\Storage\Blob\Models\SetContainerMetadataOptions; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\StorageServiceSettings; use MicrosoftAzure\Storage\Common\Internal\Utilities; -use MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory; -use MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware; +use MicrosoftAzure\Storage\Common\Middlewares\RetryMiddlewareFactory; +use MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\Psr7\Response; +use GuzzleHttp\Client; class BlobServiceFunctionalTest extends FunctionalTestBase { @@ -274,6 +275,8 @@ private function setServicePropertiesWorker($serviceProperties, $options) } else { $this->assertFalse($this->isEmulated(), 'Should succeed when not running in emulator'); } + + \sleep(10); $ret = (is_null($options) ? $this->restProxy->getServiceProperties() : @@ -1194,14 +1197,17 @@ private function verifySetContainerACLWorker($ret, $container, $acl, $blobConten private function canDownloadFromUrl($blobAddress, $expectedStartingValue) { - $url = parse_url($blobAddress); - $host = $url['host']; - $fp = fsockopen($host, '80'); - $request = 'GET ' . $blobAddress . ' HTTP/1.1' . "\r\n" . 'Host: ' . $host ."\r\n\r\n"; - fputs($fp, $request); - $value = fread($fp, 1000); - fclose($fp); - return strpos($value, $expectedStartingValue) !== false; + $client = new Client(); + $body = ''; + try { + $response = $client->request('GET', $blobAddress); + $body = $response->getBody(); + } catch (RequestException $e) { + if ($e->hasResponse()) { + $body = $e->getResponse()->getBody(); + } + } + return strpos($body, $expectedStartingValue) !== false; } /** diff --git a/tests/functional/Blob/BlobServiceFunctionalTestData.php b/tests/functional/Blob/BlobServiceFunctionalTestData.php index fdd2b6f44..6e00fdcc3 100644 --- a/tests/functional/Blob/BlobServiceFunctionalTestData.php +++ b/tests/functional/Blob/BlobServiceFunctionalTestData.php @@ -24,6 +24,7 @@ namespace MicrosoftAzure\Storage\Tests\functional\Blob; +use MicrosoftAzure\Storage\Tests\Framework\TestResources; use MicrosoftAzure\Storage\Blob\Models\AccessCondition; use MicrosoftAzure\Storage\Blob\Models\ContainerAcl; use MicrosoftAzure\Storage\Blob\Models\CopyBlobOptions; @@ -43,6 +44,7 @@ use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Models\Logging; use MicrosoftAzure\Storage\Common\Models\Metrics; +use MicrosoftAzure\Storage\Common\Models\CORS; use MicrosoftAzure\Storage\Common\Models\RetentionPolicy; use MicrosoftAzure\Storage\Common\Models\ServiceProperties; @@ -259,9 +261,12 @@ public static function getInterestingServiceProperties() $m->setEnabled(true); $m->setIncludeAPIs(true); + $c = CORS::create(TestResources::getCORSSingle()); + $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setMetrics($m); + $sp->setCorses(array($c)); array_push($ret, $sp); } @@ -287,9 +292,15 @@ public static function getInterestingServiceProperties() $m->setEnabled(true); $m->setIncludeAPIs(true); + $csArray = + TestResources::getServicePropertiesSample()[Resources::XTAG_CORS]; + $c0 = CORS::create($csArray[Resources::XTAG_CORS_RULE][0]); + $c1 = CORS::create($csArray[Resources::XTAG_CORS_RULE][1]); + $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setMetrics($m); + $sp->setCorses(array($c0, $c1)); array_push($ret, $sp); } @@ -315,10 +326,16 @@ public static function getInterestingServiceProperties() $m->setIncludeAPIs(null); $m->setRetentionPolicy($rp); + $csArray = + TestResources::getServicePropertiesSample()[Resources::XTAG_CORS]; + $c0 = CORS::create($csArray[Resources::XTAG_CORS_RULE][0]); + $c1 = CORS::create($csArray[Resources::XTAG_CORS_RULE][1]); + $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setMetrics($m); - + $sp->setCorses(array($c0, $c1)); + array_push($ret, $sp); } diff --git a/tests/functional/Blob/BlobServiceIntegrationTest.php b/tests/functional/Blob/BlobServiceIntegrationTest.php index 05879a383..2b5091ffd 100644 --- a/tests/functional/Blob/BlobServiceIntegrationTest.php +++ b/tests/functional/Blob/BlobServiceIntegrationTest.php @@ -41,7 +41,7 @@ use MicrosoftAzure\Storage\Blob\Models\PageRange; use MicrosoftAzure\Storage\Blob\Models\PublicAccessType; use MicrosoftAzure\Storage\Blob\Models\SetBlobPropertiesOptions; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Common\Internal\Utilities; class BlobServiceIntegrationTest extends IntegrationTestBase diff --git a/tests/functional/Blob/FunctionalTestBase.php b/tests/functional/Blob/FunctionalTestBase.php index 8fc935fa9..9ab0f1886 100644 --- a/tests/functional/Blob/FunctionalTestBase.php +++ b/tests/functional/Blob/FunctionalTestBase.php @@ -24,7 +24,7 @@ namespace MicrosoftAzure\Storage\Tests\functional\Blob; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Common\Internal\StorageServiceSettings; class FunctionalTestBase extends IntegrationTestBase diff --git a/tests/functional/Common/AccountSASFunctionalTest.php b/tests/functional/Common/AccountSASFunctionalTest.php new file mode 100644 index 000000000..a29c9180f --- /dev/null +++ b/tests/functional/Common/AccountSASFunctionalTest.php @@ -0,0 +1,496 @@ + + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ + +namespace MicrosoftAzure\Storage\Tests\functional\Common; + +use MicrosoftAzure\Storage\Common\ServicesBuilder; +use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; +use MicrosoftAzure\Storage\Common\Internal\Resources; +use MicrosoftAzure\Storage\Common\Internal\StorageServiceSettings; +use MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper; +use MicrosoftAzure\Storage\Tests\framework\TestResources; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; + +/** + * Testbase for all REST proxy tests. + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Tests\Framework + * @author Azure Storage PHP SDK + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +class AccountSASFunctionalTest extends \PHPUnit_Framework_TestCase +{ + protected $connectionString; + protected $xmlSerializer; + protected $builder; + protected $serviceSettings; + protected $createdContainer; + protected $createdTable; + protected $createdQueue; + protected $blobRestProxy; + protected $tableRestProxy; + protected $queueRestProxy; + + public function __construct() + { + $this->xmlSerializer = new XmlSerializer(); + $this->builder = new ServicesBuilder(); + $this->connectionString = TestResources::getWindowsAzureStorageServicesConnectionString(); + $this->serviceSettings = + StorageServiceSettings::createFromConnectionString( + $this->connectionString + ); + } + + protected function setUp() + { + parent::setUp(); + $this->createdContainer = array(); + $this->createdTable = array(); + $this->createdQueue = array(); + $this->blobRestProxy = null; + $this->tableRestProxy = null; + $this->queueRestProxy = null; + } + + protected function tearDown() + { + if ($this->blobRestProxy != null) { + foreach ($this->createdContainer as $container) { + $this->safeDeleteContainer($container); + } + } + + if ($this->tableRestProxy != null) { + foreach ($this->createdTable as $table) { + $this->safeDeleteTable($table); + } + } + + if ($this->queueRestProxy != null) { + foreach ($this->createdQueue as $queue) { + $this->safeDeleteQueue($queue); + } + } + } + + /** + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::__construct + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::generateAccountSharedAccessSignatureToken + */ + public function testServiceAccountSASPositive() + { + $helper = new SharedAccessSignatureHelperMock( + $this->serviceSettings->getName(), + $this->serviceSettings->getKey() + ); + + //Full permission + $this->initializeProxiesWithSASfromArray( + $helper, + TestResources::getInterestingAccountSASTestCase( + 'pucaldwr', + 'ftqb', + 'ocs' + ) + ); + + //Validate 'rwdlc' + $container = TestResources::getInterestingName('con'); + $count0 = count($this->blobRestProxy->listContainers()->getContainers()); + $this->safeCreateContainer($container); + $count1 = count($this->blobRestProxy->listContainers()->getContainers()); + $this->assertEquals( + $count0 + 1, + $count1, + sprintf("Expected %d container(s), listed %d container(s).", $count0 + 1, $count1) + ); + $blob = TestResources::getInterestingName('blob'); + $content = 'test content'; + $this->blobRestProxy->createBlockBlob($container, $blob, $content); + $getContent = stream_get_contents($this->blobRestProxy->getBlob($container, $blob)->getContentStream()); + $this->assertEquals($content, $getContent, "Expected {$content}, got {$getContent}."); + $this->safeDeleteContainer($container); + $count1 = count($this->blobRestProxy->listContainers()->getContainers()); + $this->assertEquals( + $count0, + $count1, + sprintf("Expected %d container(s), listed %d container(s).", $count0, $count1) + ); + + //Validate 'aup' + $queue = TestResources::getInterestingName('queue'); + $count0 = count($this->queueRestProxy->listQueues()->getQueues()); + $this->safeCreateQueue($queue); + $count1 = count($this->queueRestProxy->listQueues()->getQueues()); + $this->assertEquals( + $count0 + 1, + $count1, + sprintf("Expected %d queue(s), listed %d queue(s).", $count0 + 1, $count1) + ); + $message = TestResources::getInterestingName('message'); + $content = 'test content'; + $this->queueRestProxy->createMessage($queue, $content); + $messages = $this->queueRestProxy->listMessages($queue)->getQueueMessages(); + $found = false; + $resultMessage = null; + foreach ($messages as $value) { + if ($value->getMessageText() === $content) { + $found = true; + $resultMessage = $value; + break; + } + } + $this->assertTrue($found, "Created message not found in the specified queue"); + $count3 = count($messages); + $this->queueRestProxy->deleteMessage( + $queue, + $resultMessage->getMessageId(), + $resultMessage->getPopReceipt() + ); + $count1 = count($this->queueRestProxy->listMessages($queue)->getQueueMessages()); + $this->assertEquals( + $count3 - 1, + $count1, + sprintf("Expected %d messages(s), listed %d messages(s).", $count3 - 1, $count1) + ); + $this->safeDeleteQueue($queue); + $count1 = count($this->queueRestProxy->listQueues()->getQueues()); + $this->assertEquals( + $count0, + $count1, + sprintf("Expected %d queue(s), listed %d queue(s).", $count0, $count1) + ); + } + + /** + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::__construct + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::generateAccountSharedAccessSignatureToken + */ + public function testServiceAccountSASSSNegative() + { + $helper = new SharedAccessSignatureHelperMock( + $this->serviceSettings->getName(), + $this->serviceSettings->getKey() + ); + + //qtf permission + $this->initializeProxiesWithSASfromArray( + $helper, + TestResources::getInterestingAccountSASTestCase( + 'pucaldwr', + 'ftq', + 'ocs' + ) + ); + + //Validate cannot access blob service + $message = ''; + try { + $this->blobRestProxy->listContainers(); + } catch (ServiceException $e) { + $message = $e->getMessage(); + } + $this->assertContains( + 'not authorized to perform this operation', + $message, + 'Error: access not blocked for blob service.' + ); + //Validate can access table and queue service + $this->tableRestProxy->queryTables(); + $this->queueRestProxy->listQueues(); + + //btf permission + $this->initializeProxiesWithSASfromArray( + $helper, + TestResources::getInterestingAccountSASTestCase( + 'pucaldwr', + 'btf', + 'ocs' + ) + ); + + //Validate cannot access queue service + $message = ''; + try { + $this->queueRestProxy->listQueues(); + } catch (ServiceException $e) { + $message = $e->getMessage(); + } + $this->assertContains( + 'not authorized to perform this operation', + $message, + 'Error: access not blocked for queue service.' + ); + //Validate can access table and queue service + $this->tableRestProxy->queryTables(); + $this->blobRestProxy->listContainers(); + + //bqf permission + $this->initializeProxiesWithSASfromArray( + $helper, + TestResources::getInterestingAccountSASTestCase( + 'pucaldwr', + 'fqb', + 'ocs' + ) + ); + + //Validate cannot access queue service + $message = ''; + try { + $this->tableRestProxy->queryTables(); + } catch (ServiceException $e) { + $message = $e->getMessage(); + } + $this->assertContains( + 'not authorized to perform this operation', + $message, + 'Error: access not blocked for table service.' + ); + //Validate can access table and queue service + $this->queueRestProxy->listQueues(); + $this->blobRestProxy->listContainers(); + } + + /** + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::__construct + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::generateAccountSharedAccessSignatureToken + */ + public function testServiceAccountSASSPNegative() + { + $helper = new SharedAccessSignatureHelperMock( + $this->serviceSettings->getName(), + $this->serviceSettings->getKey() + ); + + //rdaup permit + $this->initializeProxiesWithSASfromArray( + $helper, + TestResources::getInterestingAccountSASTestCase( + 'rdaup', + 'btqf', + 'ocs' + ) + ); + $queue = TestResources::getInterestingName('queue'); + $message = ''; + try { + $this->queueRestProxy->listQueues(); + } catch (ServiceException $e) { + $message = $e->getMessage(); + } + $this->assertContains( + 'not authorized to perform this operation', + $message, + 'Error: access not blocked for list queue operation.' + ); + $message = ''; + try { + $this->queueRestProxy->createQueue('exceptionqueue'); + } catch (ServiceException $e) { + $message = $e->getMessage(); + } + $this->assertContains( + 'not authorized to perform this operation', + $message, + 'Error: access not blocked for create queue operation.' + ); + + //wlcu permit + $this->initializeProxiesWithSASfromArray( + $helper, + TestResources::getInterestingAccountSASTestCase( + 'wlcu', + 'btqf', + 'ocs' + ) + ); + $container = TestResources::getInterestingName('container'); + $blob = TestResources::getInterestingName('blob'); + $this->safeCreateContainer($container); + $this->blobRestProxy->createBlockBlob($container, $blob, 'test message'); + $message = ''; + try { + $this->blobRestProxy->getBlob($container, $blob); + } catch (ServiceException $e) { + $message = $e->getMessage(); + } + $this->assertContains( + 'not authorized to perform this operation', + $message, + 'Error: access not blocked for get blob operation.' + ); + $message = ''; + try { + $this->blobRestProxy->deleteBlob($container, $blob); + } catch (ServiceException $e) { + $message = $e->getMessage(); + } + $this->assertContains( + 'not authorized to perform this operation', + $message, + 'Error: access not blocked for delete blob operation.' + ); + + //initialize with full permision for tearDown + $this->initializeProxiesWithSASfromArray( + $helper, + TestResources::getInterestingAccountSASTestCase( + 'rdlwaup', + 'btqf', + 'ocs' + ) + ); + } + + private function initializeProxiesWithSASfromArray($helper, $testCase) + { + $sas = $helper->generateAccountSharedAccessSignatureToken( + $testCase['signedVersion'], + $testCase['signedPermissions'], + $testCase['signedService'], + $testCase['signedResourceType'], + $testCase['signedExpiracy'], + $testCase['signedStart'], + $testCase['signedIP'], + $testCase['signedProtocol'] + ); + + $accountName = $helper->getAccountName(); + + $connectionString = Resources::BLOB_ENDPOINT_NAME . + '='. + 'https://' . + $accountName . + '.' . + Resources::BLOB_BASE_DNS_NAME . + ';'; + $connectionString .= Resources::QUEUE_ENDPOINT_NAME . + '='. + 'https://' . + $accountName . + '.' . + Resources::QUEUE_BASE_DNS_NAME . + ';'; + $connectionString .= Resources::TABLE_ENDPOINT_NAME . + '='. + 'https://' . + $accountName . + '.' . + Resources::TABLE_BASE_DNS_NAME . + ';'; + $connectionString .= Resources::SAS_TOKEN_NAME . + '='. + $sas; + + $this->blobRestProxy = + $this->builder->createBlobService($connectionString); + $this->queueRestProxy = + $this->builder->createQueueService($connectionString); + $this->tableRestProxy = + $this->builder->createTableService($connectionString); + } + + /** + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::deleteContainer + */ + private function safeDeleteContainer($name) + { + try { + $this->blobRestProxy->deleteContainer($name); + $this->createdContainer = array_diff($this->createdContainer, [$name]); + } catch (ServiceException $e) { + error_log($e->getMessage()); + } + } + + /** + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::createContainer + */ + private function safeCreateContainer($name) + { + try { + $this->blobRestProxy->createContainer($name); + $this->createdContainer[] = $name; + } catch (ServiceException $e) { + error_log($e->getMessage()); + } + } + + /** + * @covers MicrosoftAzure\Storage\Queue\QueueRestProxy::deleteQueue + */ + private function safeDeleteQueue($name) + { + try { + $this->queueRestProxy->deleteQueue($name); + $this->createdQueue = array_diff($this->createdQueue, [$name]); + } catch (ServiceException $e) { + error_log($e->getMessage()); + } + } + + /** + * @covers MicrosoftAzure\Storage\Queue\QueueRestProxy::createQueue + */ + private function safeCreateQueue($name) + { + try { + $this->queueRestProxy->createQueue($name); + $this->createdQueue[] = $name; + } catch (ServiceException $e) { + error_log($e->getMessage()); + } + } + + /** + * @covers MicrosoftAzure\Storage\Table\TableRestProxy::deleteTable + */ + private function safeDeleteTable($name) + { + try { + $this->blobRestProxy->deleteTable($name); + $this->createdTable = array_diff($this->createdTable, [$name]); + } catch (ServiceException $e) { + error_log($e->getMessage()); + } + } + + /** + * @covers MicrosoftAzure\Storage\Table\TableRestProxy::createTable + */ + private function safeCreateTable($name) + { + try { + $this->tableRestProxy->createTable($name); + $this->createdTable[] = $name; + } catch (ServiceException $e) { + error_log($e->getMessage()); + } + } +} diff --git a/tests/functional/Common/SharedAccessSignatureHelperMock.php b/tests/functional/Common/SharedAccessSignatureHelperMock.php new file mode 100644 index 000000000..a7f45fe22 --- /dev/null +++ b/tests/functional/Common/SharedAccessSignatureHelperMock.php @@ -0,0 +1,50 @@ + + * @copyright Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ + +namespace MicrosoftAzure\Storage\Tests\functional\Common; + +use MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper; + +/** + * Provides methods to access the account name and key for the + * SharedAccessSignatureHelper. + * + * @category Microsoft + * @author Azure Storage PHP SDK + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +class SharedAccessSignatureHelperMock extends SharedAccessSignatureHelper +{ + public function getAccountName() + { + return $this->accountName; + } + + public function getAccountKey() + { + return $this->accountKey; + } +} diff --git a/tests/functional/Queue/QueueServiceFunctionalParameterTest.php b/tests/functional/Queue/QueueServiceFunctionalParameterTest.php index 53441593f..005cec3c6 100644 --- a/tests/functional/Queue/QueueServiceFunctionalParameterTest.php +++ b/tests/functional/Queue/QueueServiceFunctionalParameterTest.php @@ -25,7 +25,7 @@ namespace MicrosoftAzure\Storage\Tests\functional\Queue; use MicrosoftAzure\Storage\Tests\Framework\TestResources; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Queue\Models\ListMessagesOptions; use MicrosoftAzure\Storage\Queue\Models\PeekMessagesOptions; diff --git a/tests/functional/Queue/QueueServiceFunctionalTest.php b/tests/functional/Queue/QueueServiceFunctionalTest.php index 173b50d10..b5ecb0502 100644 --- a/tests/functional/Queue/QueueServiceFunctionalTest.php +++ b/tests/functional/Queue/QueueServiceFunctionalTest.php @@ -25,15 +25,15 @@ namespace MicrosoftAzure\Storage\Tests\functional\Queue; use MicrosoftAzure\Storage\Tests\Framework\TestResources; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Queue\Models\CreateMessageOptions; use MicrosoftAzure\Storage\Queue\Models\CreateQueueOptions; use MicrosoftAzure\Storage\Queue\Models\ListMessagesOptions; use MicrosoftAzure\Storage\Queue\Models\ListQueuesOptions; use MicrosoftAzure\Storage\Queue\Models\PeekMessagesOptions; use MicrosoftAzure\Storage\Queue\Models\QueueServiceOptions; -use MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory; -use MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware; +use MicrosoftAzure\Storage\Common\Middlewares\RetryMiddlewareFactory; +use MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\Psr7\Response; @@ -257,6 +257,8 @@ private function setServicePropertiesWorker($serviceProperties, $options) $this->assertFalse($this->isEmulated(), 'Should succeed when not running in emulator'); } + \sleep(10); + $ret = (is_null($options) ? $this->restProxy->getServiceProperties() : $this->restProxy->getServiceProperties($options) diff --git a/tests/functional/Queue/QueueServiceFunctionalTestData.php b/tests/functional/Queue/QueueServiceFunctionalTestData.php index f82586d64..11245a97d 100644 --- a/tests/functional/Queue/QueueServiceFunctionalTestData.php +++ b/tests/functional/Queue/QueueServiceFunctionalTestData.php @@ -24,8 +24,11 @@ namespace MicrosoftAzure\Storage\Tests\functional\Queue; +use MicrosoftAzure\Storage\Tests\Framework\TestResources; +use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Models\Logging; use MicrosoftAzure\Storage\Common\Models\Metrics; +use MicrosoftAzure\Storage\Common\Models\CORS; use MicrosoftAzure\Storage\Common\Models\RetentionPolicy; use MicrosoftAzure\Storage\Common\Models\ServiceProperties; use MicrosoftAzure\Storage\Queue\Models\CreateMessageOptions; @@ -34,7 +37,10 @@ class QueueServiceFunctionalTestData { - const INTERESTING_TTL = 4; + //Needs to keep this value as low as possible to quicken the test + //but if the test machine is slow, a small value will cause unexpected + //failures. Default value: 20. + const INTERESTING_TTL = 20; public static $testUniqueId; public static $tempQueueCounter; public static $nonExistQueuePrefix; @@ -128,9 +134,12 @@ public static function getInterestingServiceProperties() $m->setEnabled(true); $m->setIncludeAPIs(true); + $c = CORS::create(TestResources::getCORSSingle()); + $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setMetrics($m); + $sp->setCorses(array($c)); array_push($ret, $sp); } @@ -156,9 +165,15 @@ public static function getInterestingServiceProperties() $m->setEnabled(true); $m->setIncludeAPIs(true); + $csArray = + TestResources::getServicePropertiesSample()[Resources::XTAG_CORS]; + $c0 = CORS::create($csArray[Resources::XTAG_CORS_RULE][0]); + $c1 = CORS::create($csArray[Resources::XTAG_CORS_RULE][1]); + $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setMetrics($m); + $sp->setCorses(array($c0, $c1)); array_push($ret, $sp); } @@ -184,9 +199,15 @@ public static function getInterestingServiceProperties() $m->setIncludeAPIs(null); $m->setRetentionPolicy($rp); + $csArray = + TestResources::getServicePropertiesSample()[Resources::XTAG_CORS]; + $c0 = CORS::create($csArray[Resources::XTAG_CORS_RULE][0]); + $c1 = CORS::create($csArray[Resources::XTAG_CORS_RULE][1]); + $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setMetrics($m); + $sp->setCorses(array($c0, $c1)); array_push($ret, $sp); } diff --git a/tests/functional/Queue/QueueServiceIntegrationTest.php b/tests/functional/Queue/QueueServiceIntegrationTest.php index 7d3a58049..f7bed512e 100644 --- a/tests/functional/Queue/QueueServiceIntegrationTest.php +++ b/tests/functional/Queue/QueueServiceIntegrationTest.php @@ -25,7 +25,7 @@ namespace MicrosoftAzure\Storage\Tests\functional\Queue; use MicrosoftAzure\Storage\Tests\Framework\TestResources; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Queue\Models\CreateQueueOptions; use MicrosoftAzure\Storage\Queue\Models\ListMessagesOptions; use MicrosoftAzure\Storage\Queue\Models\ListQueuesOptions; diff --git a/tests/functional/Table/TableServiceFunctionalParametersTest.php b/tests/functional/Table/TableServiceFunctionalParametersTest.php index 51a49118f..5a9e3979c 100644 --- a/tests/functional/Table/TableServiceFunctionalParametersTest.php +++ b/tests/functional/Table/TableServiceFunctionalParametersTest.php @@ -25,7 +25,7 @@ namespace MicrosoftAzure\Storage\Tests\functional\Table; use MicrosoftAzure\Storage\Tests\Framework\TestResources; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Models\ServiceProperties; use MicrosoftAzure\Storage\Table\Models\DeleteEntityOptions; diff --git a/tests/functional/Table/TableServiceFunctionalQueryTest.php b/tests/functional/Table/TableServiceFunctionalQueryTest.php index a0222f391..34a16b4e5 100644 --- a/tests/functional/Table/TableServiceFunctionalQueryTest.php +++ b/tests/functional/Table/TableServiceFunctionalQueryTest.php @@ -25,7 +25,7 @@ namespace MicrosoftAzure\Storage\Tests\functional\Table; use MicrosoftAzure\Storage\Tests\Framework\TestResources; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Table\Models\BatchOperations; use MicrosoftAzure\Storage\Table\Models\EdmType; use MicrosoftAzure\Storage\Table\Models\Entity; diff --git a/tests/functional/Table/TableServiceFunctionalTest.php b/tests/functional/Table/TableServiceFunctionalTest.php index d495047a1..675e21031 100644 --- a/tests/functional/Table/TableServiceFunctionalTest.php +++ b/tests/functional/Table/TableServiceFunctionalTest.php @@ -31,7 +31,7 @@ use MicrosoftAzure\Storage\Tests\Functional\Table\Models\BatchWorkerConfig; use MicrosoftAzure\Storage\Tests\Functional\Table\Models\FakeTableInfoEntry; use MicrosoftAzure\Storage\Common\Internal\Utilities; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Table\Models\BatchError; use MicrosoftAzure\Storage\Table\Models\BatchOperations; use MicrosoftAzure\Storage\Table\Models\DeleteEntityOptions; @@ -43,8 +43,8 @@ use MicrosoftAzure\Storage\Table\Models\QueryTablesOptions; use MicrosoftAzure\Storage\Table\Models\TableServiceOptions; use MicrosoftAzure\Storage\Table\Models\UpdateEntityResult; -use MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory; -use MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware; +use MicrosoftAzure\Storage\Common\Middlewares\RetryMiddlewareFactory; +use MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\Psr7\Response; @@ -233,6 +233,9 @@ private function setServicePropertiesWorker($serviceProperties, $options) } $this->assertFalse($this->isEmulated(), 'Should succeed when not running in emulator'); + + \sleep(10); + $ret = (is_null($options) ? $this->restProxy->getServiceProperties() : $this->restProxy->getServiceProperties($options) diff --git a/tests/functional/Table/TableServiceFunctionalTestData.php b/tests/functional/Table/TableServiceFunctionalTestData.php index ec6481bd8..2d43e2fa8 100644 --- a/tests/functional/Table/TableServiceFunctionalTestData.php +++ b/tests/functional/Table/TableServiceFunctionalTestData.php @@ -24,9 +24,12 @@ namespace MicrosoftAzure\Storage\Tests\functional\Table; +use MicrosoftAzure\Storage\Tests\Framework\TestResources; use MicrosoftAzure\Storage\Common\Internal\Utilities; +use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Models\Logging; use MicrosoftAzure\Storage\Common\Models\Metrics; +use MicrosoftAzure\Storage\Common\Models\CORS; use MicrosoftAzure\Storage\Common\Models\RetentionPolicy; use MicrosoftAzure\Storage\Common\Models\ServiceProperties; use MicrosoftAzure\Storage\Table\Models\EdmType; @@ -141,9 +144,12 @@ public static function getInterestingServiceProperties() $m->setEnabled(true); $m->setIncludeAPIs(true); + $c = CORS::create(TestResources::getCORSSingle()); + $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setMetrics($m); + $sp->setCorses(array($c)); array_push($ret, $sp); } @@ -168,9 +174,15 @@ public static function getInterestingServiceProperties() $m->setEnabled(true); $m->setIncludeAPIs(true); + $csArray = + TestResources::getServicePropertiesSample()[Resources::XTAG_CORS]; + $c0 = CORS::create($csArray[Resources::XTAG_CORS_RULE][0]); + $c1 = CORS::create($csArray[Resources::XTAG_CORS_RULE][1]); + $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setMetrics($m); + $sp->setCorses(array($c0, $c1)); array_push($ret, $sp); } @@ -196,9 +208,15 @@ public static function getInterestingServiceProperties() $m->setIncludeAPIs(null); $m->setRetentionPolicy($rp); + $csArray = + TestResources::getServicePropertiesSample()[Resources::XTAG_CORS]; + $c0 = CORS::create($csArray[Resources::XTAG_CORS_RULE][0]); + $c1 = CORS::create($csArray[Resources::XTAG_CORS_RULE][1]); + $sp = new ServiceProperties(); $sp->setLogging($l); $sp->setMetrics($m); + $sp->setCorses(array($c0, $c1)); array_push($ret, $sp); } @@ -354,7 +372,7 @@ public static function getInterestingEntities() $e->setRowKey(self::getNewKey()); $e->addProperty('BINARY', EdmType::BINARY, chr(0) . chr(1) . chr(2) . chr(3) . chr(4)); $e->addProperty('BOOLEAN', EdmType::BOOLEAN, true); - $e->addProperty('DATETIME', EdmType::DATETIME, Utilities::convertToDateTime('2012-01-26T18:26:19.0000473Z')); + $e->addProperty('DATETIME', EdmType::DATETIME, Utilities::convertToDateTime('2012-01-26T18:26:19.0000470Z')); $e->addProperty('DOUBLE', EdmType::DOUBLE, 12345678901); $e->addProperty('GUID', EdmType::GUID, '90ab64d6-d3f8-49ec-b837-b8b5b6367b74'); $e->addProperty('INT32', EdmType::INT32, 23); diff --git a/tests/functional/Table/TableServiceFunctionalTestUtils.php b/tests/functional/Table/TableServiceFunctionalTestUtils.php index f24da968e..bd66dbce9 100644 --- a/tests/functional/Table/TableServiceFunctionalTestUtils.php +++ b/tests/functional/Table/TableServiceFunctionalTestUtils.php @@ -146,7 +146,7 @@ public static function mutateEntity(&$ent, $pivot) self::mutateEntityChangeValues($ent); } elseif ($pivot == MutatePivot::ADD_PROPERTY) { $ent->addProperty('BOOLEAN' . TableServiceFunctionalTestData::getNewKey(), EdmType::BOOLEAN, true); - $ent->addProperty('DATETIME' . TableServiceFunctionalTestData::getNewKey(), EdmType::DATETIME, Utilities::convertToDateTime('2012-01-26T18:26:19.0000473Z')); + $ent->addProperty('DATETIME' . TableServiceFunctionalTestData::getNewKey(), EdmType::DATETIME, Utilities::convertToDateTime('2012-01-26T18:26:19.0000470Z')); $ent->addProperty('DOUBLE' . TableServiceFunctionalTestData::getNewKey(), EdmType::DOUBLE, 12345678901); $ent->addProperty('GUID' . TableServiceFunctionalTestData::getNewKey(), EdmType::GUID, '90ab64d6-d3f8-49ec-b837-b8b5b6367b74'); $ent->addProperty('INT32' . TableServiceFunctionalTestData::getNewKey(), EdmType::INT32, 23); diff --git a/tests/functional/Table/TableServiceIntegrationTest.php b/tests/functional/Table/TableServiceIntegrationTest.php index 786fffd55..ea76173a2 100644 --- a/tests/functional/Table/TableServiceIntegrationTest.php +++ b/tests/functional/Table/TableServiceIntegrationTest.php @@ -25,7 +25,7 @@ namespace MicrosoftAzure\Storage\Tests\functional\Table; use MicrosoftAzure\Storage\Tests\Framework\TestResources; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Common\Internal\Utilities; use MicrosoftAzure\Storage\Table\Models\BatchError; use MicrosoftAzure\Storage\Table\Models\BatchOperations; diff --git a/tests/unit/Blob/BlobRestProxyTest.php b/tests/unit/Blob/BlobRestProxyTest.php index d8e4a70c0..ce1dcf5d2 100644 --- a/tests/unit/Blob/BlobRestProxyTest.php +++ b/tests/unit/Blob/BlobRestProxyTest.php @@ -29,8 +29,9 @@ use MicrosoftAzure\Storage\Tests\Framework\TestResources; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Utilities; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Common\Models\ServiceProperties; +use MicrosoftAzure\Storage\Blob\Models\AppendBlockOptions; use MicrosoftAzure\Storage\Blob\Models\ListContainersOptions; use MicrosoftAzure\Storage\Blob\Models\ListContainersResult; use MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions; @@ -73,22 +74,9 @@ private function createSuffix() { return sprintf('-%04x', mt_rand(0, 65535)); } - - /** - * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::getServiceProperties - */ - public function testGetServiceProperties() - { - $this->skipIfEmulated(); - - // Test - $result = $this->restProxy->getServiceProperties(); - - // Assert - $this->assertEquals($this->defaultProperties->toArray(), $result->getValue()->toArray()); - } /** + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::getServiceProperties * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::setServiceProperties */ public function testSetServiceProperties() @@ -202,7 +190,7 @@ public function testListContainersWithNextMarker() /** * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::listContainers - * @expectedException MicrosoftAzure\Storage\Common\ServiceException + * @expectedException MicrosoftAzure\Storage\Common\Exceptions\ServiceException * @expectedExceptionMessage 400 */ public function testListContainersWithInvalidNextMarkerFail() @@ -318,7 +306,7 @@ public function testCreateContainerWithMetadata() /** * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::createContainer $this->setExpectedException(get_class(new ServiceException('400'))); - * @expectedException MicrosoftAzure\Storage\Common\ServiceException + * @expectedException MicrosoftAzure\Storage\Common\Exceptions\ServiceException * @expectedExceptionMessage 400 */ public function testCreateContainerInvalidNameFail() @@ -332,7 +320,7 @@ public function testCreateContainerInvalidNameFail() /** * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::createContainer - * @expectedException MicrosoftAzure\Storage\Common\ServiceException + * @expectedException MicrosoftAzure\Storage\Common\Exceptions\ServiceException * @expectedExceptionMessage 409 */ public function testCreateContainerAlreadyExitsFail() @@ -365,7 +353,7 @@ public function testDeleteContainer() /** * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::deleteContainer - * @expectedException MicrosoftAzure\Storage\Common\ServiceException + * @expectedException MicrosoftAzure\Storage\Common\Exceptions\ServiceException * @expectedExceptionMessage 404 */ public function testDeleteContainerFail() @@ -673,6 +661,158 @@ public function testCreatePageBlob() $this->assertCount(1, $result->getBlobs()); } + /** + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::createAppendBlob + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::getBlobProperties + */ + public function testCreateAppendBlob() + { + // Setup + $name = 'createappendblob' . $this->createSuffix(); + $this->createContainer($name); + + // Test + $createResult = $this->restProxy->createAppendBlob($name, 'myblob'); + + // Assert + $this->assertNotNull($createResult->getETag()); + $this->assertInstanceOf('\DateTime', $createResult->getLastModified()); + + $appendBlob = $this->restProxy->getBlobProperties($name, 'myblob'); + $this->assertEquals('AppendBlob', $appendBlob->getProperties()->getBlobType()); + $this->assertEquals(0, $appendBlob->getProperties()->getCommittedBlockCount()); + } + + /** + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::createAppendBlob + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::appendBlock + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::listBlobs + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::getBlobProperties + */ + public function testAppendBlock() + { + // Setup + $name = 'createappendblob' . $this->createSuffix(); + $this->createContainer($name); + $textToBeAppended = 'text to be appended'; + + // Test + $this->restProxy->createAppendBlob($name, 'myblob'); + $appendResult = $this->restProxy->appendBlock($name, 'myblob', $textToBeAppended); + + // Assert + $this->assertNotNull($appendResult->getETag()); + $this->assertInstanceOf('\DateTime', $appendResult->getLastModified()); + $this->assertEquals(0, $appendResult->getAppendOffset()); + $this->assertEquals(1, $appendResult->getCommittedBlockCount()); + + // List blobs + $listBlobs = $this->restProxy->listBlobs($name, null)->getBlobs(); + $this->assertCount(1, $listBlobs); + $this->assertEquals('AppendBlob', $listBlobs[0]->getProperties()->getBlobType()); + + + // Get append blob properties + $appendBlob = $this->restProxy->getBlobProperties($name, 'myblob'); + $this->assertEquals('AppendBlob', $appendBlob->getProperties()->getBlobType()); + $this->assertEquals(1, $appendBlob->getProperties()->getCommittedBlockCount()); + $this->assertEquals(strlen($textToBeAppended), $appendBlob->getProperties()->getContentLength()); + + // Append again + $appendResult = $this->restProxy->appendBlock($name, 'myblob', $textToBeAppended); + $this->assertNotNull($appendResult->getETag()); + $this->assertInstanceOf('\DateTime', $appendResult->getLastModified()); + $this->assertEquals(19, $appendResult->getAppendOffset()); + $this->assertEquals(2, $appendResult->getCommittedBlockCount()); + + $appendBlob = $this->restProxy->getBlobProperties($name, 'myblob'); + $this->assertEquals('AppendBlob', $appendBlob->getProperties()->getBlobType()); + $this->assertEquals(2, $appendBlob->getProperties()->getCommittedBlockCount()); + $this->assertEquals(2 * strlen($textToBeAppended), $appendBlob->getProperties()->getContentLength()); + } + + /** + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::createAppendBlob + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::appendBlock + */ + public function testAppendBlockSuccessWithAppendPosition() + { + // Setup + $name = 'appendblockappendpositionsuccess' . $this->createSuffix(); + $this->createContainer($name); + $textToBeAppended = 'text to be appended'; + $appendBlockOption = new AppendBlockOptions(); + $appendBlockOption->setAppendPosition(0); + + // Test + $this->restProxy->createAppendBlob($name, 'myblob'); + $this->restProxy->appendBlock($name, 'myblob', $textToBeAppended, $appendBlockOption); + + // Append again + $appendBlockOption->setAppendPosition(strlen($textToBeAppended)); + $appendResult = $this->restProxy->appendBlock($name, 'myblob', $textToBeAppended, $appendBlockOption); + $this->assertNotNull($appendResult->getETag()); + } + + /** + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::createAppendBlob + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::appendBlock + * @expectedException MicrosoftAzure\Storage\Common\Exceptions\ServiceException + * @expectedExceptionMessage 412 + */ + public function testAppendBlockConflictBecauseOfAppendPosition() + { + // Setup + $name = 'appendblockappendpositionconflict' . $this->createSuffix(); + $this->createContainer($name); + $textToBeAppended = 'text to be appended'; + $appendBlockOption = new AppendBlockOptions(); + $appendBlockOption->setAppendPosition(1); + + // Test + $this->restProxy->createAppendBlob($name, 'myblob'); + $this->restProxy->appendBlock($name, 'myblob', $textToBeAppended, $appendBlockOption); + } + + /** + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::createAppendBlob + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::appendBlock + */ + public function testAppendBlockSuccessWithMaxBlobSize() + { + // Setup + $name = 'appendblockmaxblobsizeconflict' . $this->createSuffix(); + $this->createContainer($name); + $textToBeAppended = 'text to be appended'; + $appendBlockOption = new AppendBlockOptions(); + $appendBlockOption->setMaxBlobSize(1000); + + // Test + $this->restProxy->createAppendBlob($name, 'myblob'); + $appendResult = $this->restProxy->appendBlock($name, 'myblob', $textToBeAppended, $appendBlockOption); + $this->assertNotNull($appendResult->getETag()); + } + + /** + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::createAppendBlob + * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::appendBlock + * @expectedException MicrosoftAzure\Storage\Common\Exceptions\ServiceException + * @expectedExceptionMessage 412 + */ + public function testAppendBlockConflictBecauseOfMaxBlobSize() + { + // Setup + $name = 'appendblockmaxblobsizeconflict' . $this->createSuffix(); + $this->createContainer($name); + $textToBeAppended = 'text to be appended'; + $appendBlockOption = new AppendBlockOptions(); + $appendBlockOption->setMaxBlobSize(1); + + // Test + $this->restProxy->createAppendBlob($name, 'myblob'); + $this->restProxy->appendBlock($name, 'myblob', $textToBeAppended, $appendBlockOption); + } + /** * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::createPageBlob * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::_addCreateBlobOptionalHeaders @@ -912,7 +1052,7 @@ public function testGetBlob() /** * @covers MicrosoftAzure\Storage\Blob\BlobRestProxy::getBlobAsync - * @expectedException MicrosoftAzure\Storage\Common\ServiceException + * @expectedException MicrosoftAzure\Storage\Common\Exceptions\ServiceException * @expectedExceptionMessage 404 */ public function testGetBlobNotExist() @@ -2228,6 +2368,80 @@ public function testGetLargePageBlob() unlink($downloadPath); } + /** + * @group large-scale + * @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::getBlob + * @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::createPageBlobFromContent + */ + public function testCreateLargePageBlobFromContent() + { + //Setup + //create a temp file that is 2GB in size. + $cwd = getcwd(); + $uuid = uniqid('test-file-', true); + $path = $cwd.DIRECTORY_SEPARATOR.$uuid.'.txt'; + $resource = fopen($path, 'w+'); + $count = 2 * 1024 / 4; + for ($index = 0; $index < $count; ++$index) { + fwrite($resource, openssl_random_pseudo_bytes(Resources::MB_IN_BYTES_4)); + } + rewind($resource); + + //upload the blob + $container = 'createpageblobfromcontent' . $this->createSuffix(); + $blob = 'myblob'; + $length = $count * Resources::MB_IN_BYTES_4; + $this->createContainer($container); + + $metadata = array('m1' => 'v1', 'm2' => 'v2'); + $contentType = 'text/plain; charset=UTF-8'; + $options = new CreateBlobOptions(); + $options->setContentType($contentType); + $options->setMetadata($metadata); + + $createPageBlobResult = $this->restProxy->createPageBlobFromContent($container, $blob, $length, $resource, $options); + + $originMd5 = md5_file($path); + $this->assertEquals("PageBlob", $createPageBlobResult->getProperties()->getBlobType()); + $this->assertEquals($contentType, $createPageBlobResult->getProperties()->getContentType()); + $this->assertEquals(2, count($createPageBlobResult->getMetadata())); + $this->assertEquals($metadata["m1"], $createPageBlobResult->getMetadata()["m1"]); + $this->assertEquals($metadata["m2"], $createPageBlobResult->getMetadata()["m2"]); + + // Test + $result = $this->restProxy->getBlob($container, $blob); + + //get the path for the file to be downloaded into. + $uuid = uniqid('test-file-', true); + $downloadPath = $cwd.DIRECTORY_SEPARATOR.$uuid.'.txt'; + $downloadResource = fopen($downloadPath, 'w'); + + //download the file + $content = $result->getContentStream(); + while (!feof($content)) { + fwrite( + $downloadResource, + stream_get_contents($content, Resources::MB_IN_BYTES_4) + ); + } + + // Assert + $this->assertEquals( + BlobType::PAGE_BLOB, + $result->getProperties()->getBlobType() + ); + $downloadMd5 = md5_file($downloadPath); + $this->assertEquals($originMd5, $downloadMd5); + + // Delete file after assertion. + if (is_resource($resource)) { + fclose($resource); + } + fclose($downloadResource); + unlink($path); + unlink($downloadPath); + } + /** * @group large-scale * @covers \MicrosoftAzure\Storage\Blob\BlobRestProxy::saveBlobToFile diff --git a/tests/unit/Blob/Models/ContainerACLTest.php b/tests/unit/Blob/Models/ContainerACLTest.php index 698484979..942712720 100644 --- a/tests/unit/Blob/Models/ContainerACLTest.php +++ b/tests/unit/Blob/Models/ContainerACLTest.php @@ -30,7 +30,7 @@ use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; /** - * Unit tests for class ContainerAcl + * Unit tests for class ContainerACL * * @category Microsoft * @package MicrosoftAzure\Storage\Tests\Unit\Blob\Models @@ -46,6 +46,7 @@ class ContainerACLTest extends \PHPUnit_Framework_TestCase * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::getPublicAccess * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::getSignedIdentifiers * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::addSignedIdentifier + * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::fromXml */ public function testCreateEmpty() { @@ -66,6 +67,7 @@ public function testCreateEmpty() * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::getPublicAccess * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::getSignedIdentifiers * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::addSignedIdentifier + * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::fromXml */ public function testCreateOneEntry() { @@ -86,6 +88,7 @@ public function testCreateOneEntry() * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::getPublicAccess * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::getSignedIdentifiers * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::addSignedIdentifier + * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::fromXml */ public function testCreateMultipleEntries() { @@ -102,31 +105,10 @@ public function testCreateMultipleEntries() return $acl; } - - /** - * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::setSignedIdentifiers - * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::getSignedIdentifiers - */ - public function testSetSignedIdentifiers() - { - // Setup - $sample = TestResources::getContainerAclOneEntrySample(); - $expectedPublicAccess = 'container'; - $acl = ContainerAcl::create($expectedPublicAccess, $sample['SignedIdentifiers']); - $expected = $acl->getSignedIdentifiers(); - $expected[0]->setId('newXid'); - - // Test - $acl->setSignedIdentifiers($expected); - - // Assert - $this->assertEquals($expectedPublicAccess, $acl->getPublicAccess()); - $this->assertEquals($expected, $acl->getSignedIdentifiers()); - } - + /** - * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::setPublicAccess - * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::getPublicAccess + * @covers MicrosoftAzure\Storage\Common\Internal\ACLBase::setPublicAccess + * @covers MicrosoftAzure\Storage\Common\Internal\ACLBase::getPublicAccess */ public function testSetPublicAccess() { @@ -141,25 +123,4 @@ public function testSetPublicAccess() // Assert $this->assertEquals($expected, $acl->getPublicAccess()); } - - /** - * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::toXml - * @covers MicrosoftAzure\Storage\Blob\Models\ContainerAcl::toArray - * @depends testCreateMultipleEntries - */ - public function testToXml($acl) - { - // Setup - $sample = TestResources::getContainerAclMultipleEntriesSample(); - $expected = ContainerAcl::create('container', $sample['SignedIdentifiers']); - $xmlSerializer = new XmlSerializer(); - - // Test - $xml = $acl->toXml($xmlSerializer); - - // Assert - $array = Utilities::unserialize($xml); - $acl = ContainerAcl::create('container', $array); - $this->assertEquals($expected->getSignedIdentifiers(), $acl->getSignedIdentifiers()); - } } diff --git a/tests/unit/Blob/Models/CreateContainerOptionsTest.php b/tests/unit/Blob/Models/CreateContainerOptionsTest.php index 9048ca3b4..6cd07099f 100644 --- a/tests/unit/Blob/Models/CreateContainerOptionsTest.php +++ b/tests/unit/Blob/Models/CreateContainerOptionsTest.php @@ -25,7 +25,7 @@ namespace MicrosoftAzure\Storage\Tests\unit\Blob\Models; use MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions; -use MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException; +use MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException; /** * Unit tests for class CreateContainerOptions diff --git a/tests/unit/Blob/Models/SignedIdentifierTest.php b/tests/unit/Blob/Models/SignedIdentifierTest.php index 39a54f31d..708f5d10d 100644 --- a/tests/unit/Blob/Models/SignedIdentifierTest.php +++ b/tests/unit/Blob/Models/SignedIdentifierTest.php @@ -15,22 +15,22 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Blob\Models + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Models * @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 */ -namespace MicrosoftAzure\Storage\Tests\unit\Blob\Models; +namespace MicrosoftAzure\Storage\Tests\unit\Common\Models; -use MicrosoftAzure\Storage\Blob\Models\SignedIdentifier; -use MicrosoftAzure\Storage\Blob\Models\AccessPolicy; +use MicrosoftAzure\Storage\Common\Models\SignedIdentifier; +use MicrosoftAzure\Storage\Common\Models\AccessPolicy; /** * Unit tests for class SignedIdentifier * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Blob\Models + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Models * @author Azure Storage PHP SDK * @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -39,7 +39,7 @@ class SignedIdentifierTest extends \PHPUnit_Framework_TestCase { /** - * @covers MicrosoftAzure\Storage\Blob\Models\SignedIdentifier::getId + * @covers MicrosoftAzure\Storage\Common\Models\SignedIdentifier::getId */ public function testGetId() { @@ -56,7 +56,7 @@ public function testGetId() } /** - * @covers MicrosoftAzure\Storage\Blob\Models\SignedIdentifier::setId + * @covers MicrosoftAzure\Storage\Common\Models\SignedIdentifier::setId */ public function testSetId() { @@ -72,7 +72,7 @@ public function testSetId() } /** - * @covers MicrosoftAzure\Storage\Blob\Models\SignedIdentifier::getAccessPolicy + * @covers MicrosoftAzure\Storage\Common\Models\SignedIdentifier::getAccessPolicy */ public function testGetAccessPolicy() { @@ -92,7 +92,7 @@ public function testGetAccessPolicy() } /** - * @covers MicrosoftAzure\Storage\Blob\Models\SignedIdentifier::setAccessPolicy + * @covers MicrosoftAzure\Storage\Common\Models\SignedIdentifier::setAccessPolicy */ public function testSetAccessPolicy() { @@ -113,7 +113,7 @@ public function testSetAccessPolicy() } /** - * @covers MicrosoftAzure\Storage\Blob\Models\SignedIdentifier::toArray + * @covers MicrosoftAzure\Storage\Common\Models\SignedIdentifier::toArray * @depends testSetAccessPolicy */ public function testToXml($signedIdentifier) diff --git a/tests/unit/Common/ServiceExceptionTest.php b/tests/unit/Common/Exceptions/ServiceExceptionTest.php similarity index 71% rename from tests/unit/Common/ServiceExceptionTest.php rename to tests/unit/Common/Exceptions/ServiceExceptionTest.php index f0b99b5ac..5213d319b 100644 --- a/tests/unit/Common/ServiceExceptionTest.php +++ b/tests/unit/Common/Exceptions/ServiceExceptionTest.php @@ -15,23 +15,23 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Common + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Exceptions * @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 */ -namespace MicrosoftAzure\Storage\Tests\unit\Common; +namespace MicrosoftAzure\Storage\Tests\unit\Common\Exceptions; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Tests\framework\TestResources; /** * Unit tests for class ServiceException * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Common + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Exceptions * @author Azure Storage PHP SDK * @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -40,7 +40,7 @@ class ServiceExceptionTest extends \PHPUnit_Framework_TestCase { /** - * @covers MicrosoftAzure\Storage\Common\ServiceException::__construct + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::__construct */ public function testConstruct() { @@ -57,8 +57,8 @@ public function testConstruct() } /** - * @covers MicrosoftAzure\Storage\Common\ServiceException::getErrorText - * @covers MicrosoftAzure\Storage\Common\ServiceException::__construct + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::getErrorText + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::__construct */ public function testGetErrorText() { @@ -73,9 +73,9 @@ public function testGetErrorText() } /** - * @covers MicrosoftAzure\Storage\Common\ServiceException::getErrorMessage - * @covers MicrosoftAzure\Storage\Common\ServiceException::__construct - * @covers MicrosoftAzure\Storage\Common\ServiceException::parseErrorMessage + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::getErrorMessage + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::__construct + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::parseErrorMessage */ public function testGetErrorMessage() { @@ -91,8 +91,8 @@ public function testGetErrorMessage() } /** - * @covers MicrosoftAzure\Storage\Common\ServiceException::getRequestID - * @covers MicrosoftAzure\Storage\Common\ServiceException::__construct + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::getRequestID + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::__construct */ public function testGetRequestID() { @@ -105,8 +105,8 @@ public function testGetRequestID() } /** - * @covers MicrosoftAzure\Storage\Common\ServiceException::getDate - * @covers MicrosoftAzure\Storage\Common\ServiceException::__construct + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::getDate + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::__construct */ public function testGetDate() { @@ -119,8 +119,8 @@ public function testGetDate() } /** - * @covers MicrosoftAzure\Storage\Common\ServiceException::getResponse - * @covers MicrosoftAzure\Storage\Common\ServiceException::__construct + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::getResponse + * @covers MicrosoftAzure\Storage\Common\Exceptions\ServiceException::__construct */ public function testGetResponse() { diff --git a/tests/unit/Common/Internal/ACLBaseTest.php b/tests/unit/Common/Internal/ACLBaseTest.php new file mode 100644 index 000000000..cbbc3e5ff --- /dev/null +++ b/tests/unit/Common/Internal/ACLBaseTest.php @@ -0,0 +1,170 @@ + + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +namespace MicrosoftAzure\Storage\Tests\unit\Common\Internal; + +use MicrosoftAzure\Storage\Tests\Framework\TestResources; +use MicrosoftAzure\Storage\Tests\Framework\ReflectionTestBase; +use MicrosoftAzure\Storage\Common\Internal\ACLBase; +use MicrosoftAzure\Storage\Common\Internal\Resources; +use MicrosoftAzure\Storage\Common\Internal\Utilities; +use MicrosoftAzure\Storage\Queue\Models\QueueACL; +use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; + +/** + * Unit tests for class ACLBase + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal + * @author Azure Storage PHP SDK + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +class ACLBaseTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers MicrosoftAzure\Storage\Common\Internal\ACLBase::setSignedIdentifiers + * @covers MicrosoftAzure\Storage\Common\Internal\ACLBase::getSignedIdentifiers + * @covers MicrosoftAzure\Storage\Common\Internal\ACLBase::fromXmlArray + */ + public function testSetGetSignedIdentifiers() + { + // Setup + $sample = TestResources::getQueueACLMultipleEntriesSample(); + $child = new QueueACL(); + + $child->fromXmlArray($sample[Resources::XTAG_SIGNED_IDENTIFIERS]); + $expected = $child->getSignedIdentifiers(); + $expected[0]->setId('newXid'); + + // Test + $child->setSignedIdentifiers($expected); + + // Assert + $this->assertEquals($expected, $child->getSignedIdentifiers()); + } + + /** + * @covers MicrosoftAzure\Storage\Common\Internal\ACLBase::fromXmlArray + * @covers MicrosoftAzure\Storage\Common\Internal\ACLBase::toXml + */ + public function testToXml() + { + // Setup + $sample = TestResources::getQueueACLMultipleEntriesSample(); + $expected = new QueueACL(); + $expected->fromXmlArray($sample['SignedIdentifiers']); + + $xmlSerializer = new XmlSerializer(); + + // Test + $xml = $expected->toXml($xmlSerializer); + + // Assert + $array = Utilities::unserialize($xml); + $acl = QueueACL::create($array); + $this->assertEquals( + $expected->getSignedIdentifiers(), + $acl->getSignedIdentifiers() + ); + } + + /** + * @covers MicrosoftAzure\Storage\Common\Internal\ACLBase::toArray + * @covers MicrosoftAzure\Storage\Common\Internal\ACLBase::fromXmlArray + */ + public function testToArray() + { + // Setup + $sample = TestResources::getQueueACLMultipleUnencodedEntriesSample(); + $expected = $sample['SignedIdentifiers']; + $acl = new QueueACL(); + $acl->fromXmlArray($expected); + + // Test + $actual = $acl->toArray(); + + // Assert + $this->assertEquals( + $expected['SignedIdentifier'][0], + $actual[0]['SignedIdentifier'] + ); + $this->assertEquals( + $expected['SignedIdentifier'][1], + $actual[1]['SignedIdentifier'] + ); + } + + /** + * @covers MicrosoftAzure\Storage\Common\Internal\ACLBase::addSignedIdentifier + * @covers MicrosoftAzure\Storage\Common\Internal\ACLBase::removeSignedIdenntifier + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage There can be at most 5 signed identifiers + */ + public function testAddRemoveSignedIdentifier() + { + $sample = TestResources::getQueueACLMultipleArraySample(); + $acl = new QueueACL(); + for ($i = 0; $i < 5; ++$i) { + $acl->addSignedIdentifier( + $sample[$i]['Id'], + $sample[$i]['AccessPolicy']['Start'], + $sample[$i]['AccessPolicy']['Expiry'], + $sample[$i]['AccessPolicy']['Permission'] + ); + } + + $this->assertEquals(5, count($acl->getSignedIdentifiers())); + + //remove a non-exist signed identifier. + $acl->removeSignedIdentifier('random_signed_identifier'); + $this->assertEquals(5, count($acl->getSignedIdentifiers())); + //remove an exist signed identifier. + $acl->removeSignedIdentifier('a'); + $this->assertEquals(4, count($acl->getSignedIdentifiers())); + //add this signed identifier back. + $acl->addSignedIdentifier( + $sample[0]['Id'], + $sample[0]['AccessPolicy']['Start'], + $sample[0]['AccessPolicy']['Expiry'], + $sample[0]['AccessPolicy']['Permission'] + ); + $this->assertEquals(5, count($acl->getSignedIdentifiers())); + //add a signed identifier with existing ID. + $acl->addSignedIdentifier( + $sample[0]['Id'], + $sample[0]['AccessPolicy']['Start'], + $sample[0]['AccessPolicy']['Expiry'], + $sample[0]['AccessPolicy']['Permission'] + ); + $this->assertEquals(5, count($acl->getSignedIdentifiers())); + //add 6th signed identifier, expect error. + $acl->addSignedIdentifier( + $sample[5]['Id'], + $sample[5]['AccessPolicy']['Start'], + $sample[5]['AccessPolicy']['Expiry'], + $sample[5]['AccessPolicy']['Permission'] + ); + } +} diff --git a/tests/unit/Common/Internal/Authentication/SharedAccessSignatureHelperTest.php b/tests/unit/Common/Internal/Authentication/SharedAccessSignatureHelperTest.php index b11688ddf..6950be1d9 100644 --- a/tests/unit/Common/Internal/Authentication/SharedAccessSignatureHelperTest.php +++ b/tests/unit/Common/Internal/Authentication/SharedAccessSignatureHelperTest.php @@ -27,7 +27,7 @@ use MicrosoftAzure\Storage\Common\ServiceException; use MicrosoftAzure\Storage\Tests\framework\TestResources; use MicrosoftAzure\Storage\Tests\Framework\ReflectionTestBase; -use MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureHelper; +use MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper; /** * Unit tests for class SharedAccessSignatureHelper @@ -42,7 +42,7 @@ class SharedAccessSignatureHelperTest extends ReflectionTestBase { /** - * @covers MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureHelper::__construct + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::__construct */ public function testConstruct() { @@ -60,7 +60,7 @@ public function testConstruct() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureHelper::validateAndSanitizeSignedService + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::validateAndSanitizeSignedService */ public function testValidateAndSanitizeSignedService() { @@ -78,8 +78,8 @@ public function testValidateAndSanitizeSignedService() $expected = array(); $expected[] = "bqtf"; $expected[] = "bqtf"; - $expected[] = "fqtb"; - $expected[] = "fq"; + $expected[] = "bqtf"; + $expected[] = "qf"; $expected[] = "b"; for ($i = 0; $i < count($authorizedSignedService); $i++) { @@ -92,9 +92,9 @@ public function testValidateAndSanitizeSignedService() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureHelper::validateAndSanitizeSignedService + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::validateAndSanitizeSignedService * @expectedException InvalidArgumentException - * @expectedExceptionMessage The signed service should only be a combination of the letters b(lob) q(ueue) t(able) or f(ile). + * @expectedExceptionMessage The string should only be a combination of */ public function testValidateAndSanitizeSignedServiceThrowsException() { @@ -108,7 +108,7 @@ public function testValidateAndSanitizeSignedServiceThrowsException() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureHelper::validateAndSanitizeSignedResourceType + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::validateAndSanitizeSignedResourceType */ public function testValidateAndSanitizeSignedResourceType() { @@ -124,13 +124,16 @@ public function testValidateAndSanitizeSignedResourceType() $expected = array(); $expected[] = "sco"; - $expected[] = "ocs"; - $expected[] = "osc"; + $expected[] = "sco"; + $expected[] = "sco"; $expected[] = "o"; for ($i = 0; $i < count($authorizedSignedResourceType); $i++) { // Test - $actual = $validateAndSanitizeSignedResourceType->invokeArgs($sasHelper, array($authorizedSignedResourceType[$i])); + $actual = $validateAndSanitizeSignedResourceType->invokeArgs( + $sasHelper, + array($authorizedSignedResourceType[$i]) + ); // Assert $this->assertEquals($expected[$i], $actual); @@ -138,9 +141,9 @@ public function testValidateAndSanitizeSignedResourceType() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureHelper::validateAndSanitizeSignedResourceType + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::validateAndSanitizeSignedResourceType * @expectedException InvalidArgumentException - * @expectedExceptionMessage The signed resource type should only be a combination of the letters s(ervice) c(container) or o(bject). + * @expectedExceptionMessage The string should only be a combination of */ public function testValidateAndSanitizeSignedResourceTypeThrowsException() { @@ -155,7 +158,7 @@ public function testValidateAndSanitizeSignedResourceTypeThrowsException() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureHelper::validateAndSanitizeSignedProtocol + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::validateAndSanitizeSignedProtocol */ public function testValidateAndSanitizeSignedProtocol() { @@ -181,7 +184,7 @@ public function testValidateAndSanitizeSignedProtocol() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Authentication\SharedAccessSignatureHelper::validateAndSanitizeSignedProtocol + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::validateAndSanitizeSignedProtocol * @expectedException InvalidArgumentException * @expectedExceptionMessage is invalid */ @@ -197,163 +200,37 @@ public function testValidateAndSanitizeSignedProtocolThrowsException() $validateAndSanitizeSignedProtocol->invokeArgs($sasHelper, array($unauthorizedSignedProtocol)); } + /** + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::__construct + * @covers MicrosoftAzure\Storage\Common\SharedAccessSignatureHelper::generateAccountSharedAccessSignatureToken + */ public function testGenerateAccountSharedAccessSignatureToken() { // Setup - $accountName = "phptests"; - $accountKey = "WaZvixrkMok53QDmj8Tc99+BV6vO9cCOJNsdm+wD9QVEScwl8c1eYPcQ182ndNFqxX1+SEKs18SmOxh8OpzIUg=="; + $accountName = TestResources::ACCOUNT_NAME; + $accountKey = TestResources::KEY4; // Test $sasHelper = new SharedAccessSignatureHelper($accountName, $accountKey); // create the test cases - $testCases = GenerateAccountSASTestCase::BuildTestCases(); + $testCases = TestResources::getSASInterestingUTCases(); - foreach($testCases as $testCase) { - + foreach ($testCases as $testCase) { // test $actualSignature = $sasHelper->generateAccountSharedAccessSignatureToken( - $testCase->getSignedVersion(), - $testCase->getSignedPermission(), - $testCase->getSignedService(), - $testCase->getSignedResourceType(), - $testCase->getSignedExpiracy(), - $testCase->getSignedStart(), - $testCase->getSignedIP(), - $testCase->getSignedProtocol() + $testCase[0], + $testCase[1], + $testCase[2], + $testCase[3], + $testCase[4], + $testCase[5], + $testCase[6], + $testCase[7] ); // assert - $this->assertEquals($testCase->getExpectedSignature(), urlencode($actualSignature)); + $this->assertEquals($testCase[8], urlencode($actualSignature)); } } } - -class GenerateAccountSASTestCase { - - protected $signedVersion; - protected $signedService; - protected $signedResourceType; - protected $signedPermission; - protected $signedExpiracy; - protected $signedStart; - protected $signedProtocol; - protected $signedIP; - protected $expectedSignature; - - public function __construct( - $signedVersion, - $signedService, - $signedResourceType, - $signedPermission, - $signedExpiracy, - $signedStart, - $signedProtocol, - $signedIP, - $expectedSignature - ) { - $this->signedVersion = $signedVersion; - $this->signedService = $signedService; - $this->signedResourceType = $signedResourceType; - $this->signedPermission = $signedPermission; - $this->signedExpiracy = $signedExpiracy; - $this->signedStart = $signedStart; - $this->signedProtocol = $signedProtocol; - $this->signedIP = $signedIP; - $this->expectedSignature = $expectedSignature; - } - - public function getSignedVersion() { - return $this->signedVersion; - } - - public function getSignedService() { - return $this->signedService; - } - - public function getSignedResourceType() { - return $this->signedResourceType; - } - - public function getSignedPermission() { - return $this->signedPermission; - } - - public function getSignedExpiracy() { - return $this->signedExpiracy; - } - - public function getSignedStart() { - return $this->signedStart; - } - - public function getSignedProtocol() { - return $this->signedProtocol; - } - - public function getSignedIP() { - return $this->signedIP; - } - - public function getExpectedSignature() { - return $this->expectedSignature; - } - - public static function BuildTestCases() { - $testCases = array(); - - // ?sv=2016-05-31&ss=bfqt&srt=sco&sp=rwdlacup&se=2017-03-24T21:14:01Z&st=2017-03-17T13:14:01Z&spr=https&sig=ZpEYbkT%2B9NJTYyMIuFnXQ9RzOehYF1mjnsk00B%2FX1nw%3D - $testCases[] = new GenerateAccountSASTestCase( - "2016-05-31", // signedVersion - "bfqt", // signedService - "sco", // signedResourceType - "rwdlacup", // signedPermission - "2017-03-24T21:14:01Z", // signedExpiracy - "2017-03-17T13:14:01Z", // signedStart - "https", // signedProtocol - "", // signedIP - "ZpEYbkT%2B9NJTYyMIuFnXQ9RzOehYF1mjnsk00B%2FX1nw%3D" // expectedSignature - ); - - // ?sv=2016-05-31&ss=bfqt&srt=sco&sp=rwdlacup&se=2017-03-24T21:14:01Z&st=2017-03-17T13:14:01Z&sip=168.1.5.65&spr=https,http&sig=GZcWRjLJk%2FJSbM9zKb1XufTt2OueTSSgwsa03nYn5yM%3D - $testCases[] = new GenerateAccountSASTestCase( - "2016-05-31", // signedVersion - "bfqt", // signedService - "sco", // signedResourceType - "rwdlacup", // signedPermission - "2017-03-24T21:14:01Z", // signedExpiracy - "2017-03-17T13:14:01Z", // signedStart - "https,http", // signedProtocol - "168.1.5.65", // signedIP - "GZcWRjLJk%2FJSbM9zKb1XufTt2OueTSSgwsa03nYn5yM%3D" // expectedSignature - ); - - // ?sv=2016-05-31&ss=bf&srt=s&sp=rw&se=2017-03-24T00:00:00Z&st=2017-03-17T00:00:00Z&spr=https&sig=1%2BAozefG5VZDx9XorEGrAjOiTS8dX%2BJelK5SW91Zvq0%3D - $testCases[] = new GenerateAccountSASTestCase( - "2016-05-31", // signedVersion - "bf", // signedService - "s", // signedResourceType - "rw", // signedPermission - "2017-03-24T00:00:00Z", // signedExpiracy - "2017-03-17T00:00:00Z", // signedStart - "https", // signedProtocol - "", // signedIP - "1%2BAozefG5VZDx9XorEGrAjOiTS8dX%2BJelK5SW91Zvq0%3D" // expectedSignature - ); - - // ?sv=2016-05-31&ss=q&srt=o&sp=up&se=2017-03-24T00:00:00Z&st=2017-03-17T00:00:00Z&spr=https&sig=k1BKI65TdXs7rdAJiqDSJ6wYHjfJD0CJgplvOyqBK7Y%3D - $testCases[] = new GenerateAccountSASTestCase( - "2016-05-31", // signedVersion - "q", // signedService - "o", // signedResourceType - "up", // signedPermission - "2017-03-24T00:00:00Z", // signedExpiracy - "2017-03-17T00:00:00Z", // signedStart - "https", // signedProtocol - "", // signedIP - "k1BKI65TdXs7rdAJiqDSJ6wYHjfJD0CJgplvOyqBK7Y%3D" // expectedSignature - ); - - return $testCases; - } -} diff --git a/tests/unit/Common/Internal/InvalidArgumentTypeExceptionTest.php b/tests/unit/Common/Internal/InvalidArgumentTypeExceptionTest.php index 28b7135de..615d23a0b 100644 --- a/tests/unit/Common/Internal/InvalidArgumentTypeExceptionTest.php +++ b/tests/unit/Common/Internal/InvalidArgumentTypeExceptionTest.php @@ -24,7 +24,7 @@ namespace MicrosoftAzure\Storage\Tests\unit\Common\Internal; -use MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException; +use MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException; /** * Unit tests for class InvalidArgumentTypeException @@ -39,7 +39,7 @@ class InvalidArgumentTypeExceptionTest extends \PHPUnit_Framework_TestCase { /** - * @covers MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException::__construct + * @covers MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException::__construct */ public function testConstruct() { diff --git a/tests/unit/Common/Internal/LoggerTest.php b/tests/unit/Common/Internal/LoggerTest.php index 7574ad5d1..b966304f6 100644 --- a/tests/unit/Common/Internal/LoggerTest.php +++ b/tests/unit/Common/Internal/LoggerTest.php @@ -24,7 +24,7 @@ namespace MicrosoftAzure\Storage\Tests\unit\Common\Internal; -use MicrosoftAzure\Storage\Common\Internal\Logger; +use MicrosoftAzure\Storage\Common\Logger; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Tests\Framework\VirtualFileSystem; @@ -41,8 +41,8 @@ class LoggerTest extends \PHPUnit_Framework_TestCase { /** - * @covers MicrosoftAzure\Storage\Common\Internal\Logger::log - * @covers MicrosoftAzure\Storage\Common\Internal\Logger::setLogFile + * @covers MicrosoftAzure\Storage\Common\Logger::log + * @covers MicrosoftAzure\Storage\Common\Logger::setLogFile */ public function testLogWithArray() { @@ -61,8 +61,8 @@ public function testLogWithArray() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Logger::log - * @covers MicrosoftAzure\Storage\Common\Internal\Logger::setLogFile + * @covers MicrosoftAzure\Storage\Common\Logger::log + * @covers MicrosoftAzure\Storage\Common\Logger::setLogFile */ public function testLogWithString() { diff --git a/tests/unit/Common/Internal/Middlewares/CommonRequestMiddlewareTest.php b/tests/unit/Common/Internal/Middlewares/CommonRequestMiddlewareTest.php index 1574e4d25..afac2d49d 100644 --- a/tests/unit/Common/Internal/Middlewares/CommonRequestMiddlewareTest.php +++ b/tests/unit/Common/Internal/Middlewares/CommonRequestMiddlewareTest.php @@ -15,7 +15,7 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal\Http + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -35,7 +35,7 @@ * Unit tests for class CommonRequestMiddleware * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal\Http + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE diff --git a/tests/unit/Common/Internal/Serialization/JsonSerializerTest.php b/tests/unit/Common/Internal/Serialization/JsonSerializerTest.php index b326a9393..7fd57b71d 100644 --- a/tests/unit/Common/Internal/Serialization/JsonSerializerTest.php +++ b/tests/unit/Common/Internal/Serialization/JsonSerializerTest.php @@ -26,7 +26,7 @@ use MicrosoftAzure\Storage\Tests\Framework\TestResources; use MicrosoftAzure\Storage\Common\Models\ServiceProperties; -use MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException; +use MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException; use MicrosoftAzure\Storage\Common\Internal\Serialization\JsonSerializer; use MicrosoftAzure\Storage\Common\Internal\Resources; @@ -153,7 +153,7 @@ public function testSerializeNull() $jsonSerializer = new JsonSerializer(); $testData = null; $expected = ""; - $this->setExpectedException('MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException', sprintf(Resources::INVALID_PARAM_MSG, 'array', 'array')); + $this->setExpectedException('MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException', sprintf(Resources::INVALID_PARAM_MSG, 'array', 'array')); // Test $actual = $jsonSerializer->serialize($testData); diff --git a/tests/unit/Common/Internal/Serialization/XmlSerializerTest.php b/tests/unit/Common/Internal/Serialization/XmlSerializerTest.php index 39793c3d0..5d9b31a7d 100644 --- a/tests/unit/Common/Internal/Serialization/XmlSerializerTest.php +++ b/tests/unit/Common/Internal/Serialization/XmlSerializerTest.php @@ -26,7 +26,7 @@ use MicrosoftAzure\Storage\Tests\Framework\TestResources; use MicrosoftAzure\Storage\Common\Models\ServiceProperties; -use MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException; +use MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException; use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; /** @@ -53,11 +53,10 @@ public function testUnserialize() $properties = ServiceProperties::create($propertiesSample); $xml = $properties->toXml($xmlSerializer); $expected = $properties->toArray(); - // Test $actual = $xmlSerializer->unserialize($xml); - $this->assertEquals($expected, $actual); + $this->assertEquals($propertiesSample, $actual); } /** @@ -72,7 +71,7 @@ public function testSerialize() $properties = ServiceProperties::create($propertiesSample); $expected = $properties->toXml($xmlSerializer); $array = $properties->toArray(); - $serializerProperties = array(XmlSerializer::ROOT_NAME => ServiceProperties::$xmlRootName); + $serializerProperties = array(XmlSerializer::ROOT_NAME => "StorageServiceProperties"); // Test $actual = $xmlSerializer->serialize($array, $serializerProperties); diff --git a/tests/unit/Common/ServiceOptionsBaseTest.php b/tests/unit/Common/Internal/ServiceOptionsBaseTest.php similarity index 78% rename from tests/unit/Common/ServiceOptionsBaseTest.php rename to tests/unit/Common/Internal/ServiceOptionsBaseTest.php index cad689855..94e229221 100644 --- a/tests/unit/Common/ServiceOptionsBaseTest.php +++ b/tests/unit/Common/Internal/ServiceOptionsBaseTest.php @@ -15,7 +15,7 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Blob\Models + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal * @author Azure Storage PHP SDK * @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -24,13 +24,13 @@ namespace MicrosoftAzure\Storage\Tests\unit\Common; -use MicrosoftAzure\Storage\Common\ServiceOptionsBase; +use MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase; /** * Unit tests for class ServiceOptionsBase * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Blob\Models + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal * @author Azure Storage PHP SDK * @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -39,8 +39,8 @@ class ServiceOptionsBaseTest extends \PHPUnit_Framework_TestCase { /** - * @covers MicrosoftAzure\Storage\Common\ServiceOptionsBase::setTimeout - * @covers MicrosoftAzure\Storage\Common\ServiceOptionsBase::getTimeout + * @covers MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase::setTimeout + * @covers MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase::getTimeout */ public function testSetGetTimeout() { @@ -56,8 +56,8 @@ public function testSetGetTimeout() } /** - * @covers MicrosoftAzure\Storage\Common\ServiceOptionsBase::setRequestOptions - * @covers MicrosoftAzure\Storage\Common\ServiceOptionsBase::getRequestOptions + * @covers MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase::setRequestOptions + * @covers MicrosoftAzure\Storage\Common\Internal\ServiceOptionsBase::getRequestOptions */ public function testSetGetRequestOptions() { diff --git a/tests/unit/Common/Internal/UtilitiesTest.php b/tests/unit/Common/Internal/UtilitiesTest.php index 55224c7b6..203bbd533 100644 --- a/tests/unit/Common/Internal/UtilitiesTest.php +++ b/tests/unit/Common/Internal/UtilitiesTest.php @@ -217,12 +217,11 @@ public function testUnserialize() $properties = ServiceProperties::create($propertiesSample); $xmlSerializer = new XmlSerializer(); $xml = $properties->toXml($xmlSerializer); - $expected = $properties->toArray(); // Test $actual = Utilities::unserialize($xml); - $this->assertEquals($expected, $actual); + $this->assertEquals($propertiesSample, $actual); } /** @@ -234,16 +233,29 @@ public function testSerialize() // Setup $propertiesSample = TestResources::getServicePropertiesSample(); $properties = ServiceProperties::create($propertiesSample); + $expected = '' . "\n"; $expected .= '1.0true'; $expected .= 'falsetruetrue'; $expected .= '201.0'; $expected .= 'truefalse'; - $expected .= 'true20'; + $expected .= 'true20'; + $expected .= 'http://www.microsoft.com,http://www.bing.com'; + $expected .= 'GET,PUT'; + $expected .= 'x-ms-meta-customheader0,x-ms-meta-target0*'; + $expected .= 'x-ms-meta-customheader0,x-ms-meta-data0*'; + $expected .= '500'; + $expected .= 'http://www.azure.com,http://www.office.com'; + $expected .= 'POST,HEAD'; + $expected .= 'x-ms-meta-customheader1,x-ms-meta-target1*'; + $expected .= 'x-ms-meta-customheader1,x-ms-meta-data1*'; + $expected .= '350'; + $expected .= ''; + $array = $properties->toArray(); // Test - $actual = Utilities::serialize($array, ServiceProperties::$xmlRootName); + $actual = Utilities::serialize($array, "StorageServiceProperties"); $this->assertEquals($expected, $actual); } diff --git a/tests/unit/Common/Internal/ValidateTest.php b/tests/unit/Common/Internal/ValidateTest.php index 3e917ebd1..f391e2c31 100644 --- a/tests/unit/Common/Internal/ValidateTest.php +++ b/tests/unit/Common/Internal/ValidateTest.php @@ -25,7 +25,7 @@ namespace MicrosoftAzure\Storage\Tests\unit\Common\Internal; use MicrosoftAzure\Storage\Common\Internal\Validate; -use MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException; +use MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Common\Internal\Utilities; diff --git a/tests/unit/Common/Internal/Middlewares/HistoryMiddlewareTest.php b/tests/unit/Common/Middlewares/HistoryMiddlewareTest.php similarity index 75% rename from tests/unit/Common/Internal/Middlewares/HistoryMiddlewareTest.php rename to tests/unit/Common/Middlewares/HistoryMiddlewareTest.php index ffea97356..99bd25e8a 100644 --- a/tests/unit/Common/Internal/Middlewares/HistoryMiddlewareTest.php +++ b/tests/unit/Common/Middlewares/HistoryMiddlewareTest.php @@ -15,16 +15,16 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal\Http + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE * @link https://github.com/azure/azure-storage-php */ -namespace MicrosoftAzure\Storage\Tests\unit\Common\Internal\Middlewares; +namespace MicrosoftAzure\Storage\Tests\unit\Common\Middlewares; -use MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware; +use MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware; use MicrosoftAzure\Storage\Tests\Framework\ReflectionTestBase; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Psr7\Response; @@ -34,7 +34,7 @@ * Unit tests for class HistoryMiddleware * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal\Http + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -44,9 +44,9 @@ class HistoryMiddlewareTest extends ReflectionTestBase { /** - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware::onFulfilled - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware::getHistory - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware::__construct + * @covers MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware::onFulfilled + * @covers MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware::getHistory + * @covers MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware::__construct */ public function testOnFulfilled() { @@ -66,9 +66,9 @@ public function testOnFulfilled() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware::onRejected - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware::getHistory - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware::__construct + * @covers MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware::onRejected + * @covers MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware::getHistory + * @covers MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware::__construct */ public function testOnRejected() { @@ -94,10 +94,10 @@ public function testOnRejected() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware::addHistory - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware::clearHistory - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware::getHistory - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\HistoryMiddleware::__construct + * @covers MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware::addHistory + * @covers MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware::clearHistory + * @covers MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware::getHistory + * @covers MicrosoftAzure\Storage\Common\Middlewares\HistoryMiddleware::__construct */ public function testAddGetClearHistory() { diff --git a/tests/unit/Common/Internal/Middlewares/MiddlewareBaseTest.php b/tests/unit/Common/Middlewares/MiddlewareBaseTest.php similarity index 87% rename from tests/unit/Common/Internal/Middlewares/MiddlewareBaseTest.php rename to tests/unit/Common/Middlewares/MiddlewareBaseTest.php index d601731e7..9d16f7a93 100644 --- a/tests/unit/Common/Internal/Middlewares/MiddlewareBaseTest.php +++ b/tests/unit/Common/Middlewares/MiddlewareBaseTest.php @@ -15,16 +15,16 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal\Http + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE * @link https://github.com/azure/azure-storage-php */ -namespace MicrosoftAzure\Storage\Tests\unit\Common\Internal\Middlewares; +namespace MicrosoftAzure\Storage\Tests\unit\Common\Middlewares; -use MicrosoftAzure\Storage\Common\Internal\Middlewares\MiddlewareBase; +use MicrosoftAzure\Storage\Common\Middlewares\MiddlewareBase; use MicrosoftAzure\Storage\Tests\Framework\ReflectionTestBase; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Psr7\Response; @@ -35,7 +35,7 @@ * Unit tests for class MiddlewareBase * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal\Http + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal\Middlewares * @author Azure Storage PHP SDK * @copyright 2017 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -45,7 +45,7 @@ class MiddlewareBaseTest extends ReflectionTestBase { /** - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\MiddlewareBase::__invoke + * @covers MicrosoftAzure\Storage\Common\Middlewares\MiddlewareBase::__invoke */ public function testInvoke() { @@ -60,7 +60,7 @@ public function testInvoke() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\MiddlewareBase::onRequest + * @covers MicrosoftAzure\Storage\Common\Middlewares\MiddlewareBase::onRequest * @depends testInvoke */ public function testOnRequest() @@ -73,7 +73,7 @@ public function testOnRequest() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\MiddlewareBase::onFulfilled + * @covers MicrosoftAzure\Storage\Common\Middlewares\MiddlewareBase::onFulfilled * @depends testInvoke */ public function testOnFulfilled() @@ -88,7 +88,7 @@ public function testOnFulfilled() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\Middlewares\MiddlewareBase::onRejected + * @covers MicrosoftAzure\Storage\Common\Middlewares\MiddlewareBase::onRejected * @depends testInvoke */ public function testOnRejected() diff --git a/tests/unit/Common/Internal/RetryMiddlewareFactoryTest.php b/tests/unit/Common/Middlewares/RetryMiddlewareFactoryTest.php similarity index 83% rename from tests/unit/Common/Internal/RetryMiddlewareFactoryTest.php rename to tests/unit/Common/Middlewares/RetryMiddlewareFactoryTest.php index 5c488e084..e8789b208 100644 --- a/tests/unit/Common/Internal/RetryMiddlewareFactoryTest.php +++ b/tests/unit/Common/Middlewares/RetryMiddlewareFactoryTest.php @@ -15,16 +15,16 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Common\Internal + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Middlewares * @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 */ -namespace MicrosoftAzure\Storage\Tests\unit\Common\Internal; +namespace MicrosoftAzure\Storage\Tests\unit\Common\Middlewares; -use MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory; +use MicrosoftAzure\Storage\Common\Middlewares\RetryMiddlewareFactory; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Tests\Framework\ReflectionTestBase; use GuzzleHttp\Psr7\Response; @@ -33,7 +33,7 @@ class RetryMiddlewareFactoryTest extends ReflectionTestBase { /** - * @covers MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory::create + * @covers MicrosoftAzure\Storage\Common\RetryMiddlewareFactory::create * @expectedException InvalidArgumentException * @expectedExceptionMessage should be positive number */ @@ -48,7 +48,7 @@ public function testCreateWithNegativeNumberOfRetries() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory::create + * @covers MicrosoftAzure\Storage\Common\RetryMiddlewareFactory::create * @expectedException InvalidArgumentException * @expectedExceptionMessage should be positive number */ @@ -63,7 +63,7 @@ public function testCreateWithNegativeInterval() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory::create + * @covers MicrosoftAzure\Storage\Common\RetryMiddlewareFactory::create * @expectedException InvalidArgumentException * @expectedExceptionMessage is invalid */ @@ -78,7 +78,7 @@ public function testCreateWithInvalidType() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory::create + * @covers MicrosoftAzure\Storage\Common\RetryMiddlewareFactory::create * @expectedException InvalidArgumentException * @expectedExceptionMessage is invalid */ @@ -93,8 +93,8 @@ public function testCreateWithInvalidAccumulationMethod() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory::createRetryDecider - * @covers MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory::generalRetryDecider + * @covers MicrosoftAzure\Storage\Common\RetryMiddlewareFactory::createRetryDecider + * @covers MicrosoftAzure\Storage\Common\RetryMiddlewareFactory::generalRetryDecider */ public function testCreateRetryDeciderWithGeneralRetryDecider() { @@ -121,7 +121,7 @@ public function testCreateRetryDeciderWithGeneralRetryDecider() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory::createLinearDelayCalculator + * @covers MicrosoftAzure\Storage\Common\RetryMiddlewareFactory::createLinearDelayCalculator */ public function testCreateLinearDelayCalculator() { @@ -133,7 +133,7 @@ public function testCreateLinearDelayCalculator() } /** - * @covers MicrosoftAzure\Storage\Common\Internal\RetryMiddlewareFactory::createExponentialDelayCalculator + * @covers MicrosoftAzure\Storage\Common\RetryMiddlewareFactory::createExponentialDelayCalculator */ public function testCreateExponentialDelayCalculator() { diff --git a/tests/unit/Blob/Models/AccessPolicyTest.php b/tests/unit/Common/Models/AccessPolicyTest.php similarity index 70% rename from tests/unit/Blob/Models/AccessPolicyTest.php rename to tests/unit/Common/Models/AccessPolicyTest.php index 0908415ec..b6499fa94 100644 --- a/tests/unit/Blob/Models/AccessPolicyTest.php +++ b/tests/unit/Common/Models/AccessPolicyTest.php @@ -21,9 +21,10 @@ * @license https://github.com/azure/azure-storage-php/LICENSE * @link https://github.com/azure/azure-storage-php */ -namespace MicrosoftAzure\Storage\Tests\unit\Blob\Models; +namespace MicrosoftAzure\Storage\Tests\unit\Common\Models; -use MicrosoftAzure\Storage\Blob\Models\AccessPolicy; +use MicrosoftAzure\Storage\Common\Models\AccessPolicy; +use MicrosoftAzure\Storage\Tests\framework\TestResources; /** * Unit tests for class AccessPolicy @@ -104,36 +105,54 @@ public function testSetExpiry() } /** + * @covers MicrosoftAzure\Storage\Blob\Models\AccessPolicy::setPermission * @covers MicrosoftAzure\Storage\Blob\Models\AccessPolicy::getPermission */ - public function testGetPermission() + public function testSetPermission() { // Setup - $accessPolicy = new AccessPolicy(); - $expected = 'rw'; - $accessPolicy->setPermission($expected); - - // Test - $actual = $accessPolicy->getPermission(); - - // Assert - $this->assertEquals($expected, $actual); + $validPermissions = TestResources::getValidAccessPermission(); + $resourceArray = ['Blob', 'Container', 'Table', 'Queue']; + foreach ($resourceArray as $resourceType) { + $accessPolicy = new AccessPolicy($resourceType); + + foreach ($validPermissions[$resourceType] as $value) { + $expected = $value[1]; + + // Test + $accessPolicy->setPermission($value[0]); + // Assert + $this->assertEquals($expected, $accessPolicy->getPermission()); + } + } } - + /** * @covers MicrosoftAzure\Storage\Blob\Models\AccessPolicy::setPermission + * @covers MicrosoftAzure\Storage\Blob\Models\AccessPolicy::getPermission */ - public function testSetPermission() + public function testSetPermissionNegative() { // Setup - $accessPolicy = new AccessPolicy(); - $expected = 'rw'; - - // Test - $accessPolicy->setPermission($expected); - - // Assert - $this->assertEquals($expected, $accessPolicy->getPermission()); + $validPermissions = TestResources::getInvalidAccessPermission(); + $resourceArray = ['Blob', 'Container', 'Table', 'Queue']; + foreach ($resourceArray as $resourceType) { + $accessPolicy = new AccessPolicy($resourceType); + + foreach ($validPermissions[$resourceType] as $value) { + // Test + try { + $accessPolicy->setPermission($value); + } catch (\InvalidArgumentException $e) { + $this->assertStringStartsWith( + 'Invalid permission provided', + $e->getMessage() + ); + continue; + } + $this->assertTrue(false); + } + } } /** diff --git a/tests/unit/Common/Models/CORSTest.php b/tests/unit/Common/Models/CORSTest.php new file mode 100644 index 000000000..c62a94af3 --- /dev/null +++ b/tests/unit/Common/Models/CORSTest.php @@ -0,0 +1,109 @@ + + * @copyright 2016 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ + +namespace MicrosoftAzure\Storage\Tests\unit\Common\Models; + +use MicrosoftAzure\Storage\Common\Models\CORS; +use MicrosoftAzure\Storage\Tests\Framework\TestResources; +use MicrosoftAzure\Storage\Common\Internal\Utilities; +use MicrosoftAzure\Storage\Common\Internal\Resources; + +/** + * Unit tests for class CORS + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Tests\Unit\Common\Models + * @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 CORSTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers MicrosoftAzure\Storage\Common\Models\CORS::create + * @covers MicrosoftAzure\Storage\Common\Models\CORS::__construct + * @covers MicrosoftAzure\Storage\Common\Models\CORS::getAllowedOrigins + * @covers MicrosoftAzure\Storage\Common\Models\CORS::setAllowedOrigins + * @covers MicrosoftAzure\Storage\Common\Models\CORS::setAllowedMethods + * @covers MicrosoftAzure\Storage\Common\Models\CORS::getAllowedMethods + * @covers MicrosoftAzure\Storage\Common\Models\CORS::setAllowedHeaders + * @covers MicrosoftAzure\Storage\Common\Models\CORS::getAllowedHeaders + * @covers MicrosoftAzure\Storage\Common\Models\CORS::setExposedHeaders + * @covers MicrosoftAzure\Storage\Common\Models\CORS::getExposedHeaders + * @covers MicrosoftAzure\Storage\Common\Models\CORS::setMaxedAgeInSeconds + * @covers MicrosoftAzure\Storage\Common\Models\CORS::getMaxedAgeInSeconds + * @covers MicrosoftAzure\Storage\Common\Models\CORS::toArray + */ + public function testCreateAndToArray() + { + $parsedResponse = TestResources::getCORSSingle(); + + $cors = CORS::create($parsedResponse); + + $this->assertEquals($parsedResponse, $cors->toArray()); + } + + /** + * @covers MicrosoftAzure\Storage\Common\Models\CORS::create + * @covers MicrosoftAzure\Storage\Common\Models\CORS::__construct + * @expectedException \UnexpectedValueException + * @expectedExceptionMessage does not exist in the given array + */ + public function testCreateNegative() + { + $parsedResponse = array(); + + $cors = CORS::create($parsedResponse); + } + + /** + * @covers MicrosoftAzure\Storage\Common\Models\CORS::__construct + * @covers MicrosoftAzure\Storage\Common\Models\CORS::getAllowedOrigins + * @covers MicrosoftAzure\Storage\Common\Models\CORS::setAllowedOrigins + * @covers MicrosoftAzure\Storage\Common\Models\CORS::setAllowedMethods + * @covers MicrosoftAzure\Storage\Common\Models\CORS::getAllowedMethods + * @covers MicrosoftAzure\Storage\Common\Models\CORS::setAllowedHeaders + * @covers MicrosoftAzure\Storage\Common\Models\CORS::getAllowedHeaders + * @covers MicrosoftAzure\Storage\Common\Models\CORS::setExposedHeaders + * @covers MicrosoftAzure\Storage\Common\Models\CORS::getExposedHeaders + * @covers MicrosoftAzure\Storage\Common\Models\CORS::setMaxedAgeInSeconds + * @covers MicrosoftAzure\Storage\Common\Models\CORS::getMaxedAgeInSeconds + * @covers MicrosoftAzure\Storage\Common\Models\CORS::toArray + */ + public function testToArray() + { + $parsedResponse = TestResources::getCORSSingle(); + + $cors = new CORS( + ['http://www.microsoft.com', 'http://www.bing.com'], + ['GET', 'PUT'], + ['x-ms-meta-customheader0', 'x-ms-meta-target0*'], + ['x-ms-meta-customheader0', 'x-ms-meta-data0*'], + 500 + ); + + $this->assertEquals($parsedResponse, $cors->toArray()); + } +} diff --git a/tests/unit/Common/Models/ServicePropertiesTest.php b/tests/unit/Common/Models/ServicePropertiesTest.php index d985f8301..7a9b7b4d2 100644 --- a/tests/unit/Common/Models/ServicePropertiesTest.php +++ b/tests/unit/Common/Models/ServicePropertiesTest.php @@ -139,9 +139,19 @@ public function testToArray() { // Setup $properties = ServiceProperties::create(TestResources::getServicePropertiesSample()); + $corsesArray = array(); + if (count($properties->getCorses()) == 1) { + $corsesArray = ['CorsRule' => $properties->getCorses()[0]->toArray()]; + } else { + foreach ($properties->getCorses() as $cors) { + $corsesArray[] = ['CorsRule' => $cors->toArray()]; + } + } + $expected = array( 'Logging' => $properties->getLogging()->toArray(), - 'HourMetrics' => $properties->getMetrics()->toArray() + 'HourMetrics' => $properties->getMetrics()->toArray(), + 'Cors' => !empty($corsesArray) ? $corsesArray : null ); // Test diff --git a/tests/unit/Common/ServicesBuilderTest.php b/tests/unit/Common/ServicesBuilderTest.php index 74b16425d..c2c9209ec 100644 --- a/tests/unit/Common/ServicesBuilderTest.php +++ b/tests/unit/Common/ServicesBuilderTest.php @@ -29,7 +29,7 @@ use MicrosoftAzure\Storage\Common\Internal\MediaServicesSettings; use MicrosoftAzure\Storage\Common\ServicesBuilder; use MicrosoftAzure\Storage\Common\Configuration; -use MicrosoftAzure\Storage\Common\Internal\InvalidArgumentTypeException; +use MicrosoftAzure\Storage\Common\Exceptions\InvalidArgumentTypeException; /** * Unit tests for class ServicesBuilder diff --git a/tests/unit/Queue/Models/QueueACLTest.php b/tests/unit/Queue/Models/QueueACLTest.php new file mode 100644 index 000000000..bc928326f --- /dev/null +++ b/tests/unit/Queue/Models/QueueACLTest.php @@ -0,0 +1,100 @@ + + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +namespace MicrosoftAzure\Storage\Tests\unit\Queue\Models; + +use MicrosoftAzure\Storage\Queue\Models\QueueACL; +use MicrosoftAzure\Storage\Tests\Framework\TestResources; +use MicrosoftAzure\Storage\Common\Internal\Resources; +use MicrosoftAzure\Storage\Common\Internal\Utilities; +use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; + +/** + * Unit tests for class QueueACL + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Tests\Unit\Queue\Models + * @author Azure Storage PHP SDK + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +class QueueACLTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::create + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::getSignedIdentifiers + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::addSignedIdentifier + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::fromXml + */ + public function testCreateEmpty() + { + // Setup + $sample = array(); + + // Test + $acl = QueueACL::create($sample); + + // Assert + $this->assertCount(0, $acl->getSignedIdentifiers()); + } + + /** + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::create + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::getSignedIdentifiers + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::addSignedIdentifier + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::fromXml + */ + public function testCreateOneEntry() + { + // Setup + $sample = TestResources::getQueueACLOneEntrySample(); + + // Test + $acl = QueueACL::create($sample['SignedIdentifiers']); + + // Assert + $this->assertCount(1, $acl->getSignedIdentifiers()); + } + + /** + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::create + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::getPublicAccess + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::getSignedIdentifiers + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::addSignedIdentifier + * @covers MicrosoftAzure\Storage\Queue\Models\QueueACL::fromXml + */ + public function testCreateMultipleEntries() + { + // Setup + $sample = TestResources::getQueueACLMultipleEntriesSample(); + + // Test + $acl = QueueACL::create($sample['SignedIdentifiers']); + + // Assert + $this->assertCount(2, $acl->getSignedIdentifiers()); + + return $acl; + } +} diff --git a/tests/unit/Queue/Models/QueueMessageTest.php b/tests/unit/Queue/Models/QueueMessageTest.php index 20b22344e..8374a808a 100644 --- a/tests/unit/Queue/Models/QueueMessageTest.php +++ b/tests/unit/Queue/Models/QueueMessageTest.php @@ -85,7 +85,7 @@ public function testToXml() $array = array('MessageText' => $messageText); $queueMessage->setMessageText($messageText); $xmlSerializer = new XmlSerializer(); - $properties = array(XmlSerializer::ROOT_NAME => QueueMessage::$xmlRootName); + $properties = array(XmlSerializer::ROOT_NAME => "QueueMessage"); $expected = $xmlSerializer->serialize($array, $properties); // Test diff --git a/tests/unit/Queue/QueueRestProxyTest.php b/tests/unit/Queue/QueueRestProxyTest.php index 69b4c9817..a7c4ae5f0 100644 --- a/tests/unit/Queue/QueueRestProxyTest.php +++ b/tests/unit/Queue/QueueRestProxyTest.php @@ -37,9 +37,10 @@ use MicrosoftAzure\Storage\Queue\Models\PeekMessagesOptions; use MicrosoftAzure\Storage\Queue\Models\UpdateMessageResult; use MicrosoftAzure\Storage\Queue\Models\QueueServiceOptions; +use MicrosoftAzure\Storage\Queue\Models\QueueACL; use MicrosoftAzure\Storage\Tests\Framework\TestResources; use MicrosoftAzure\Storage\Common\Internal\Resources; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; /** * Unit tests for QueueRestProxy class @@ -146,7 +147,7 @@ public function testListQueuesWithNextMarker() /** * @covers MicrosoftAzure\Storage\Queue\QueueRestProxy::listQueues - * @expectedException MicrosoftAzure\Storage\Common\ServiceException + * @expectedException MicrosoftAzure\Storage\Common\Exceptions\ServiceException * @expectedExceptionMessage 400 */ public function testListQueuesWithInvalidNextMarkerFail() @@ -261,7 +262,7 @@ public function testCreateQueueWithMetadata() /** * @covers MicrosoftAzure\Storage\Queue\QueueRestProxy::createQueue - * @expectedException MicrosoftAzure\Storage\Common\ServiceException + * @expectedException MicrosoftAzure\Storage\Common\Exceptions\ServiceException * @expectedExceptionMessage 400 */ public function testCreateQueueInvalidNameFail() @@ -293,7 +294,7 @@ public function testDeleteQueue() /** * @covers MicrosoftAzure\Storage\Queue\QueueRestProxy::deleteQueue - * @expectedException MicrosoftAzure\Storage\Common\ServiceException + * @expectedException MicrosoftAzure\Storage\Common\Exceptions\ServiceException * @expectedExceptionMessage 404 */ public function testDeleteQueueFail() @@ -307,19 +308,6 @@ public function testDeleteQueueFail() /** * @covers MicrosoftAzure\Storage\Queue\QueueRestProxy::getServiceProperties - */ - public function testGetServiceProperties() - { - $this->skipIfEmulated(); - - // Test - $result = $this->restProxy->getServiceProperties(); - - // Assert - $this->assertEquals($this->defaultProperties->toArray(), $result->getValue()->toArray()); - } - - /** * @covers MicrosoftAzure\Storage\Queue\QueueRestProxy::setServiceProperties */ public function testSetServiceProperties() @@ -692,4 +680,36 @@ public function testUpdateMessage() $actual = $messages[0]; $this->assertEquals($expectedText, $actual->getMessageText()); } + + /** + * @covers MicrosoftAzure\Storage\Queue\QueueRestProxy::getQueueAcl + * @covers MicrosoftAzure\Storage\Queue\QueueRestProxy::getQueueAclAsync + * @covers MicrosoftAzure\Storage\Queue\QueueRestProxy::setQueueAcl + * @covers MicrosoftAzure\Storage\Queue\QueueRestProxy::setQueueAclAsync + */ + public function testGetSetQueueAcl() + { + // Setup + $name = 'testgetsetqueueacl'; + $this->createQueue($name); + $sample = TestResources::getQueueACLMultipleEntriesSample(); + $acl = QueueACL::create($sample['SignedIdentifiers']); + //because the time is randomized, this should create a different instance + $negativeSample = TestResources::getQueueACLMultipleEntriesSample(); + $negative = QueueACL::create($negativeSample['SignedIdentifiers']); + + // Test + $this->restProxy->setQueueAcl($name, $acl); + $resultAcl = $this->restProxy->getQueueAcl($name); + + $this->assertEquals( + $acl->getSignedIdentifiers(), + $resultAcl->getSignedIdentifiers() + ); + + $this->assertFalse( + $resultAcl->getSignedIdentifiers() == $negative->getSignedIdentifiers(), + 'Should not equal to the negative test case' + ); + } } diff --git a/tests/unit/Table/Internal/AtomReaderWriterTest.php b/tests/unit/Table/Internal/AtomReaderWriterTest.php index 426be5422..33d84cbb2 100644 --- a/tests/unit/Table/Internal/AtomReaderWriterTest.php +++ b/tests/unit/Table/Internal/AtomReaderWriterTest.php @@ -257,7 +257,7 @@ public function testParseEntities() 890 John true - 2012-01-26T18:26:19.0000473Z + 2012-01-26T18:26:19.0000470Z @@ -278,7 +278,7 @@ public function testParseEntities() 890 John true - 2012-01-26T18:26:19.0000473Z + 2012-01-26T18:26:19.0000470Z @@ -299,7 +299,7 @@ public function testParseEntities() 890 John true - 2012-01-26T18:26:19.0000473Z + 2012-01-26T18:26:19.0000470Z diff --git a/tests/unit/Table/Models/BatchErrorTest.php b/tests/unit/Table/Models/BatchErrorTest.php index 5a79e8c0f..d445bf5b8 100644 --- a/tests/unit/Table/Models/BatchErrorTest.php +++ b/tests/unit/Table/Models/BatchErrorTest.php @@ -25,7 +25,7 @@ namespace MicrosoftAzure\Storage\Tests\unit\Table\Models; use MicrosoftAzure\Storage\Table\Models\BatchError; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use GuzzleHttp\Psr7\Response; /** diff --git a/tests/unit/Table/Models/EdmTypeTest.php b/tests/unit/Table/Models/EdmTypeTest.php index b1846c030..c8ba24389 100644 --- a/tests/unit/Table/Models/EdmTypeTest.php +++ b/tests/unit/Table/Models/EdmTypeTest.php @@ -210,6 +210,29 @@ public function testValidateEdmValueWithBinary() // Assert $this->assertEquals($expected, $actual); } + + /** + * @covers MicrosoftAzure\Storage\Table\Models\EdmType::validateEdmValue + */ + public function testValidateEdmValueWithDouble() + { + // Setup + $type = EdmType::DOUBLE; + $values = array(); + $values[] = 1; + $values[] = PHP_INT_MAX; + $values[] = pi(); + $values[] = 1.0; + $expected = true; + + // Test + foreach ($values as $value) { + $actual = EdmType::validateEdmValue($type, $value); + + // Assert + $this->assertEquals($expected, $actual); + } + } /** * @covers MicrosoftAzure\Storage\Table\Models\EdmType::validateEdmValue diff --git a/tests/unit/Table/Models/TableACLTest.php b/tests/unit/Table/Models/TableACLTest.php new file mode 100644 index 000000000..94056aa53 --- /dev/null +++ b/tests/unit/Table/Models/TableACLTest.php @@ -0,0 +1,100 @@ + + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +namespace MicrosoftAzure\Storage\Tests\unit\Table\Models; + +use MicrosoftAzure\Storage\Table\Models\TableACL; +use MicrosoftAzure\Storage\Tests\Framework\TestResources; +use MicrosoftAzure\Storage\Common\Internal\Resources; +use MicrosoftAzure\Storage\Common\Internal\Utilities; +use MicrosoftAzure\Storage\Common\Internal\Serialization\XmlSerializer; + +/** + * Unit tests for class TableACL + * + * @category Microsoft + * @package MicrosoftAzure\Storage\Tests\Unit\Table\Models + * @author Azure Storage PHP SDK + * @copyright 2017 Microsoft Corporation + * @license https://github.com/azure/azure-storage-php/LICENSE + * @link https://github.com/azure/azure-storage-php + */ +class TableACLTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::create + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::getSignedIdentifiers + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::addSignedIdentifier + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::fromXml + */ + public function testCreateEmpty() + { + // Setup + $sample = array(); + + // Test + $acl = TableACL::create($sample); + + // Assert + $this->assertCount(0, $acl->getSignedIdentifiers()); + } + + /** + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::create + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::getSignedIdentifiers + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::addSignedIdentifier + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::fromXml + */ + public function testCreateOneEntry() + { + // Setup + $sample = TestResources::getTableACLOneEntrySample(); + + // Test + $acl = TableACL::create($sample['SignedIdentifiers']); + + // Assert + $this->assertCount(1, $acl->getSignedIdentifiers()); + } + + /** + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::create + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::getPublicAccess + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::getSignedIdentifiers + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::addSignedIdentifier + * @covers MicrosoftAzure\Storage\Table\Models\TableACL::fromXml + */ + public function testCreateMultipleEntries() + { + // Setup + $sample = TestResources::getTableACLMultipleEntriesSample(); + + // Test + $acl = TableACL::create($sample['SignedIdentifiers']); + + // Assert + $this->assertCount(2, $acl->getSignedIdentifiers()); + + return $acl; + } +} diff --git a/tests/unit/Table/TableRestProxyTest.php b/tests/unit/Table/TableRestProxyTest.php index 72f561d54..c893fcd3b 100644 --- a/tests/unit/Table/TableRestProxyTest.php +++ b/tests/unit/Table/TableRestProxyTest.php @@ -15,20 +15,20 @@ * PHP version 5 * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Table\internal + * @package MicrosoftAzure\Storage\Tests\Unit\Table * @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 */ -namespace MicrosoftAzure\Storage\Tests\Unit\Table\internal; +namespace MicrosoftAzure\Storage\Tests\Unit\Table; use MicrosoftAzure\Storage\Table\Internal\AtomReaderWriter; use MicrosoftAzure\Storage\Table\Internal\MimeReaderWriter; use MicrosoftAzure\Storage\Tests\Framework\TableServiceRestProxyTestBase; use MicrosoftAzure\Storage\Common\Internal\Utilities; -use MicrosoftAzure\Storage\Common\ServiceException; +use MicrosoftAzure\Storage\Common\Exceptions\ServiceException; use MicrosoftAzure\Storage\Tests\Framework\TestResources; use MicrosoftAzure\Storage\Common\Internal\Resources; use MicrosoftAzure\Storage\Table\TableRestProxy; @@ -37,6 +37,7 @@ use MicrosoftAzure\Storage\Table\Models\Query; use MicrosoftAzure\Storage\Table\Models\Filters\Filter; use MicrosoftAzure\Storage\Table\Models\Entity; +use MicrosoftAzure\Storage\Table\Models\TableACL; use MicrosoftAzure\Storage\Table\Models\EdmType; use MicrosoftAzure\Storage\Table\Models\QueryEntitiesOptions; use MicrosoftAzure\Storage\Table\Models\BatchOperations; @@ -46,7 +47,7 @@ * Unit tests for class TableRestProxy * * @category Microsoft - * @package MicrosoftAzure\Storage\Tests\Unit\Table\internal + * @package MicrosoftAzure\Storage\Tests\Unit\Table * @author Azure Storage PHP SDK * @copyright 2016 Microsoft Corporation * @license https://github.com/azure/azure-storage-php/LICENSE @@ -54,23 +55,8 @@ */ class TableRestProxyTest extends TableServiceRestProxyTestBase { - /** * @covers MicrosoftAzure\Storage\Table\TableRestProxy::getServiceProperties - * @covers MicrosoftAzure\Storage\Common\Internal\ServiceRestProxy::sendContext - */ - public function testGetServiceProperties() - { - $this->skipIfEmulated(); - - // Test - $result = $this->restProxy->getServiceProperties(); - - // Assert - $this->assertEquals($this->defaultProperties->toArray(), $result->getValue()->toArray()); - } - - /** * @covers MicrosoftAzure\Storage\Table\TableRestProxy::setServiceProperties * @covers MicrosoftAzure\Storage\Common\Internal\ServiceRestProxy::sendContext */ @@ -1194,4 +1180,41 @@ public function testBatchWithDifferentPKFail() // Assert $this->assertTrue(true); } + + /** + * @covers MicrosoftAzure\Storage\Table\TableRestProxy::getTableAcl + * @covers MicrosoftAzure\Storage\Table\TableRestProxy::getTableAclAsync + * @covers MicrosoftAzure\Storage\Table\TableRestProxy::setTableAcl + * @covers MicrosoftAzure\Storage\Table\TableRestProxy::setTableAclAsync + */ + public function testGetSetTableAcl() + { + // Setup + $name = self::getTableNameWithPrefix('testGetSetTableAcl'); + $this->createTable($name); + $sample = TestResources::getTableACLMultipleEntriesSample(); + $acl = TableACL::create($sample['SignedIdentifiers']); + //because the time is randomized, this should create a different instance + $negativeSample = TestResources::getTableACLMultipleEntriesSample(); + $negative = TableACL::create($negativeSample['SignedIdentifiers']); + + // Test + $this->restProxy->setTableAcl($name, $acl); + $resultAcl = $this->restProxy->getTableAcl($name); + + $this->assertEquals( + $acl->getSignedIdentifiers(), + $resultAcl->getSignedIdentifiers() + ); + + $this->assertFalse( + $resultAcl->getSignedIdentifiers() == $negative->getSignedIdentifiers(), + 'Should not equal to the negative test case' + ); + } + + private static function getTableNameWithPrefix($prefix) + { + return $prefix . sprintf('%04x', mt_rand(0, 65535)); + } }