Skip to content

Commit

Permalink
Remove jms in favour of simple xml (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
brecht-vermeersch authored Jul 24, 2024
1 parent af9904c commit eb1829f
Show file tree
Hide file tree
Showing 24 changed files with 217 additions and 225 deletions.
9 changes: 3 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
"php": "^8.1",
"ext-curl": "*",
"ext-json": "*",
"ext-simplexml": "*",
"caseyamcl/guzzle_retry_middleware": "^2.10",
"guzzlehttp/guzzle": "^7.8",
"jms/serializer": "^3.30"
"guzzlehttp/guzzle": "^7.8"
},
"require-dev": {
"laravel/pint": "^1.16",
Expand All @@ -41,9 +41,6 @@
"phpunit/phpunit": "^10.5"
},
"config": {
"sort-packages": true,
"allow-plugins": {
"phpstan/extension-installer": true
}
"sort-packages": true
}
}
11 changes: 7 additions & 4 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
parameters:
level: 9
paths:
- src
- tests
level: 9
paths:
- src
- tests
ignoreErrors:
-
message: '#Variable property access on SimpleXMLElement#'
includes:
- vendor/phpstan/phpstan-strict-rules/rules.neon
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
25 changes: 6 additions & 19 deletions src/Blob/BlobClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@
use AzureOss\Storage\Common\Auth\StorageSharedKeyCredential;
use AzureOss\Storage\Common\Middleware\ClientFactory;
use AzureOss\Storage\Common\Sas\SasProtocol;
use AzureOss\Storage\Common\Serializer\SerializerFactory;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Pool;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Psr7\Utils as StreamUtils;
use JMS\Serializer\SerializerInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;

Expand All @@ -39,8 +37,6 @@ final class BlobClient

private readonly BlobStorageExceptionFactory $exceptionFactory;

private readonly SerializerInterface $serializer;

public readonly string $containerName;

public readonly string $blobName;
Expand All @@ -55,8 +51,7 @@ public function __construct(
$this->containerName = BlobUriParserHelper::getContainerName($uri);
$this->blobName = BlobUriParserHelper::getBlobName($uri);
$this->client = (new ClientFactory())->create($uri, $sharedKeyCredentials);
$this->serializer = (new SerializerFactory())->create();
$this->exceptionFactory = new BlobStorageExceptionFactory($this->serializer);
$this->exceptionFactory = new BlobStorageExceptionFactory();
}

public function downloadStreaming(): BlobDownloadStreamingResult
Expand Down Expand Up @@ -196,11 +191,7 @@ private function uploadInBlocks(StreamInterface $content, UploadBlobOptions $opt
$pool = new Pool($this->client, $putBlockRequestGenerator(), [
'concurrency' => $options->maximumConcurrency,
'rejected' => function (\Exception $e) {
if ($e instanceof RequestException) {
throw $this->exceptionFactory->create($e);
}

throw $e;
throw $this->exceptionFactory->create($e);
},
]);

Expand Down Expand Up @@ -237,7 +228,7 @@ private function putBlockList(array $blocks, UploadBlobOptions $options): void
'headers' => [
'x-ms-blob-content-type' => $options->contentType,
],
'body' => $this->serializer->serialize(new PutBlockRequestBody($blocks), 'xml'),
'body' => (new PutBlockRequestBody($blocks))->toXml()->asXML(),
]);
} catch (RequestException $e) {
throw $this->exceptionFactory->create($e);
Expand Down Expand Up @@ -282,13 +273,11 @@ public function generateSasUri(BlobSasBuilder $blobSasBuilder): UriInterface
public function setTags(array $tags): void
{
try {
$body = BlobTagsBody::fromArray($tags);

$this->client->put($this->uri, [
'query' => [
'comp' => 'tags',
],
'body' => $this->serializer->serialize($body, 'xml'),
'body' => (new BlobTagsBody($tags))->toXml()->asXML(),
]);
} catch (RequestException $e) {
throw $this->exceptionFactory->create($e);
Expand All @@ -307,10 +296,8 @@ public function getTags(): array
],
]);

/** @var BlobTagsBody $body */
$body = $this->serializer->deserialize($response->getBody()->getContents(), BlobTagsBody::class, 'xml');

