Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
lazka committed Aug 29, 2024
1 parent 4cf2527 commit 1821773
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 30 deletions.
97 changes: 97 additions & 0 deletions src/Blob/BlobSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

declare(strict_types=1);

namespace Dbp\Relay\CabinetBundle\Blob;

use Dbp\Relay\BlobBundle\Entity\FileData;
use Dbp\Relay\BlobBundle\Event\AddFileDataByPostSuccessEvent;
use Dbp\Relay\BlobBundle\Event\ChangeFileDataByPatchSuccessEvent;
use Dbp\Relay\BlobBundle\Event\DeleteFileDataByDeleteSuccessEvent;
use Dbp\Relay\CabinetBundle\Service\ConfigurationService;
use Dbp\Relay\CabinetBundle\TypesenseSync\DocumentTranslator;
use Dbp\Relay\CabinetBundle\TypesenseSync\TypesenseSync;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class BlobSubscriber implements EventSubscriberInterface
{
private ConfigurationService $config;
private DocumentTranslator $translator;
private TypesenseSync $typesenseSync;

public function __construct(ConfigurationService $config, DocumentTranslator $translator, TypesenseSync $typesenseSync)
{
$this->config = $config;
$this->translator = $translator;
$this->typesenseSync = $typesenseSync;
}

private function isForCabinet(FileData $fileData): bool
{
$bucket = $fileData->getBucket();
if ($bucket->getBucketID() !== $this->config->getBlobBucketId()) {
return false;
}
if ($fileData->getPrefix() !== $this->config->getBlobBucketPrefix()) {
return false;
}

return true;
}

public static function getSubscribedEvents(): array
{
return [
AddFileDataByPostSuccessEvent::class => 'onFileAdded',
ChangeFileDataByPatchSuccessEvent::class => 'onFileChanged',
DeleteFileDataByDeleteSuccessEvent::class => 'onFileRemoved',
];
}

private function translateMetadata(FileData $fileData): array
{
$metadata = json_decode($fileData->getMetadata(), associative: true, flags: JSON_THROW_ON_ERROR);
$objectType = $metadata['objectType'];
$input = [
'id' => $fileData->getIdentifier(),
'fileSource' => $fileData->getBucket()->getBucketID(),
'fileName' => $fileData->getFileName(),
'metadata' => $metadata,
];

return $this->translator->translateDocument($objectType, $input);
}

public function onFileAdded(AddFileDataByPostSuccessEvent $event)
{
$fileData = $event->getFileData();
if (!$this->isForCabinet($fileData)) {
return;
}

$translated = $this->translateMetadata($fileData);
$this->typesenseSync->upsertPartialFile($translated);
}

public function onFileChanged(ChangeFileDataByPatchSuccessEvent $event)
{
$fileData = $event->getFileData();
if (!$this->isForCabinet($fileData)) {
return;
}

$translated = $this->translateMetadata($fileData);
$this->typesenseSync->upsertPartialFile($translated);
}

public function onFileRemoved(DeleteFileDataByDeleteSuccessEvent $event)
{
$fileData = $event->getFileData();
if (!$this->isForCabinet($fileData)) {
return;
}

$translated = $this->translateMetadata($fileData);
$this->typesenseSync->removePartialFile($translated);
}
}
49 changes: 49 additions & 0 deletions src/Command/DeleteFileCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace Dbp\Relay\CabinetBundle\Command;

use Dbp\Relay\BlobLibrary\Api\BlobApiError;
use Dbp\Relay\CabinetBundle\Service\BlobService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class DeleteFileCommand extends Command
{
private BlobService $blobService;

public function __construct(BlobService $blobService)
{
parent::__construct();

$this->blobService = $blobService;
}

protected function configure(): void
{
$this->setName('dbp:relay:cabinet:delete-file');
$this->setDescription('Delete a file from the cabinet blob bucket');
$this->addArgument('id', InputArgument::REQUIRED, 'The ID of the file');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$fileId = $input->getArgument('id');

try {
$this->blobService->deleteFile($fileId);
$output->writeln("<info>File deleted successfully: $fileId</info>");

return Command::SUCCESS;
} catch (BlobApiError $e) {
$output->writeln('<error>Error deleting file: '.$e->getMessage().' </error>');
$output->writeln(print_r($e->getErrorId(), true));
$output->writeln(print_r($e->getErrorDetails(), true));

return Command::FAILURE;
}
}
}
4 changes: 3 additions & 1 deletion src/Command/UploadFileCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ protected function configure(): void
$this->addArgument('filepath', InputArgument::REQUIRED, 'The path to the file to upload');
$this->addOption('type', 't', InputOption::VALUE_OPTIONAL, 'The type of the file');
$this->addOption('metadata', 'm', InputOption::VALUE_OPTIONAL, 'The metadata of the file');
$this->addOption('filename', 'f', InputOption::VALUE_REQUIRED,
'The filename, defaults to the filename of the given filepath');
}

