mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-22 15:43:51 +00:00
Implement asynchronous upload feature in Openstack Object Store
Those features were previously stored in champs-libres/async-upload-bundle This commit introduces several new classes within the ChillDocStore bundle for handling asynchronous uploads onto an Openstack Object Store. Specifically, the TempUrlOpenstackGenerator, SignedUrl, TempUrlGeneratorInterface, TempUrlGenerateEvent, and TempUrlGeneratorException classes have been created. This implementation will allow for generating "temporary URLs", which assist in securely and temporarily uploading resources to the OpenStack Object Store. This feature enables the handling of file uploads in a more scalable and efficient manner in high-volume environments. Additionally, corresponding unit tests have also been added to ensure the accuracy of this new feature.
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace AsyncUpload\Driver\OpenstackObjectStore;
|
||||
|
||||
use Chill\DocStoreBundle\AsyncUpload\Driver\OpenstackObjectStore\TempUrlOpenstackGenerator;
|
||||
use Chill\DocStoreBundle\AsyncUpload\SignedUrl;
|
||||
use Chill\DocStoreBundle\AsyncUpload\SignedUrlPost;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\NullLogger;
|
||||
use Symfony\Component\Clock\MockClock;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class TempUrlOpenstackGeneratorTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider dataProviderGenerate
|
||||
*/
|
||||
public function testGenerate(string $baseUrl, \DateTimeImmutable $now, string $key, string $method, string $objectName, int $expireDelay, SignedUrl $expected): void
|
||||
{
|
||||
$logger = new NullLogger();
|
||||
$eventDispatcher = new EventDispatcher();
|
||||
$clock = new MockClock($now);
|
||||
|
||||
$generator = new TempUrlOpenstackGenerator(
|
||||
$logger,
|
||||
$eventDispatcher,
|
||||
$clock,
|
||||
$baseUrl,
|
||||
$key,
|
||||
1800,
|
||||
1800,
|
||||
150
|
||||
);
|
||||
|
||||
$signedUrl = $generator->generate($method, $objectName, $expireDelay);
|
||||
|
||||
self::assertEquals($expected, $signedUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataProviderGeneratePost
|
||||
*/
|
||||
public function testGeneratePost(string $baseUrl, \DateTimeImmutable $now, string $key, string $method, string $objectName, int $expireDelay, SignedUrl $expected): void
|
||||
{
|
||||
$logger = new NullLogger();
|
||||
$eventDispatcher = new EventDispatcher();
|
||||
$clock = new MockClock($now);
|
||||
|
||||
$generator = new TempUrlOpenstackGenerator(
|
||||
$logger,
|
||||
$eventDispatcher,
|
||||
$clock,
|
||||
$baseUrl,
|
||||
$key,
|
||||
1800,
|
||||
1800,
|
||||
150
|
||||
);
|
||||
|
||||
$signedUrl = $generator->generatePost();
|
||||
|
||||
self::assertEquals('POST', $signedUrl->method);
|
||||
self::assertEquals((int) $clock->now()->format('U') + 1800, $signedUrl->expires->getTimestamp());
|
||||
self::assertEquals(150, $signedUrl->max_file_size);
|
||||
self::assertEquals(1, $signedUrl->max_file_count);
|
||||
self::assertEquals(1800, $signedUrl->submit_delay);
|
||||
self::assertEquals('', $signedUrl->redirect);
|
||||
self::assertGreaterThanOrEqual(20, strlen($signedUrl->prefix));
|
||||
}
|
||||
|
||||
public function dataProviderGenerate(): iterable
|
||||
{
|
||||
$now = \DateTimeImmutable::createFromFormat('U', '1702041743');
|
||||
$expireDelay = 1800;
|
||||
$baseUrls = [
|
||||
'https://objectstore.example/v1/my_account/container/',
|
||||
'https://objectstore.example/v1/my_account/container',
|
||||
];
|
||||
$objectName = 'object';
|
||||
$method = 'GET';
|
||||
$key = 'MYKEY';
|
||||
|
||||
$signedUrl = new SignedUrl(
|
||||
'GET',
|
||||
'https://objectstore.example/v1/my_account/container/object?temp_url_sig=0aeef353a5f6e22d125c76c6ad8c644a59b222ba1b13eaeb56bf3d04e28b081d11dfcb36601ab3aa7b623d79e1ef03017071bbc842fb7b34afec2baff895bf80&temp_url_expires=1702043543',
|
||||
\DateTimeImmutable::createFromFormat('U', '1702043543')
|
||||
);
|
||||
|
||||
foreach ($baseUrls as $baseUrl) {
|
||||
yield [
|
||||
$baseUrl,
|
||||
$now,
|
||||
$key,
|
||||
$method,
|
||||
$objectName,
|
||||
$expireDelay,
|
||||
$signedUrl,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function dataProviderGeneratePost(): iterable
|
||||
{
|
||||
$now = \DateTimeImmutable::createFromFormat('U', '1702041743');
|
||||
$expireDelay = 1800;
|
||||
$baseUrls = [
|
||||
'https://objectstore.example/v1/my_account/container/',
|
||||
'https://objectstore.example/v1/my_account/container',
|
||||
];
|
||||
$objectName = 'object';
|
||||
$method = 'GET';
|
||||
$key = 'MYKEY';
|
||||
|
||||
$signedUrl = new SignedUrlPost(
|
||||
'https://objectstore.example/v1/my_account/container/object?temp_url_sig=0aeef353a5f6e22d125c76c6ad8c644a59b222ba1b13eaeb56bf3d04e28b081d11dfcb36601ab3aa7b623d79e1ef03017071bbc842fb7b34afec2baff895bf80&temp_url_expires=1702043543',
|
||||
\DateTimeImmutable::createFromFormat('U', '1702043543'),
|
||||
150,
|
||||
1,
|
||||
1800,
|
||||
'',
|
||||
'abc',
|
||||
'abc'
|
||||
);
|
||||
|
||||
foreach ($baseUrls as $baseUrl) {
|
||||
yield [
|
||||
$baseUrl,
|
||||
$now,
|
||||
$key,
|
||||
$method,
|
||||
$objectName,
|
||||
$expireDelay,
|
||||
$signedUrl,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user