Skip to content

Commit 35541f8

Browse files
Merge pull request #402 from CybotTM/feature/migrate-azure-oss-storage
Migrate Azure Blob adapter from abandoned SDK to azure-oss/storage
2 parents 9a03d8e + 5247956 commit 35541f8

9 files changed

Lines changed: 365 additions & 350 deletions

File tree

build.xml

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -504,18 +504,48 @@
504504
</fileset>
505505
</copy>
506506

507-
<!-- microsoft -->
508-
<copy file="${basedir}/vendor/microsoft/azure-storage-blob/LICENSE"
509-
tofile="${basedir}/build/phar/lib/microsoft/azure-storage-blob/LICENSE"/>
510-
<copy todir="${basedir}/build/phar/lib/microsoft/azure-storage-blob">
511-
<fileset dir="${basedir}/vendor/microsoft/azure-storage-blob/src">
507+
<!-- azure-oss (Azure Blob Storage SDK) -->
508+
<copy todir="${basedir}/build/phar/lib/azure-oss/storage">
509+
<fileset dir="${basedir}/vendor/azure-oss/storage">
512510
<include name="**/*.php"/>
513511
</fileset>
514512
</copy>
515-
<copy file="${basedir}/vendor/microsoft/azure-storage-common/LICENSE"
516-
tofile="${basedir}/build/phar/lib/microsoft/azure-storage-common/LICENSE"/>
517-
<copy todir="${basedir}/build/phar/lib/microsoft/azure-storage-common">
518-
<fileset dir="${basedir}/vendor/microsoft/azure-storage-common/src">
513+
<copy todir="${basedir}/build/phar/lib/azure-oss/storage-common">
514+
<fileset dir="${basedir}/vendor/azure-oss/storage-common">
515+
<include name="**/*.php"/>
516+
</fileset>
517+
</copy>
518+
<copy file="${basedir}/vendor/azure-oss/identity/LICENSE"
519+
tofile="${basedir}/build/phar/lib/azure-oss/identity/LICENSE"/>
520+
<copy todir="${basedir}/build/phar/lib/azure-oss/identity">
521+
<fileset dir="${basedir}/vendor/azure-oss/identity/src">
522+
<include name="**/*.php"/>
523+
</fileset>
524+
</copy>
525+
526+
<!-- caseyamcl/guzzle_retry_middleware (azure-oss dependency) -->
527+
<copy file="${basedir}/vendor/caseyamcl/guzzle_retry_middleware/LICENSE.md"
528+
tofile="${basedir}/build/phar/lib/caseyamcl/guzzle_retry_middleware/LICENSE.md"/>
529+
<copy todir="${basedir}/build/phar/lib/caseyamcl/guzzle_retry_middleware">
530+
<fileset dir="${basedir}/vendor/caseyamcl/guzzle_retry_middleware/src">
531+
<include name="**/*.php"/>
532+
</fileset>
533+
</copy>
534+
535+
<!-- symfony/deprecation-contracts (azure-oss dependency) -->
536+
<copy file="${basedir}/vendor/symfony/deprecation-contracts/LICENSE"
537+
tofile="${basedir}/build/phar/lib/symfony/deprecation-contracts/LICENSE"/>
538+
<copy todir="${basedir}/build/phar/lib/symfony/deprecation-contracts">
539+
<fileset dir="${basedir}/vendor/symfony/deprecation-contracts">
540+
<include name="**/*.php"/>
541+
</fileset>
542+
</copy>
543+
544+
<!-- symfony/polyfill-php80 (azure-oss dependency) -->
545+
<copy file="${basedir}/vendor/symfony/polyfill-php80/LICENSE"
546+
tofile="${basedir}/build/phar/lib/symfony/polyfill-php80/LICENSE"/>
547+
<copy todir="${basedir}/build/phar/lib/symfony/polyfill-php80">
548+
<fileset dir="${basedir}/vendor/symfony/polyfill-php80">
519549
<include name="**/*.php"/>
520550
</fileset>
521551
</copy>

