Skip to content

Commit

Permalink
Merge branch 'develop' into enhancement/blob-storage-usage
Browse files Browse the repository at this point in the history
  • Loading branch information
GabsCoding committed Jul 27, 2024
2 parents a7540ab + 2c19e8c commit 74dea6c
Show file tree
Hide file tree
Showing 10 changed files with 424 additions and 17 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
vendor/
.env
.DS_Store
.DS_Store
index.php
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

[![PHP CI](https://github.com/sjspereira/azure-storage-php-sdk/actions/workflows/CI.yaml/badge.svg)](https://github.com/sjspereira/azure-storage-php-sdk/actions/workflows/CI.yaml)
[![PHP CI](https://github.com/xray-labs/azure-storage-php-sdk/actions/workflows/CI.yaml/badge.svg)](https://github.com/xray-labs/azure-storage-php-sdk/actions/workflows/CI.yaml)

## Description

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "xray/azure-storage-php-sdk",
"description": "Integrate with Azure's cloud storage services",
"description": "Azure Storage PHP SDK",
"type": "library",
"license": "MIT",
"scripts": {
Expand Down
3 changes: 1 addition & 2 deletions src/BlobStorage/Entities/Blob/BlobLease.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ public function __construct(array $blobLease)
$this->version = $blobLease[Resource::AUTH_VERSION] ?? '';
$this->date = new DateTimeImmutable($blobLease['Date'] ?? 'now');

$this->leaseId = $blobLease[Resource::LEASE_ID]
?? null;
$this->leaseId = $blobLease[Resource::LEASE_ID] ?? null;
}

public function renew(): self
Expand Down
2 changes: 2 additions & 0 deletions src/BlobStorage/Managers/Blob/BlobLeaseManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ protected function request(array $headers): Response
return $this->request
->withHeaders($headers)
->put("{$this->container}/{$this->blob}?comp=lease&resttype=blob");
// @codeCoverageIgnoreStart
} catch (RequestExceptionInterface $e) {
throw RequestException::createFromRequestException($e);
}
// @codeCoverageIgnoreEnd
}
}
23 changes: 17 additions & 6 deletions src/BlobStorage/Managers/Blob/BlobManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Xray\AzureStoragePhpSdk\BlobStorage\Managers\Blob;

use DateTime;
use DateTimeImmutable;
use Psr\Http\Client\RequestExceptionInterface;
use Xray\AzureStoragePhpSdk\BlobStorage\Entities\Blob\{Blob, Blobs};
use Xray\AzureStoragePhpSdk\BlobStorage\Enums\{BlobIncludeOption, BlobType, ExpirationOption};
Expand Down Expand Up @@ -76,9 +75,11 @@ public function findByTag(array $options = []): BlobTagQuery
->withOptions($options)
->get("{$this->containerName}/?restype=container&comp=blobs&where={$query}")
->getBody();
// @codeCoverageIgnoreStart
} catch (RequestExceptionInterface $e) {
throw RequestException::createFromRequestException($e);
}
// @codeCoverageIgnoreEnd

/** @var array{Blobs?: array{Blob: BlobTypeStan|BlobTypeStan[]}} $parsed */
$parsed = $this->request->getConfig()->parser->parse($response);
Expand Down Expand Up @@ -155,21 +156,23 @@ public function setExpiry(string $blobName, ExpirationOption $expirationOption,
]))
->put("{$this->containerName}/{$blobName}?resttype=blob&comp=expiry")
->isOk();
// @codeCoverageIgnoreStart
} catch (RequestExceptionInterface $e) {
throw RequestException::createFromRequestException($e);
}
// @codeCoverageIgnoreEnd
}

