Skip to content

Commit 06e3ffb

Browse files
committed
do not create container for AzureBlobStorage
Related to #618. Container creation is out of Gaufrette scope. The container should be created by the deleveloper on its own. Thus, the multi container mode has been removed, as it was creating containers on the fly.
1 parent a93e739 commit 06e3ffb

File tree

6 files changed

+37
-473
lines changed

6 files changed

+37
-473
lines changed

Diff for: CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,18 @@ which is the latest supported version of the SDK for OpenStack instead of
1010
https://github.com/rackspace/php-opencloud (#533).
1111
- Google Cloud Storage Adapter (#557)
1212

13-
## Removed
13+
## Removed (introduces BC breaks)
1414

1515
- The [OpenCloud adapter](https://github.com/KnpLabs/Gaufrette/blob/v0.5.0/src/Gaufrette/Adapter/OpenCloud.php)
1616
has been removed.
1717
- The [ObjectStoreFactory](https://github.com/KnpLabs/Gaufrette/blob/v0.5.0/src/Gaufrette/Adapter/OpenStackCloudFiles/ObjectStoreFactory.php)
1818
has been removed.
1919

20+
## Changes (introduces BC breaks)
21+
22+
- Gaufrette is no longer responsible for bucket / container creation. This
23+
should be done prior to any adapter usage (#618).
24+
2025
Thank you @nicolasmure and @PanzerLlama for your contributions !
2126

2227
v0.8.3

Diff for: UPGRADE.md

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
1.0
22
===
33

4+
**Gaufrette\Adapter\AzureblobStorage:**
5+
As container management is out of Gaufrette scope (see #618), this adapter has
6+
the following BC breaks :
7+
* The `createContainer` public method has been removed.
8+
* The `deleteContainer` public method has been removed.
9+
* The `getCreateContainerOptions` public method has been removed.
10+
* The `setCreateContainerOptions` public method has been removed.
11+
* Drop support for [multi continer mode](https://github.com/KnpLabs/Gaufrette/blob/b488cf8f595c3c7a35005f72b60692e14c69398c/doc/adapters/azure-blob-storage.md#multi-container-mode).
12+
* The constructor's `create` parameter has been removed.
13+
* The constructor's `containerName` parameter is now mandatory (string).
14+
415
**Gaufrette\Adapter\OpenStackCloudFiles\ObjectStoreFactory:**
516
* This factory has been removed
617

Diff for: spec/Gaufrette/Adapter/AzureBlobStorageSpec.php

+7-25
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ function it_should_be_initializable()
3131
$this->shouldHaveType('Gaufrette\Adapter\MetadataSupporter');
3232
}
3333

34+
function it_should_require_a_container_name(BlobProxyFactoryInterface $blobFactory)
35+
{
36+
$this->beConstructedWith($blobFactory);
37+
38+
$this->shouldThrow(\ArgumentCountError::class)->duringInstantiation();
39+
}
40+
3441
function it_reads_file(BlobProxyFactoryInterface $blobFactory, IBlob $blob, GetBlobResult $blobContent)
3542
{
3643
$blobFactory->create()->willReturn($blob);
@@ -302,29 +309,4 @@ function it_throws_storage_failure_when_it_fails_to_get_keys(
302309

303310
$this->shouldThrow(StorageFailure::class)->duringKeys();
304311
}
305-
306-
function it_creates_container(BlobProxyFactoryInterface $blobFactory, IBlob $blob)
307-
{
308-
$blobFactory->create()->willReturn($blob);
309-
310-
$blob->createContainer('containerName', null)->shouldBeCalled();
311-
312-
$this->createContainer('containerName');
313-
}
314-
315-
function it_throws_storage_failure_when_it_fails_to_create_container(
316-
BlobProxyFactoryInterface $blobFactory,
317-
IBlob $blob,
318-
ServiceException $azureException,
319-
ResponseInterface $response
320-
) {
321-
$blobFactory->create()->willReturn($blob);
322-
323-
$blob->createContainer('containerName', null)->willThrow($azureException->getWrappedObject());
324-
$azureException->getResponse()->willReturn($response);
325-
$response->getBody()->willReturn('<Code>SomeErrorCode</Code>');
326-
$azureException->getErrorText()->willReturn(Argument::type('string'));
327-
328-
$this->shouldThrow(StorageFailure::class)->duringCreateContainer('containerName');
329-
}
330312
}

Diff for: src/Gaufrette/Adapter/AzureBlobStorage.php

+3-179
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface;
1010
use MicrosoftAzure\Storage\Blob\Models\Blob;
1111
use MicrosoftAzure\Storage\Blob\Models\CreateBlockBlobOptions;
12-
use MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions;
1312
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
1413

1514
/**
@@ -46,104 +45,18 @@ class AzureBlobStorage implements Adapter, MetadataSupporter, SizeCalculator, Ch
4645
*/
4746
protected $blobProxy;
4847

49-
/**
50-
* @var bool
51-
*/
52-
protected $multiContainerMode = false;
53-
54-
/**
55-
* @var CreateContainerOptions
56-
*/
57-
protected $createContainerOptions;
58-
5948
/**
6049
* @param AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
61-
* @param string|null $containerName
62-
* @param bool $create
50+
* @param string $containerName
6351
* @param bool $detectContentType
6452
*
6553
* @throws \RuntimeException
6654
*/
67-
public function __construct(BlobProxyFactoryInterface $blobProxyFactory, $containerName = null, $create = false, $detectContentType = true)
55+
public function __construct(BlobProxyFactoryInterface $blobProxyFactory, string $containerName, bool $detectContentType = true)
6856
{
6957
$this->blobProxyFactory = $blobProxyFactory;
7058
$this->containerName = $containerName;
7159
$this->detectContentType = $detectContentType;
72-
73-
if (null === $containerName) {
74-
$this->multiContainerMode = true;
75-
} elseif ($create) {
76-
$this->createContainer($containerName);
77-
}
78-
}
79-
80-
/**
81-
* @return CreateContainerOptions
82-
*/
83-
public function getCreateContainerOptions()
84-
{
85-
return $this->createContainerOptions;
86-
}
87-
88-
/**
89-
* @param CreateContainerOptions $options
90-
*/
91-
public function setCreateContainerOptions(CreateContainerOptions $options)
92-
{
93-
$this->createContainerOptions = $options;
94-
}
95-
96-
/**
97-
* Creates a new container.
98-
*
99-
* @param string $containerName
100-
* @param \MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions $options
101-
*
102-
* @throws StorageFailure if cannot create the container
103-
*/
104-
public function createContainer($containerName, CreateContainerOptions $options = null)
105-
{
106-
$this->init();
107-
108-
if (null === $options) {
109-
$options = $this->getCreateContainerOptions();
110-
}
111-
112-
try {
113-
$this->blobProxy->createContainer($containerName, $options);
114-
} catch (ServiceException $e) {
115-
$errorCode = $this->getErrorCodeFromServiceException($e);
116-
117-
// We don't care if the container was created between check and creation attempt
118-
// it might be due to a parallel execution creating it.
119-
if ($errorCode !== self::ERROR_CONTAINER_ALREADY_EXISTS) {
120-
throw StorageFailure::unexpectedFailure('createContainer', [
121-
'containerName' => $containerName,
122-
'options' => $options,
123-
], $e);
124-
}
125-
}
126-
}
127-
128-
/**
129-
* Deletes a container.
130-
*
131-
* @param string $containerName
132-
* @param DeleteContainerOptions $options
133-
*
134-
* @throws StorageFailure if cannot delete the container
135-
*/
136-
public function deleteContainer($containerName, DeleteContainerOptions $options = null)
137-
{
138-
$this->init();
139-
140-
try {
141-
$this->blobProxy->deleteContainer($containerName, $options);
142-
} catch (ServiceException $e) {
143-
throw StorageFailure::unexpectedFailure('deleteContainer', [
144-
'containerName' => $containerName,
145-
], $e);
146-
}
14760
}
14861

14962
/**
@@ -187,10 +100,6 @@ public function write($key, $content)
187100
}
188101

189102
try {
190-
if ($this->multiContainerMode) {
191-
$this->createContainer($containerName);
192-
}
193-
194103
$this->blobProxy->createBlockBlob($containerName, $key, $content, $options);
195104
} catch (ServiceException $e) {
196105
throw StorageFailure::unexpectedFailure('write', [
@@ -231,76 +140,10 @@ public function keys()
231140
{
232141
$this->init();
233142

234-
if ($this->multiContainerMode) {
235-
return $this->keysForMultiContainerMode();
236-
}
237-
238-
return $this->keysForSingleContainerMode();
239-
}
240-
241-
/**
242-
* List objects stored when the adapter is used in multi container mode.
243-
*
244-
* @return array
245-
*
246-
* @throws \RuntimeException
247-
*/
248-
private function keysForMultiContainerMode()
249-
{
250-
try {
251-
$containersList = $this->blobProxy->listContainers()->getContainers();
252-
$lists = [];
253-
254-
foreach ($containersList as $container) {
255-
$lists[] = $this->fetchContainerKeysAndIgnore404($container->getName());
256-
}
257-
258-
return !empty($lists) ? array_merge(...$lists) : [];
259-
} catch (ServiceException $e) {
260-
throw StorageFailure::unexpectedFailure('keys', [
261-
'multiContainerMode' => $this->multiContainerMode,
262-
'containerName' => $this->containerName,
263-
], $e);
264-
}
265-
}
266-
267-
/**
268-
* List the keys in a container and ignore any 404 error.
269-
*
270-
* This prevent race conditions happening when a container is deleted after calling listContainers() and
271-
* before the container keys are fetched.
272-
*
273-
* @param string $containerName
274-
*
275-
* @return array
276-
*/
277-
private function fetchContainerKeysAndIgnore404($containerName)
278-
{
279-
try {
280-
return $this->fetchBlobs($containerName, $containerName);
281-
} catch (ServiceException $e) {
282-
if ($e->getResponse()->getStatusCode() === 404) {
283-
return [];
284-
}
285-
286-
throw $e;
287-
}
288-
}
289-
290-
/**
291-
* List objects stored when the adapter is not used in multi container mode.
292-
*
293-
* @return array
294-
*
295-
* @throws \RuntimeException
296-
*/
297-
private function keysForSingleContainerMode()
298-
{
299143
try {
300144
return $this->fetchBlobs($this->containerName);
301145
} catch (ServiceException $e) {
302146
throw StorageFailure::unexpectedFailure('keys', [
303-
'multiContainerMode' => $this->multiContainerMode,
304147
'containerName' => $this->containerName,
305148
], $e);
306149
}
@@ -413,10 +256,6 @@ public function rename($sourceKey, $targetKey)
413256
list($targetContainerName, $targetKey) = $this->tokenizeKey($targetKey);
414257

415258
try {
416-
if ($this->multiContainerMode) {
417-
$this->createContainer($targetContainerName);
418-
}
419-
420259
$this->blobProxy->copyBlob($targetContainerName, $targetKey, $sourceContainerName, $sourceKey);
421260
$this->blobProxy->deleteBlob($sourceContainerName, $sourceKey);
422261
} catch (ServiceException $e) {
@@ -535,22 +374,7 @@ private function guessContentType($content)
535374
*/
536375
private function tokenizeKey($key)
537376
{
538-
$containerName = $this->containerName;
539-
if (false === $this->multiContainerMode) {
540-
return [$containerName, $key];
541-
}
542-
543-
if (false === ($index = strpos($key, '/'))) {
544-
throw new InvalidKey(sprintf(
545-
'Failed to establish container name from key "%s", container name is required in multi-container mode',
546-
$key
547-
));
548-
}
549-
550-
$containerName = substr($key, 0, $index);
551-
$key = substr($key, $index + 1);
552-
553-
return [$containerName, $key];
377+
return [$this->containerName, $key];
554378
}
555379

556380
/**

Diff for: tests/Gaufrette/Functional/Adapter/AzureBlobStorageTest.php

+10-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ class AzureBlobStorageTest extends FunctionalTestCase
1818
/** @var AzureBlobStorage */
1919
private $adapter;
2020

21+
/** @var \MicrosoftAzure\Storage\Blob\Internal\IBlob */
22+
private $blobProxy;
23+
2124
public function setUp()
2225
{
2326
$account = getenv('AZURE_ACCOUNT');
@@ -30,8 +33,13 @@ public function setUp()
3033

3134
$connection = sprintf('BlobEndpoint=http://%1$s.blob.core.windows.net/;AccountName=%1$s;AccountKey=%2$s', $account, $key);
3235

36+
$blobProxyFactory = new BlobProxyFactory($connection);
37+
$this->blobProxy = $blobProxyFactory->create();
38+
3339
$this->container = uniqid($containerName);
34-
$this->adapter = new AzureBlobStorage(new BlobProxyFactory($connection), $this->container, true);
40+
$this->blobProxy->createContainer($this->container);
41+
42+
$this->adapter = new AzureBlobStorage($blobProxyFactory, $this->container);
3543
$this->filesystem = new Filesystem($this->adapter);
3644
}
3745

@@ -41,6 +49,6 @@ public function tearDown()
4149
return;
4250
}
4351

44-
$this->adapter->deleteContainer($this->container);
52+
$this->blobProxy->deleteContainer($this->container);
4553
}
4654
}

0 commit comments

Comments
 (0)