build/phar-manifest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
"google/apiclient",
2929
"guzzlehttp/guzzle",
3030
"kunalvarma05/dropbox-php-sdk",
31-
"microsoft/azure-storage-blob",
31+
"azure-oss/storage",
32+
"azure-oss/storage-common",
33+
"azure-oss/identity",
3234
"php-opencloud/openstack",
3335
"phpmailer/phpmailer",
3436
"phpseclib/phpseclib",

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@
6363
"vlucas/phpdotenv": "^4.0",
6464
"google/apiclient":"^2.7",
6565
"php-opencloud/openstack": "^3.0",
66-
"microsoft/azure-storage-blob": "^1.4",
6766
"phpmailer/phpmailer": "^6.0",
68-
"google/cloud-storage": "^1.42"
67+
"google/cloud-storage": "^1.42",
68+
"azure-oss/storage": "^1.9"
6969
},
7070
"suggest": {
7171
"sebastianfeldmann/ftp": "Require ^0.9.2 to sync to an FTP server",
@@ -77,7 +77,7 @@
7777
"php-opencloud/openstack": "Require ^3.0 to sync to OpenStack",
7878
"vlucas/phpdotenv": "Require ^3.0 or ^4.0 or ^5.0 to use the Dotenv adapter",
7979
"google/apiclient":"Require ^2.0 to sync to Google Drive",
80-
"microsoft/azure-storage-blob": "Require ^1.4 to sync to Azure Blob Storage",
80+
"azure-oss/storage": "Require ^1.9 to sync to Azure Blob Storage",
8181
"phpmailer/phpmailer": "Require ^6.0 to receive logs via email",
8282
"google/cloud-storage": "Require ^1.42 to sync to Google Cloud Storage"
8383
},

src/Backup/Collector/AzureBlob.php

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<?php
22
namespace phpbu\App\Backup\Collector;
33