/**
* @param boolean $force If true, Delete the base blob and all of its snapshots.
*/
public function delete(string $blobName, null|DateTimeImmutable|string $snapshot = null, bool $force = false): bool
public function delete(string $blobName, null|DateTime|string $snapshot = null, bool $force = false): bool
{
if ($snapshot instanceof DateTimeImmutable) {
if ($snapshot instanceof DateTime) {
$snapshot = convert_to_RFC3339_micro($snapshot);
}

$snapshotHeader = $snapshot ? sprintf('?snapshot=%s', urlencode($snapshot)) : '';
$snapshotHeader = $snapshot ? sprintf('&snapshot=%s', urlencode($snapshot)) : '';

$deleteSnapshotHeader = $snapshot ? sprintf('&%s=only', Resource::DELETE_SNAPSHOTS) : '';

Expand All @@ -181,9 +184,11 @@ public function delete(string $blobName, null|DateTimeImmutable|string $snapshot
return $this->request
->delete("{$this->containerName}/{$blobName}?resttype=blob{$snapshotHeader}{$deleteSnapshotHeader}")
->isAccepted();
// @codeCoverageIgnoreStart
} catch (RequestExceptionInterface $e) {
throw RequestException::createFromRequestException($e);
}
// @codeCoverageIgnoreEnd
}

public function restore(string $blobName): bool
Expand All @@ -192,9 +197,11 @@ public function restore(string $blobName): bool
return $this->request
->put("{$this->containerName}/{$blobName}?comp=undelete&resttype=blob")
->isOk();
// @codeCoverageIgnoreStart
} catch (RequestExceptionInterface $e) {
throw RequestException::createFromRequestException($e);
}
// @codeCoverageIgnoreEnd
}

public function createSnapshot(string $blobName): bool
Expand All @@ -203,15 +210,17 @@ public function createSnapshot(string $blobName): bool
return $this->request
->put("{$this->containerName}/{$blobName}?comp=snapshot&resttype=blob")
->isCreated();
// @codeCoverageIgnoreStart
} catch (RequestExceptionInterface $e) {
throw RequestException::createFromRequestException($e);
}
// @codeCoverageIgnoreEnd
}

/** @param array<string, scalar> $options */
public function copy(string $sourceCopy, string $blobName, array $options = [], null|DateTimeImmutable|string $snapshot = null): bool
public function copy(string $sourceCopy, string $blobName, array $options = [], null|DateTime|string $snapshot = null): bool
{
if ($snapshot instanceof DateTimeImmutable) {
if ($snapshot instanceof DateTime) {
$snapshot = convert_to_RFC3339_micro($snapshot);
}

Expand All @@ -227,9 +236,11 @@ public function copy(string $sourceCopy, string $blobName, array $options = [],
])
->put("{$this->containerName}/{$blobName}?resttype=blob")
->isAccepted();
// @codeCoverageIgnoreStart
} catch (RequestExceptionInterface $e) {
throw RequestException::createFromRequestException($e);
}
// @codeCoverageIgnoreEnd
}

public function lease(string $blobName): BlobLeaseManager
Expand Down
4 changes: 2 additions & 2 deletions src/BlobStorage/Queries/BlobTagQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Closure;
use Xray\AzureStoragePhpSdk\Contracts\Manager;
use Xray\AzureStoragePhpSdk\Exceptions\RequiredFieldException;
use Xray\AzureStoragePhpSdk\Exceptions\{InvalidArgumentException, RequiredFieldException};

