mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
re-implements document lock manager for wopi
This commit is contained in:
parent
bf536aab38
commit
03bc94178f
@ -96,7 +96,8 @@
|
|||||||
"autoload-dev": {
|
"autoload-dev": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"App\\": "tests/app/src/",
|
"App\\": "tests/app/src/",
|
||||||
"Chill\\DocGeneratorBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests"
|
"Chill\\DocGeneratorBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests",
|
||||||
|
"Chill\\WopiBundle\\Tests\\": "src/Bundle/ChillDocGeneratorBundle/tests"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
|
@ -40,6 +40,9 @@
|
|||||||
<testsuite name="DocGeneratorBundle">
|
<testsuite name="DocGeneratorBundle">
|
||||||
<directory suffix="Test.php">src/Bundle/ChillDocGeneratorBundle/tests/</directory>
|
<directory suffix="Test.php">src/Bundle/ChillDocGeneratorBundle/tests/</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
<testsuite name="WopiBundle">
|
||||||
|
<directory suffix="Test.php">src/Bundle/ChillWopiBundle/tests/</directory>
|
||||||
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
|
|
||||||
<listeners>
|
<listeners>
|
||||||
|
@ -13,7 +13,9 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
|||||||
|
|
||||||
use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlGeneratorInterface;
|
use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlGeneratorInterface;
|
||||||
use ChampsLibres\WopiBundle\Service\Wopi as CLWopi;
|
use ChampsLibres\WopiBundle\Service\Wopi as CLWopi;
|
||||||
|
use ChampsLibres\WopiLib\Contract\Service\DocumentLockManagerInterface;
|
||||||
use ChampsLibres\WopiLib\Contract\Service\DocumentManagerInterface;
|
use ChampsLibres\WopiLib\Contract\Service\DocumentManagerInterface;
|
||||||
|
use Chill\WopiBundle\Service\Wopi\ChillDocumentLockManager;
|
||||||
use Chill\WopiBundle\Service\Wopi\ChillDocumentManager;
|
use Chill\WopiBundle\Service\Wopi\ChillDocumentManager;
|
||||||
use Chill\WopiBundle\Service\Wopi\ChillWopi;
|
use Chill\WopiBundle\Service\Wopi\ChillWopi;
|
||||||
|
|
||||||
@ -41,6 +43,11 @@ return static function (ContainerConfigurator $container) {
|
|||||||
$services
|
$services
|
||||||
->alias(DocumentManagerInterface::class, ChillDocumentManager::class);
|
->alias(DocumentManagerInterface::class, ChillDocumentManager::class);
|
||||||
|
|
||||||
|
$services
|
||||||
|
->set(ChillDocumentLockManager::class)
|
||||||
|
->decorate(DocumentLockManagerInterface::class)
|
||||||
|
;
|
||||||
|
|
||||||
// TODO: Move this into the async bundle (low priority)
|
// TODO: Move this into the async bundle (low priority)
|
||||||
$services
|
$services
|
||||||
->alias(TempUrlGeneratorInterface::class, 'async_uploader.temp_url_generator');
|
->alias(TempUrlGeneratorInterface::class, 'async_uploader.temp_url_generator');
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\WopiBundle\Service\Wopi;
|
||||||
|
|
||||||
|
use ChampsLibres\WopiLib\Contract\Entity\Document;
|
||||||
|
use ChampsLibres\WopiLib\Contract\Service\DocumentLockManagerInterface;
|
||||||
|
use Chill\MainBundle\Redis\ChillRedis;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class ChillDocumentLockManager implements DocumentLockManagerInterface
|
||||||
|
{
|
||||||
|
private const LOCK_DURATION = 60 * 30 * 1000;
|
||||||
|
|
||||||
|
private int $postDeleteLockDurationMs;
|
||||||
|
|
||||||
|
private ChillRedis $redis;
|
||||||
|
|
||||||
|
public function __construct(ChillRedis $redis)
|
||||||
|
{
|
||||||
|
$this->redis = $redis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteLock(Document $document, RequestInterface $request): bool
|
||||||
|
{
|
||||||
|
$this->redis->del($this->getCacheId($document));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLock(Document $document, RequestInterface $request): string
|
||||||
|
{
|
||||||
|
if (false !== $value = $this->redis->get($this->getCacheId($document))) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException('wopi key does not exists');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasLock(Document $document, RequestInterface $request): bool
|
||||||
|
{
|
||||||
|
return $this->redis->exists($this->getCacheId($document)) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLock(Document $document, string $lockId, RequestInterface $request): bool
|
||||||
|
{
|
||||||
|
$key = $this->getCacheId($document);
|
||||||
|
$this->redis->setex($key, self::LOCK_DURATION, $lockId);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getCacheId(Document $document): string
|
||||||
|
{
|
||||||
|
return sprintf('wopi_lib_lock_%s', $document->getWopiDocId());
|
||||||
|
}
|
||||||
|
}
|
@ -188,6 +188,11 @@ final class ChillWopi implements WopiInterface
|
|||||||
string $xWopiLock,
|
string $xWopiLock,
|
||||||
RequestInterface $request
|
RequestInterface $request
|
||||||
): ResponseInterface {
|
): ResponseInterface {
|
||||||
|
// this is because there are a delay between the request which PUT the file content,
|
||||||
|
// and the unlock: the PUT request last longer and this make the request fails, because
|
||||||
|
// the unlock terminate before.
|
||||||
|
sleep(5);
|
||||||
|
|
||||||
return $this->wopi->unlock($fileId, $accessToken, $xWopiLock, $request);
|
return $this->wopi->unlock($fileId, $accessToken, $xWopiLock, $request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\WopiBundle\Tests\Service\Wopi;
|
||||||
|
|
||||||
|
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||||
|
use Chill\MainBundle\Redis\ChillRedis;
|
||||||
|
use Chill\WopiBundle\Service\Wopi\ChillDocumentLockManager;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class ChillDocumentLockManagerTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMultipleLoops()
|
||||||
|
{
|
||||||
|
$manager = $this->makeManager(1);
|
||||||
|
$document = new StoredObject();
|
||||||
|
$request = $this->prophesize(RequestInterface::class);
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
|
||||||
|
while (50 > ++$i) {
|
||||||
|
$this->assertFalse($manager->hasLock($document, $request->reveal()));
|
||||||
|
|
||||||
|
$this->assertTrue($manager->setLock($document, 'dummy', $request->reveal()));
|
||||||
|
|
||||||
|
$this->assertEquals('dummy', $manager->getLock($document, $request->reveal()));
|
||||||
|
|
||||||
|
$this->assertTrue($manager->deleteLock($document, $request->reveal()));
|
||||||
|
|
||||||
|
$this->assertFalse($manager->hasLock($document, $request->reveal()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSingleLock()
|
||||||
|
{
|
||||||
|
$manager = $this->makeManager(1);
|
||||||
|
$document = new StoredObject();
|
||||||
|
$request = $this->prophesize(RequestInterface::class);
|
||||||
|
|
||||||
|
$this->assertFalse($manager->hasLock($document, $request->reveal()));
|
||||||
|
|
||||||
|
$this->assertTrue($manager->setLock($document, 'dummy', $request->reveal()));
|
||||||
|
|
||||||
|
$this->assertEquals('dummy', $manager->getLock($document, $request->reveal()));
|
||||||
|
|
||||||
|
$this->assertTrue($manager->deleteLock($document, $request->reveal()));
|
||||||
|
|
||||||
|
$this->assertFalse($manager->hasLock($document, $request->reveal()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function makeManager(int $ttlAfterDeleteSeconds): ChillDocumentLockManager
|
||||||
|
{
|
||||||
|
$redis = self::$container->get(ChillRedis::class);
|
||||||
|
|
||||||
|
return new ChillDocumentLockManager($redis, $ttlAfterDeleteSeconds);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user