return $body->toArray();
$body = BlobTagsBody::fromXml(new \SimpleXMLElement($response->getBody()->getContents()));
return $body->tags;
} catch (RequestException $e) {
throw $this->exceptionFactory->create($e);
}
Expand Down
13 changes: 3 additions & 10 deletions src/Blob/BlobContainerClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@
use AzureOss\Storage\Common\Auth\StorageSharedKeyCredential;
use AzureOss\Storage\Common\Middleware\ClientFactory;
use AzureOss\Storage\Common\Sas\SasProtocol;
use AzureOss\Storage\Common\Serializer\SerializerFactory;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\Uri;
use JMS\Serializer\SerializerInterface;
use Psr\Http\Message\UriInterface;

final class BlobContainerClient
Expand All @@ -35,8 +33,6 @@ final class BlobContainerClient

private readonly BlobStorageExceptionFactory $exceptionFactory;

private readonly SerializerInterface $serializer;

public readonly string $containerName;

/**
Expand All @@ -48,8 +44,7 @@ public function __construct(
) {
$this->containerName = BlobUriParserHelper::getContainerName($uri);
$this->client = (new ClientFactory())->create($uri, $sharedKeyCredentials);
$this->serializer = (new SerializerFactory())->create();
$this->exceptionFactory = new BlobStorageExceptionFactory($this->serializer);
$this->exceptionFactory = new BlobStorageExceptionFactory();
}

public function getBlobClient(string $blobName): BlobClient
Expand Down Expand Up @@ -219,8 +214,7 @@ private function listBlobs(?string $prefix, ?string $delimiter, string $marker,
],
]);

/** @phpstan-ignore-next-line */
return $this->serializer->deserialize($response->getBody()->getContents(), ListBlobsResponseBody::class, 'xml');
return ListBlobsResponseBody::fromXml(new \SimpleXMLElement($response->getBody()->getContents()));
} catch (RequestException $e) {
throw $this->exceptionFactory->create($e);
}
Expand Down Expand Up @@ -266,8 +260,7 @@ public function findBlobsByTag(string $tagFilterSqlExpression): \Generator
],
]);

/** @var FindBlobsByTagBody $body */
$body = $this->serializer->deserialize($response->getBody()->getContents(), FindBlobsByTagBody::class, 'xml');
$body = FindBlobsByTagBody::fromXml(new \SimpleXMLElement($response->getBody()->getContents()));
$nextMarker = $body->nextMarker;

foreach ($body->blobs as $blob) {
Expand Down
13 changes: 3 additions & 10 deletions src/Blob/BlobServiceClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@
use AzureOss\Storage\Common\Sas\AccountSasBuilder;
use AzureOss\Storage\Common\Sas\AccountSasServices;
use AzureOss\Storage\Common\Sas\SasProtocol;
use AzureOss\Storage\Common\Serializer\SerializerFactory;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\Uri;
use JMS\Serializer\SerializerInterface;
use Psr\Http\Message\UriInterface;

final class BlobServiceClient
Expand All @@ -31,17 +29,14 @@ final class BlobServiceClient

private readonly BlobStorageExceptionFactory $exceptionFactory;

private readonly SerializerInterface $serializer;

public function __construct(
public UriInterface $uri,
public readonly ?StorageSharedKeyCredential $sharedKeyCredentials = null,
) {
// must always include the forward slash (/) to separate the host name from the path and query portions of the URI.
$this->uri = $uri->withPath(rtrim($uri->getPath(), '/') . "/");
$this->client = (new ClientFactory())->create($this->uri, $sharedKeyCredentials);
$this->serializer = (new SerializerFactory())->create();
$this->exceptionFactory = new BlobStorageExceptionFactory($this->serializer);
$this->exceptionFactory = new BlobStorageExceptionFactory();
}

public static function fromConnectionString(string $connectionString): self
Expand Down Expand Up @@ -89,8 +84,7 @@ public function getBlobContainers(?string $prefix = null): \Generator
'prefix' => $prefix,
],
]);
/** @var ListContainersResponseBody $body */
$body = $this->serializer->deserialize($response->getBody()->getContents(), ListContainersResponseBody::class, 'xml');
$body = ListContainersResponseBody::fromXml(new \SimpleXMLElement($response->getBody()->getContents()));
$nextMarker = $body->nextMarker;

foreach ($body->containers as $container) {
Expand Down Expand Up @@ -124,8 +118,7 @@ public function findBlobsByTag(string $tagFilterSqlExpression): \Generator
],
]);

/** @var FindBlobsByTagBody $body */
$body = $this->serializer->deserialize($response->getBody()->getContents(), FindBlobsByTagBody::class, 'xml');
$body = FindBlobsByTagBody::fromXml(new \SimpleXMLElement($response->getBody()->getContents()));
$nextMarker = $body->nextMarker;