protected function execute(InputInterface $input, OutputInterface $output): int
Expand All @@ -48,7 +50,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return Command::FAILURE;
}

$filename = basename($filepath);
$filename = $input->getOption('filename') ?? basename($filepath);
$payload = file_get_contents($filepath);

if ($payload === false) {
Expand Down
27 changes: 0 additions & 27 deletions src/EventSubscriber/BlobAddFileSuccessSubscriber.php

This file was deleted.

8 changes: 6 additions & 2 deletions src/Resources/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ services:
autowire: true
autoconfigure: true

Dbp\Relay\CabinetBundle\Command\DeleteFileCommand:
autowire: true
autoconfigure: true

Dbp\Relay\CabinetBundle\Authorization\AuthorizationService:
autowire: true
autoconfigure: true
Expand All @@ -65,8 +69,8 @@ services:
autowire: true
autoconfigure: true

Dbp\Relay\CabinetBundle\EventSubscriber\:
resource: '../../EventSubscriber'
Dbp\Relay\CabinetBundle\Blob\:
resource: '../../Blob'
autowire: true
autoconfigure: true

Expand Down
7 changes: 7 additions & 0 deletions src/Service/BlobService.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ public function uploadFile(string $filename, string $payload, ?string $type = nu
return $blobApi->uploadFile($this->config->getBlobBucketPrefix(), $filename, $payload, $metadata ?? '', $type ?? '');
}

public function deleteFile(string $id): void
{
$blobApi = $this->getInternalBlobApi();

$blobApi->deleteFileByIdentifier($id);
}

public function getSignatureForGivenRequest(Request $request): Response
{
if (!$this->auth->isAuthenticated()) {
Expand Down
24 changes: 24 additions & 0 deletions src/TypesenseClient/SearchIndex.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,30 @@ public function addDocumentsToCollection(string $collectionName, array $document
}
}

/**
* Returns all documents of type $type where $key matches $value.
*/
public function findDocuments(string $collectionName, string $type, string $key, string $value): array
{
if (preg_match('/\s/', $value) || preg_match('/\s/', $type)) {
throw new \RuntimeException('no whitespace supported');
}
$filterBy = $key.':='.$value.' && @type := '.$type;
$searchResult = $this->getClient()->collections[$collectionName]->documents->search(['q' => '*', 'filter_by' => $filterBy]);

$documents = [];
foreach ($searchResult['hits'] as $hit) {
$documents[] = $hit['document'];
}

return $documents;
}

public function deleteDocument(string $collectionName, string $id): void
{
$this->getClient()->collections[$collectionName]->documents[$id]->delete();
}

public function updateAlias(string $collectionName): void
{
$aliasName = $this->getAliasName();
Expand Down
26 changes: 26 additions & 0 deletions src/TypesenseSync/TypesenseSync.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,32 @@ private static function generateRandomPDFNames($count = 50): array
return $fileNames;
}

public function upsertPartialFile(array $partialFileDocument): void
{
$collectionName = $this->searchIndex->getAliasName();

$id = $partialFileDocument['base']['identNrObfuscated'];

// Find the matching person, and copy over the base info
$results = $this->searchIndex->findDocuments($collectionName, 'Person', 'base.identNrObfuscated', $id);
if ($results) {
$partialFileDocument['base'] = $results[0]['base'];
} else {
// FIXME: what if the person is missing? Just ignore the document until the next full sync, or poll later?
// atm the schema needs those fields, so just skip for now
return;
}

$this->searchIndex->addDocumentsToCollection($collectionName, [$partialFileDocument]);
}

public function removePartialFile(array $partialFileDocument): void
{
$collectionName = $this->searchIndex->getAliasName();
$id = $partialFileDocument['id'];
$this->searchIndex->deleteDocument($collectionName, $id);
}

public function addDummyDocuments(string $collectionName, array $personDocuments): void
{
$documents = [];
Expand Down

0 comments on commit 1821773

Please sign in to comment.