Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 39 additions & 9 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -504,18 +504,48 @@
</fileset>
</copy>

<!-- microsoft -->
<copy file="${basedir}/vendor/microsoft/azure-storage-blob/LICENSE"
tofile="${basedir}/build/phar/lib/microsoft/azure-storage-blob/LICENSE"/>
<copy todir="${basedir}/build/phar/lib/microsoft/azure-storage-blob">
<fileset dir="${basedir}/vendor/microsoft/azure-storage-blob/src">
<!-- azure-oss (Azure Blob Storage SDK) -->
<copy todir="${basedir}/build/phar/lib/azure-oss/storage">
<fileset dir="${basedir}/vendor/azure-oss/storage">
<include name="**/*.php"/>
</fileset>
</copy>
<copy file="${basedir}/vendor/microsoft/azure-storage-common/LICENSE"
tofile="${basedir}/build/phar/lib/microsoft/azure-storage-common/LICENSE"/>
<copy todir="${basedir}/build/phar/lib/microsoft/azure-storage-common">
<fileset dir="${basedir}/vendor/microsoft/azure-storage-common/src">
<copy todir="${basedir}/build/phar/lib/azure-oss/storage-common">
<fileset dir="${basedir}/vendor/azure-oss/storage-common">
<include name="**/*.php"/>
</fileset>
</copy>
<copy file="${basedir}/vendor/azure-oss/identity/LICENSE"
tofile="${basedir}/build/phar/lib/azure-oss/identity/LICENSE"/>
<copy todir="${basedir}/build/phar/lib/azure-oss/identity">
<fileset dir="${basedir}/vendor/azure-oss/identity/src">
<include name="**/*.php"/>
</fileset>
</copy>

<!-- caseyamcl/guzzle_retry_middleware (azure-oss dependency) -->
<copy file="${basedir}/vendor/caseyamcl/guzzle_retry_middleware/LICENSE.md"
tofile="${basedir}/build/phar/lib/caseyamcl/guzzle_retry_middleware/LICENSE.md"/>
<copy todir="${basedir}/build/phar/lib/caseyamcl/guzzle_retry_middleware">
<fileset dir="${basedir}/vendor/caseyamcl/guzzle_retry_middleware/src">
<include name="**/*.php"/>
</fileset>
</copy>

<!-- symfony/deprecation-contracts (azure-oss dependency) -->
<copy file="${basedir}/vendor/symfony/deprecation-contracts/LICENSE"
tofile="${basedir}/build/phar/lib/symfony/deprecation-contracts/LICENSE"/>
<copy todir="${basedir}/build/phar/lib/symfony/deprecation-contracts">
<fileset dir="${basedir}/vendor/symfony/deprecation-contracts">
<include name="**/*.php"/>
</fileset>
</copy>

<!-- symfony/polyfill-php80 (azure-oss dependency) -->
<copy file="${basedir}/vendor/symfony/polyfill-php80/LICENSE"
tofile="${basedir}/build/phar/lib/symfony/polyfill-php80/LICENSE"/>
<copy todir="${basedir}/build/phar/lib/symfony/polyfill-php80">
<fileset dir="${basedir}/vendor/symfony/polyfill-php80">
<include name="**/*.php"/>
</fileset>
</copy>
Expand Down
4 changes: 3 additions & 1 deletion build/phar-manifest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
"google/apiclient",
"guzzlehttp/guzzle",
"kunalvarma05/dropbox-php-sdk",
"microsoft/azure-storage-blob",
"azure-oss/storage",
"azure-oss/storage-common",
"azure-oss/identity",
"php-opencloud/openstack",
"phpmailer/phpmailer",
"phpseclib/phpseclib",
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@
"vlucas/phpdotenv": "^4.0",
"google/apiclient":"^2.7",
"php-opencloud/openstack": "^3.0",
"microsoft/azure-storage-blob": "^1.4",
"phpmailer/phpmailer": "^6.0",
"google/cloud-storage": "^1.42"
"google/cloud-storage": "^1.42",
"azure-oss/storage": "^1.9"
},
"suggest": {
"sebastianfeldmann/ftp": "Require ^0.9.2 to sync to an FTP server",
Expand All @@ -77,7 +77,7 @@
"php-opencloud/openstack": "Require ^3.0 to sync to OpenStack",
"vlucas/phpdotenv": "Require ^3.0 or ^4.0 or ^5.0 to use the Dotenv adapter",
"google/apiclient":"Require ^2.0 to sync to Google Drive",
"microsoft/azure-storage-blob": "Require ^1.4 to sync to Azure Blob Storage",
"azure-oss/storage": "Require ^1.9 to sync to Azure Blob Storage",
"phpmailer/phpmailer": "Require ^6.0 to receive logs via email",
"google/cloud-storage": "Require ^1.42 to sync to Google Cloud Storage"
},
Expand Down
53 changes: 25 additions & 28 deletions src/Backup/Collector/AzureBlob.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<?php
namespace phpbu\App\Backup\Collector;