foreach ($body->blobs as $blob) {
Expand Down
46 changes: 23 additions & 23 deletions src/Blob/Exceptions/BlobStorageExceptionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,26 @@

use AzureOss\Storage\Blob\Responses\ErrorResponse;
use GuzzleHttp\Exception\RequestException;
use JMS\Serializer\SerializerInterface;
use Psr\Http\Message\ResponseInterface;

/**
* @internal
*/
final class BlobStorageExceptionFactory
{
public function __construct(
private readonly SerializerInterface $serializer,
) {}
public function create(\Throwable $e): \Throwable
{
return $e instanceof RequestException ? $this->createFromRequestException($e) : $e;
}

public function create(RequestException $e): \Exception
private function createFromRequestException(RequestException $e): \Exception
{
$error = $this->getErrorResponse($e);
$response = $e->getResponse();
if($response === null) {
return $e;
}

$error = $this->getErrorFromResponseBody($response) ?? $this->getErrorResponseFromHeaders($response);
if ($error === null) {
return $e;
}
Expand All @@ -37,28 +42,23 @@ public function create(RequestException $e): \Exception
};
}

public function getErrorResponse(RequestException $e): ?ErrorResponse
public function getErrorResponseFromHeaders(ResponseInterface $response): ?ErrorResponse
{
$response = $e->getResponse();
if ($response === null) {
throw $e;
$code = $response->getHeaderLine("x-ms-error-code");
if ($code === "") {
return null;
}

$content = $response->getBody()->getContents();
if ($content !== "") {
try {
/** @phpstan-ignore-next-line */
return $this->serializer->deserialize($content, ErrorResponse::class, 'xml');
} catch (\Exception) {
return null;
}
}
return new ErrorResponse($code, $response->getHeaderLine("x-ms-request-id"));
}

$code = $response->getHeaderLine("x-ms-error-code");
if ($code !== "") {
return new ErrorResponse($code, $response->getHeaderLine("x-ms-request-id"));
private function getErrorFromResponseBody(ResponseInterface $response): ?ErrorResponse
{
$content = $response->getBody()->getContents();
if ($content === "") {
return null;
}

return null;
return ErrorResponse::fromXml(new \SimpleXMLElement($content));
}
}
8 changes: 8 additions & 0 deletions src/Blob/Models/Blob.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,12 @@ public function __construct(
public readonly string $name,
public readonly BlobProperties $properties,
) {}

public static function fromXml(\SimpleXMLElement $xml): self
{
return new self(
(string) $xml->Name,
BlobProperties::fromXml($xml->Properties),
);
}
}
8 changes: 8 additions & 0 deletions src/Blob/Models/BlobContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,12 @@ public function __construct(
public readonly string $name,
public readonly BlobContainerProperties $properties,
) {}

public static function fromXml(\SimpleXMLElement $xml): self
{
return new self(
(string) $xml->Name,
BlobContainerProperties::fromXml($xml->Properties),
);
}
}
17 changes: 13 additions & 4 deletions src/Blob/Models/BlobContainerProperties.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

use AzureOss\Storage\Blob\Exceptions\DateMalformedStringException;
use AzureOss\Storage\Blob\Helpers\MetadataHelper;
use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\Type;
use Psr\Http\Message\ResponseInterface;

final class BlobContainerProperties
Expand All @@ -16,8 +14,6 @@ final class BlobContainerProperties
* @param array<string, string> $metadata
*/
public function __construct(
#[SerializedName('Last-Modified')]
#[Type("DateTimeImmutable<'" . \DateTimeInterface::RFC1123 . "'>")]
public readonly \DateTimeInterface $lastModified,
public readonly array $metadata,
) {}
Expand All @@ -31,4 +27,17 @@ public static function fromResponseHeaders(ResponseInterface $response): self

return new self($lastModified, MetadataHelper::headersToMetadata($response->getHeaders()));
}

public static function fromXml(\SimpleXMLElement $xml): self
{
$lastModified = \DateTimeImmutable::createFromFormat(\DateTimeInterface::RFC1123, (string) $xml->{'Last-Modified'});
if ($lastModified === false) {
throw new DateMalformedStringException("Azure returned a malformed date.");
}

return new self(
$lastModified,
[],
);
}
}
7 changes: 7 additions & 0 deletions src/Blob/Models/BlobPrefix.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,11 @@ final class BlobPrefix
public function __construct(
public readonly string $name,
) {}

public static function fromXml(\SimpleXMLElement $xml): self
{
return new self(
(string) $xml->Name,
);
}
}
Loading

0 comments on commit eb1829f

Please sign in to comment.