/**
* @template TManager of Manager
Expand Down Expand Up @@ -74,7 +74,7 @@ public function build(): object
protected function validateOperator(string $operator): void
{
if (!in_array($operator, ['=', '>', '>=', '<', '<='])) {
throw new \InvalidArgumentException("Invalid operator: {$operator}");
throw InvalidArgumentException::create("Invalid operator: {$operator}");
}
}
}
135 changes: 135 additions & 0 deletions tests/Feature/BlobStorage/Managers/Blob/BlobLeaseManagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

use Xray\AzureStoragePhpSdk\BlobStorage\Entities\Blob\BlobLease;
use Xray\AzureStoragePhpSdk\BlobStorage\Managers\Blob\BlobLeaseManager;
use Xray\AzureStoragePhpSdk\Exceptions\RequiredFieldException;
use Xray\AzureStoragePhpSdk\Tests\Http\{RequestFake, ResponseFake};

uses()->group('blob-storage', 'managers', 'blob');

const REQUEST_URL = 'container/blob?comp=lease&resttype=blob';
const VERSION = '2020-06-12';

it('should acquire a lease', function () {
['request' => $request, 'manager' => $manager] = prepareForBlobLeaseManagerTest();

$response = $manager->acquire();

expect($response)
->lastModified->toBeInstanceOf(DateTimeImmutable::class)
->etag->toBe('KCSNSAKDMA')
->server->toBe('MS-AZURE')
->requestId->toBe('osjdnw-29389dksd-dwwdwd')
->version->toBe(VERSION)
->leaseId->toBe('lalsncjwej-29389dksd-dwwdwd')
->date->toBeInstanceOf(DateTimeImmutable::class);

$request->assertPut(REQUEST_URL);
});

it('should renew a lease', function () {
['request' => $request, 'blobLease' => $blobLease] = prepareForBlobLeaseManagerTest();

$response = $blobLease->renew();

expect($response)
->lastModified->toBeInstanceOf(DateTimeImmutable::class)
->etag->toBe('KCSNSAKDMA')
->server->toBe('MS-AZURE')
->requestId->toBe('osjdnw-29389dksd-dwwdwd')
->version->toBe(VERSION)
->leaseId->toBe('lalsncjwej-29389dksd-dwwdwd')
->date->toBeInstanceOf(DateTimeImmutable::class);

$request->assertPut(REQUEST_URL);
});

it('should change a lease', function () {
['request' => $request, 'blobLease' => $blobLease] = prepareForBlobLeaseManagerTest();

$response = $blobLease->change('lalsncjwej-29389dksd-dwwdwd');

expect($response)
->lastModified->toBeInstanceOf(DateTimeImmutable::class)
->etag->toBe('KCSNSAKDMA')
->server->toBe('MS-AZURE')
->requestId->toBe('osjdnw-29389dksd-dwwdwd')
->version->toBe(VERSION)
->leaseId->toBe('lalsncjwej-29389dksd-dwwdwd')
->date->toBeInstanceOf(DateTimeImmutable::class);

$request->assertPut(REQUEST_URL);
});

it('should release a lease', function () {
['request' => $request, 'blobLease' => $blobLease] = prepareForBlobLeaseManagerTest();

$response = $blobLease->release('lalsncjwej-29389dksd-dwwdwd');

expect($response)
->lastModified->toBeInstanceOf(DateTimeImmutable::class)
->etag->toBe('KCSNSAKDMA')
->server->toBe('MS-AZURE')
->requestId->toBe('osjdnw-29389dksd-dwwdwd')
->version->toBe(VERSION)
->leaseId->toBe('lalsncjwej-29389dksd-dwwdwd')
->date->toBeInstanceOf(DateTimeImmutable::class);

$request->assertPut(REQUEST_URL);
});

it('should break a lease', function () {
['request' => $request, 'blobLease' => $blobLease] = prepareForBlobLeaseManagerTest();

$response = $blobLease->break('lalsncjwej-29389dksd-dwwdwd');

expect($response)
->lastModified->toBeInstanceOf(DateTimeImmutable::class)
->etag->toBe('KCSNSAKDMA')
->server->toBe('MS-AZURE')
->requestId->toBe('osjdnw-29389dksd-dwwdwd')
->version->toBe(VERSION)
->leaseId->toBe('lalsncjwej-29389dksd-dwwdwd')
->date->toBeInstanceOf(DateTimeImmutable::class);

$request->assertPut(REQUEST_URL);
});

it('should throw an exception when trying to renew a lease without a lease id', function () {
['blobLease' => $blobLease] = prepareForBlobLeaseManagerTest(['x-ms-lease-id' => '']);

$blobLease->renew();
})->throws(RequiredFieldException::class, 'Field [leaseId] is required');

/**
* @param array<string, scalar> $blobLeaseHeaders
* @return array{request: RequestFake, blobLease: BlobLease, manager: BlobLeaseManager}
*/
function prepareForBlobLeaseManagerTest(array $blobLeaseHeaders = []): array
{
$blobLeaseHeaders = array_merge([
'Last-Modified' => 'Wed, 15 Sep 2021 15:02:29 GMT',
'ETag' => 'KCSNSAKDMA',
'Server' => 'MS-AZURE',
'Date' => 'Wed, 15 Sep 2021 15:02:29 GMT',
'x-ms-request-id' => 'osjdnw-29389dksd-dwwdwd',
'x-ms-version' => VERSION,
'x-ms-lease-id' => 'lalsncjwej-29389dksd-dwwdwd',
], $blobLeaseHeaders);

$request = (new RequestFake())
->withFakeResponse(new ResponseFake(headers: $blobLeaseHeaders));

// @phpstan-ignore-next-line
$blobLease = new BlobLease($blobLeaseHeaders);

$manager = (new BlobLeaseManager($request, 'container', 'blob'));

$blobLease->setManager($manager);

return [
'request' => $request,
'blobLease' => $blobLease,
'manager' => $manager,
];
}
Loading

0 comments on commit 74dea6c

Please sign in to comment.