4-
use MicrosoftAzure\Storage\Blob\BlobRestProxy;
5-
use MicrosoftAzure\Storage\Blob\Models\ListBlobsOptions;
4+
use AzureOss\Storage\Blob\BlobContainerClient;
65
use phpbu\App\Backup\Collector;
76
use phpbu\App\Backup\File\AzureBlob as BlobFile;
87
use phpbu\App\Backup\Path;
@@ -24,52 +23,50 @@
2423
class AzureBlob extends Remote implements Collector
2524
{
2625
/**
27-
* @var \MicrosoftAzure\Storage\Blob\BlobRestProxy
26+
* @var \AzureOss\Storage\Blob\BlobContainerClient
2827
*/
2928
protected $client;
3029

3130
/**
32-
* Azure Blob Storage Container name
33-
*
34-
* @var string
35-
*/
36-
protected $containerName;
37-
38-
/**
39-
* Amazon S3 constructor.
31+
* AzureBlob constructor.
4032
*
4133
* @param \phpbu\App\Backup\Target $target
4234
* @param \phpbu\App\Backup\Path $path
43-
* @param \MicrosoftAzure\Storage\Blob\BlobRestProxy $client
44-
* @param string $containerName
35+
* @param \AzureOss\Storage\Blob\BlobContainerClient $client
4536
*/
46-
public function __construct(Target $target, Path $path, BlobRestProxy $client, string $containerName)
37+
public function __construct(Target $target, Path $path, BlobContainerClient $client)
4738
{
4839
$this->setUp($target, $path);
4940
$this->client = $client;
50-
$this->containerName = $containerName;
5141
}
5242

5343
/**
5444
* Collect all created backups.
5545
*/
5646
protected function collectBackups()
5747
{
58-
$listBlobsOptions = new ListBlobsOptions();
59-
$listBlobsOptions->setPrefix($this->getPrefix($this->path->getPathThatIsNotChanging()));
60-
$listBlobsOptions->setMaxResults(10);
48+
$prefix = $this->getPrefix($this->path->getPathThatIsNotChanging());
6149

62-
do {
63-
$blobList = $this->client->listBlobs($this->containerName, $listBlobsOptions);
64-
foreach ($blobList->getBlobs() as $blob) {
65-
if ($this->isFileMatch($blob->getName())) {
66-
$file = new BlobFile($this->client, $this->containerName, $blob);
67-
$index = $this->getFileIndex($file);
68-
$this->files[$index] = $file;
69-
}
50+
foreach ($this->listBlobs($prefix) as $blob) {
51+
if ($this->isFileMatch($blob->name)) {
52+
$file = new BlobFile($this->client, $blob);
53+
$index = $this->getFileIndex($file);
54+
$this->files[$index] = $file;
7055
}
71-
$listBlobsOptions->setContinuationToken($blobList->getContinuationToken());
72-
} while ($blobList->getContinuationToken());
56+
}
57+
}
58+
59+
/**
60+
* List all blobs in the container matching the given prefix.
61+
*
62+
* Pagination is handled transparently by the Azure Blob SDK.
63+
*
64+
* @param string $prefix
65+
* @return iterable<\AzureOss\Storage\Blob\Models\Blob>
66+
*/
67+
protected function listBlobs(string $prefix): iterable
68+
{
69+
return $this->client->getBlobs($prefix);
7370
}
7471

7572
/**

src/Backup/File/AzureBlob.php

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?php
22
namespace phpbu\App\Backup\File;
33

4-
use MicrosoftAzure\Storage\Blob\BlobRestProxy;
5-
use MicrosoftAzure\Storage\Blob\Models\Blob;
4+
use AzureOss\Storage\Blob\BlobContainerClient;
5+
use AzureOss\Storage\Blob\Models\Blob;
66
use phpbu\App\Exception;
77

88
/**
@@ -20,33 +20,25 @@
2020
class AzureBlob extends Remote
2121
{
2222
/**
23-
* Azure Blob client.
23+
* Azure Blob container client.
2424
*
25-
* @var BlobRestProxy
25+
* @var BlobContainerClient
2626
*/
27-
private $client;
28-
29-
/**
30-
* @var string
31-
*/
32-
protected $containerName;
27+
protected $client;
3328

3429
/**
3530
* AzureBlob constructor.
3631
*
37-
* @param BlobRestProxy $client
38-
* @param string $containerName
39-
* @param Blob $blob
32+
* @param BlobContainerClient $client
33+
* @param Blob $blob
4034
*/
41-
public function __construct(BlobRestProxy $client, string $containerName, Blob $blob)
35+
public function __construct(BlobContainerClient $client, Blob $blob)
4236
{
43-
$this->client = $client;
44-
$this->containerName = $containerName;
45-
$this->filename = basename($blob->getName());
46-
$this->pathname = $blob->getName();
47-
$props = $blob->getProperties();
48-
$this->size = $props->getContentLength();
49-
$this->lastModified = $props->getLastModified()->getTimestamp();
37+
$this->client = $client;
38+
$this->filename = basename($blob->name);
39+
$this->pathname = $blob->name;
40+
$this->size = $blob->properties->contentLength;
41+
$this->lastModified = $blob->properties->lastModified->getTimestamp();
5042
}
5143

5244
/**
@@ -57,9 +49,19 @@ public function __construct(BlobRestProxy $client, string $containerName, Blob $
5749
public function unlink()
5850
{
5951
try {
60-
$this->client->deleteBlob($this->containerName, $this->pathname);
52+
$this->deleteBlob($this->pathname);
6153
} catch (\Exception $exception) {
6254
throw new Exception($exception->getMessage());
6355
}
6456
}
57+
58+
/**
59+
* Delete the blob from the container.
60+
*
61+
* @param string $path
62+
*/
63+
protected function deleteBlob(string $path): void
64+
{
65+
$this->client->getBlobClient($path)->delete();
66+
}
6567
}

src/Backup/Sync/AzureBlob.php

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?php
22
namespace phpbu\App\Backup\Sync;
33

4-
use MicrosoftAzure\Storage\Blob\BlobRestProxy;
4+
use AzureOss\Storage\Blob\BlobContainerClient;
5+
use AzureOss\Storage\Blob\BlobServiceClient;
56
use phpbu\App\Backup\Collector;
67
use phpbu\App\Backup\Path;
78
use phpbu\App\Backup\Target;
@@ -25,12 +26,11 @@ class AzureBlob implements Simulator
2526
use Cleanable;
2627

2728
/**
28-
* Azure Blob client.
29+
* Azure Blob container client.
2930
*
30-
* @var BlobRestProxy;
31+
* @var BlobContainerClient
3132
*/
32-
private $client;
33-
33+
protected $client;
3434

3535
/**
3636
* Azure Blob Connection String
@@ -77,9 +77,9 @@ class AzureBlob implements Simulator
7777
*/
7878
public function setup(array $config)
7979
{
80-
if (!class_exists('\\MicrosoftAzure\\Storage\\Blob\\BlobRestProxy')) {
81-
throw new Exception('Azure Bob Storage SDK not loaded: use composer to install ' .
82-
'"microsoft/azure-storage-blob"');
80+
if (!class_exists('\\AzureOss\\Storage\\Blob\\BlobServiceClient')) {
81+
throw new Exception('Azure Blob Storage SDK not loaded: use composer to install ' .
82+
'"azure-oss/storage"');
8383
}
8484

8585
// check for mandatory options
@@ -122,7 +122,7 @@ public function sync(Target $target, Result $result)
122122
{
123123
$this->client = $this->createClient();
124124

125-
if (!$this->doesContainerExist($this->client, $this->containerName)) {
125+
if (!$this->doesContainerExist($this->client)) {
126126
$result->debug('create blob container');
127127
$this->createContainer($this->client);
128128
}
@@ -139,13 +139,14 @@ public function sync(Target $target, Result $result)
139139
}
140140

141141
/**
142-
* Create the Azure Blob client.
142+
* Create the Azure Blob container client.
143143
*
144-
* @return \MicrosoftAzure\Storage\Blob\BlobRestProxy
144+
* @return \AzureOss\Storage\Blob\BlobContainerClient
145145
*/
146-
protected function createClient() : BlobRestProxy
146+
protected function createClient() : BlobContainerClient
147147
{
148-
return BlobRestProxy::createBlobService($this->connectionString);
148+
return BlobServiceClient::fromConnectionString($this->connectionString)
149+
->getContainerClient($this->containerName);
149150
}
150151

151152
/**
@@ -157,7 +158,7 @@ protected function createClient() : BlobRestProxy
157158
protected function createCollector(Target $target) : Collector
158159
{
159160
$path = new Path($this->pathRaw, $this->time);
160-
return new Collector\AzureBlob($target, $path, $this->client, $this->containerName);
161+
return new Collector\AzureBlob($target, $path, $this->client);
161162
}
162163

163164
/**
@@ -180,47 +181,48 @@ public function simulate(Target $target, Result $result)
180181
/**
181182
* Check if an Azure Blob Storage Container exists
182183
*
183-
* @param \MicrosoftAzure\Storage\Blob\BlobRestProxy $blobRestProxy
184-
* @param string $containerName
184+
* @param \AzureOss\Storage\Blob\BlobContainerClient $client
185185
* @return bool
186186
*/
187-
private function doesContainerExist(BlobRestProxy $blobRestProxy, string $containerName): bool
187+
protected function doesContainerExist(BlobContainerClient $client): bool
188188
{
189-
$containers = $blobRestProxy->listContainers()->getContainers();
190-
foreach ($containers as $container) {
191-
if ($container->getName() === $containerName) {
192-
return true;
193-
}
194-
}
195-
return false;
189+
return $client->exists();
196190
}
197191

198192
/**
199193
* Create an Azure Storage Container
200194
*
201-
* @param \MicrosoftAzure\Storage\Blob\BlobRestProxy $blobRestProxy
195+
* @param \AzureOss\Storage\Blob\BlobContainerClient $client
202196
*/
203-
private function createContainer(BlobRestProxy $blobRestProxy)
197+
protected function createContainer(BlobContainerClient $client)
204198
{
205-
$blobRestProxy->createContainer($this->containerName);
199+
$client->create();
206200
}
207201

208202
/**
209203
* Upload backup to Azure Blob Storage
210204
*
211-
* @param \phpbu\App\Backup\Target $target
212-
* @param \MicrosoftAzure\Storage\Blob\BlobRestProxy $blobRestProxy
205+
* @param \phpbu\App\Backup\Target $target
206+
* @param \AzureOss\Storage\Blob\BlobContainerClient $client
213207
* @throws \phpbu\App\Backup\Sync\Exception
214208
* @throws \phpbu\App\Exception
215209
*/
216-
private function upload(Target $target, BlobRestProxy $blobRestProxy)
210+
protected function upload(Target $target, BlobContainerClient $client)
217211
{
218212
$source = $this->getFileHandle($target->getPathname(), 'r');
219-
$blobRestProxy->createBlockBlob(
220-
$this->containerName,
221-
$this->getUploadPath($target),
222-
$source
223-
);
213+
$this->uploadBlob($client, $this->getUploadPath($target), $source);
214+
}
215+
216+
/**
217+
* Upload a single blob to the container.
218+
*
219+
* @param \AzureOss\Storage\Blob\BlobContainerClient $client
220+
* @param string $path
221+
* @param resource $source
222+
*/
223+
protected function uploadBlob(BlobContainerClient $client, string $path, $source)
224+
{
225+
$client->getBlobClient($path)->upload($source);
224226
}
225227

226228
/**

0 commit comments

Comments
 (0)