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": {
|
||||
"psr-4": {
|
||||
"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": {
|
||||
|
@ -40,6 +40,9 @@
|
||||
<testsuite name="DocGeneratorBundle">
|
||||
<directory suffix="Test.php">src/Bundle/ChillDocGeneratorBundle/tests/</directory>
|
||||
</testsuite>
|
||||
<testsuite name="WopiBundle">
|
||||
<directory suffix="Test.php">src/Bundle/ChillWopiBundle/tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<listeners>
|
||||
|
@ -13,7 +13,9 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlGeneratorInterface;
|
||||
use ChampsLibres\WopiBundle\Service\Wopi as CLWopi;
|
||||
use ChampsLibres\WopiLib\Contract\Service\DocumentLockManagerInterface;
|
||||
use ChampsLibres\WopiLib\Contract\Service\DocumentManagerInterface;
|
||||
use Chill\WopiBundle\Service\Wopi\ChillDocumentLockManager;
|
||||
use Chill\WopiBundle\Service\Wopi\ChillDocumentManager;
|
||||
use Chill\WopiBundle\Service\Wopi\ChillWopi;
|
||||
|
||||
@ -41,6 +43,11 @@ return static function (ContainerConfigurator $container) {
|
||||
$services
|
||||
->alias(DocumentManagerInterface::class, ChillDocumentManager::class);
|
||||
|
||||
$services
|
||||
->set(ChillDocumentLockManager::class)
|
||||
->decorate(DocumentLockManagerInterface::class)
|
||||
;
|
||||
|
||||
// TODO: Move this into the async bundle (low priority)
|
||||
$services
|
||||
->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,
|
||||
RequestInterface $request
|
||||
): 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);
|
||||
}
|
||||
|
||||
|
@ -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