use MicrosoftAzure\Storage\Blob\BlobRestProxy;
use MicrosoftAzure\Storage\Blob\Models\ListBlobsOptions;
use AzureOss\Storage\Blob\BlobContainerClient;
use phpbu\App\Backup\Collector;
use phpbu\App\Backup\File\AzureBlob as BlobFile;
use phpbu\App\Backup\Path;
Expand All @@ -24,52 +23,50 @@
class AzureBlob extends Remote implements Collector
{
/**
* @var \MicrosoftAzure\Storage\Blob\BlobRestProxy
* @var \AzureOss\Storage\Blob\BlobContainerClient
*/
protected $client;

/**
* Azure Blob Storage Container name
*
* @var string
*/
protected $containerName;

/**
* Amazon S3 constructor.
* AzureBlob constructor.
*
* @param \phpbu\App\Backup\Target $target
* @param \phpbu\App\Backup\Path $path
* @param \MicrosoftAzure\Storage\Blob\BlobRestProxy $client
* @param string $containerName
* @param \AzureOss\Storage\Blob\BlobContainerClient $client
*/
public function __construct(Target $target, Path $path, BlobRestProxy $client, string $containerName)
public function __construct(Target $target, Path $path, BlobContainerClient $client)
{
$this->setUp($target, $path);
$this->client = $client;
$this->containerName = $containerName;
}

/**
* Collect all created backups.
*/
protected function collectBackups()
{
$listBlobsOptions = new ListBlobsOptions();
$listBlobsOptions->setPrefix($this->getPrefix($this->path->getPathThatIsNotChanging()));
$listBlobsOptions->setMaxResults(10);
$prefix = $this->getPrefix($this->path->getPathThatIsNotChanging());

do {
$blobList = $this->client->listBlobs($this->containerName, $listBlobsOptions);
foreach ($blobList->getBlobs() as $blob) {
if ($this->isFileMatch($blob->getName())) {
$file = new BlobFile($this->client, $this->containerName, $blob);
$index = $this->getFileIndex($file);
$this->files[$index] = $file;
}
foreach ($this->listBlobs($prefix) as $blob) {
if ($this->isFileMatch($blob->name)) {
$file = new BlobFile($this->client, $blob);
$index = $this->getFileIndex($file);
$this->files[$index] = $file;
}
$listBlobsOptions->setContinuationToken($blobList->getContinuationToken());
} while ($blobList->getContinuationToken());
}
}

/**
* List all blobs in the container matching the given prefix.
*
* Pagination is handled transparently by the Azure Blob SDK.
*
* @param string $prefix
* @return iterable<\AzureOss\Storage\Blob\Models\Blob>
*/
protected function listBlobs(string $prefix): iterable
{
return $this->client->getBlobs($prefix);
}

/**
Expand Down
46 changes: 24 additions & 22 deletions src/Backup/File/AzureBlob.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php
namespace phpbu\App\Backup\File;

use MicrosoftAzure\Storage\Blob\BlobRestProxy;
use MicrosoftAzure\Storage\Blob\Models\Blob;
use AzureOss\Storage\Blob\BlobContainerClient;
use AzureOss\Storage\Blob\Models\Blob;
use phpbu\App\Exception;

/**
Expand All @@ -20,33 +20,25 @@
class AzureBlob extends Remote
{
/**
* Azure Blob client.
* Azure Blob container client.
*
* @var BlobRestProxy
* @var BlobContainerClient
*/
private $client;

/**
* @var string
*/
protected $containerName;
protected $client;

/**
* AzureBlob constructor.
*
* @param BlobRestProxy $client
* @param string $containerName
* @param Blob $blob
* @param BlobContainerClient $client
* @param Blob $blob
*/
public function __construct(BlobRestProxy $client, string $containerName, Blob $blob)
public function __construct(BlobContainerClient $client, Blob $blob)
{
$this->client = $client;
$this->containerName = $containerName;
$this->filename = basename($blob->getName());
$this->pathname = $blob->getName();
$props = $blob->getProperties();
$this->size = $props->getContentLength();
$this->lastModified = $props->getLastModified()->getTimestamp();
$this->client = $client;
$this->filename = basename($blob->name);
$this->pathname = $blob->name;
$this->size = $blob->properties->contentLength;
$this->lastModified = $blob->properties->lastModified->getTimestamp();
}

/**
Expand All @@ -57,9 +49,19 @@ public function __construct(BlobRestProxy $client, string $containerName, Blob $
public function unlink()
{
try {
$this->client->deleteBlob($this->containerName, $this->pathname);
$this->deleteBlob($this->pathname);
} catch (\Exception $exception) {
throw new Exception($exception->getMessage());
}
}

/**
* Delete the blob from the container.
*
* @param string $path
*/
protected function deleteBlob(string $path): void
{
$this->client->getBlobClient($path)->delete();
}
}
72 changes: 37 additions & 35 deletions src/Backup/Sync/AzureBlob.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?php
namespace phpbu\App\Backup\Sync;

use MicrosoftAzure\Storage\Blob\BlobRestProxy;
use AzureOss\Storage\Blob\BlobContainerClient;
use AzureOss\Storage\Blob\BlobServiceClient;
use phpbu\App\Backup\Collector;
use phpbu\App\Backup\Path;
use phpbu\App\Backup\Target;
Expand All @@ -25,12 +26,11 @@ class AzureBlob implements Simulator
use Cleanable;

/**
* Azure Blob client.
* Azure Blob container client.
*
* @var BlobRestProxy;
* @var BlobContainerClient
*/
private $client;

protected $client;

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

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

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

/**
* Create the Azure Blob client.
* Create the Azure Blob container client.
*
* @return \MicrosoftAzure\Storage\Blob\BlobRestProxy
* @return \AzureOss\Storage\Blob\BlobContainerClient
*/
protected function createClient() : BlobRestProxy
protected function createClient() : BlobContainerClient
{
return BlobRestProxy::createBlobService($this->connectionString);
return BlobServiceClient::fromConnectionString($this->connectionString)
->getContainerClient($this->containerName);
}

/**
Expand All @@ -157,7 +158,7 @@ protected function createClient() : BlobRestProxy
protected function createCollector(Target $target) : Collector
{
$path = new Path($this->pathRaw, $this->time);
return new Collector\AzureBlob($target, $path, $this->client, $this->containerName);
return new Collector\AzureBlob($target, $path, $this->client);
}

/**
Expand All @@ -180,47 +181,48 @@ public function simulate(Target $target, Result $result)
/**
* Check if an Azure Blob Storage Container exists
*
* @param \MicrosoftAzure\Storage\Blob\BlobRestProxy $blobRestProxy
* @param string $containerName
* @param \AzureOss\Storage\Blob\BlobContainerClient $client
* @return bool
*/
private function doesContainerExist(BlobRestProxy $blobRestProxy, string $containerName): bool
protected function doesContainerExist(BlobContainerClient $client): bool
{
$containers = $blobRestProxy->listContainers()->getContainers();
foreach ($containers as $container) {
if ($container->getName() === $containerName) {
return true;
}
}
return false;
return $client->exists();
}

/**
* Create an Azure Storage Container
*
* @param \MicrosoftAzure\Storage\Blob\BlobRestProxy $blobRestProxy
* @param \AzureOss\Storage\Blob\BlobContainerClient $client
*/
private function createContainer(BlobRestProxy $blobRestProxy)
protected function createContainer(BlobContainerClient $client)
{
$blobRestProxy->createContainer($this->containerName);
$client->create();
}

/**
* Upload backup to Azure Blob Storage
*
* @param \phpbu\App\Backup\Target $target
* @param \MicrosoftAzure\Storage\Blob\BlobRestProxy $blobRestProxy
* @param \phpbu\App\Backup\Target $target
* @param \AzureOss\Storage\Blob\BlobContainerClient $client
* @throws \phpbu\App\Backup\Sync\Exception
* @throws \phpbu\App\Exception
*/
private function upload(Target $target, BlobRestProxy $blobRestProxy)
protected function upload(Target $target, BlobContainerClient $client)
{
$source = $this->getFileHandle($target->getPathname(), 'r');
$blobRestProxy->createBlockBlob(
$this->containerName,
$this->getUploadPath($target),
$source
);
$this->uploadBlob($client, $this->getUploadPath($target), $source);
}

/**
* Upload a single blob to the container.
*
* @param \AzureOss\Storage\Blob\BlobContainerClient $client
* @param string $path
* @param resource $source
*/
protected function uploadBlob(BlobContainerClient $client, string $path, $source)
{
$client->getBlobClient($path)->upload($source);
}

/**
Expand Down
Loading