Skip to content

Commit

Permalink
Add an internal connection to the blob API
Browse files Browse the repository at this point in the history
Refactor the config, the config service and add config options
for connecting internally to blob.

Also adds a healthcheck to make sure the connection works.
  • Loading branch information
lazka committed Aug 26, 2024
1 parent c8be7b8 commit 1cf5c1e
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 65 deletions.
5 changes: 4 additions & 1 deletion src/Command/DebugCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Dbp\Relay\CabinetBundle\Command;

use Dbp\Relay\CabinetBundle\Service\BlobService;
use Dbp\Relay\CabinetBundle\Service\CabinetService;
use Dbp\Relay\CabinetBundle\TypesenseClient\SearchIndex;
use Symfony\Component\Console\Command\Command;
Expand All @@ -14,13 +15,15 @@ class DebugCommand extends Command
{
private CabinetService $cabinetService;
private SearchIndex $searchIndex;
private BlobService $blobService;

public function __construct(CabinetService $cabinetService, SearchIndex $searchIndex)
public function __construct(CabinetService $cabinetService, SearchIndex $searchIndex, BlobService $blobService)
{
parent::__construct();

$this->cabinetService = $cabinetService;
$this->searchIndex = $searchIndex;
$this->blobService = $blobService;
}

/**
Expand Down
54 changes: 41 additions & 13 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,48 @@ public function getConfigTreeBuilder(): TreeBuilder
->info('The database DSN')
->cannotBeEmpty()
->end()
->scalarNode('blob_base_url')
->info('Base URL for blob storage API')
->arrayNode('blob')
->children()
->scalarNode('api_url')
->info('URL for blob storage API')
->isRequired()
->end()
->scalarNode('api_url_internal')
->info('URL for blob storage API when connecting internally (defaults to url)')
->end()
->scalarNode('bucket_id')
->info('Bucket id for blob storage')
->isRequired()
->end()
->scalarNode('bucket_key')
->info('Secret key for blob storage')
->isRequired()
->end()
->scalarNode('idp_url')
->info('IDP URL for authenticating with blob')
->isRequired()
->end()
->scalarNode('idp_client_id')
->info('Client ID for authenticating with blob')
->isRequired()
->end()
->scalarNode('idp_client_secret')
->info('Client secret for authenticating with blob')
->isRequired()
->end()
->end()
->end()
->scalarNode('blob_bucket_id')
->info('Bucket id for blob storage')
->end()
->scalarNode('blob_key')
->info('Secret key for blob storage')
->end()
->scalarNode('typesense_base_url')
->info('Base URL for the Typesense server')
->end()
->scalarNode('typesense_api_key')
->info('API key for the Typesense server')
->arrayNode('typesense')
->children()
->scalarNode('api_url')
->info('URL for the Typesense server')
->isRequired()
->end()
->scalarNode('api_key')
->info('API key for the Typesense server')
->isRequired()
->end()
->end()
->end()
->end()
->append($this->getAuthNode())
Expand Down
3 changes: 0 additions & 3 deletions src/DependencyInjection/DbpRelayCabinetExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ public function loadInternal(array $mergedConfig, ContainerBuilder $container):
);
$loader->load('services.yaml');

$definition = $container->getDefinition('Dbp\Relay\CabinetBundle\Service\BlobService');
$definition->addMethodCall('setConfig', [$mergedConfig]);

$definition = $container->getDefinition('Dbp\Relay\CabinetBundle\Service\CabinetService');
$definition->addMethodCall('setConfig', [$mergedConfig]);

Expand Down
59 changes: 17 additions & 42 deletions src/Service/BlobService.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,56 +11,28 @@
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Uid\Uuid;

class BlobService implements LoggerAwareInterface
{
use LoggerAwareTrait;

/**
* @var mixed
*/
private $blobKey;
/**
* @var mixed
*/
private $blobBucketId;

/**
* @var UrlGeneratorInterface
*/
private $router;

/**
* @var string
*/
private $blobBaseUrl;

/**
* @var BlobApi
*/
private $blobApi;

/**
* @var AuthorizationService
*/
private $auth;

public function __construct(UrlGeneratorInterface $router, AuthorizationService $auth)
private AuthorizationService $auth;

private ConfigurationService $config;

public function __construct(AuthorizationService $auth, ConfigurationService $config)
{
$this->router = $router;
$this->blobBaseUrl = '';
$this->blobKey = '';
$this->blobBucketId = '';
$this->auth = $auth;
$this->config = $config;
}

public function setConfig(array $config)
public function checkConnection(): void
{
$this->blobBaseUrl = $config['blob_base_url'] ?? '';
$this->blobKey = $config['blob_key'] ?? '';
$this->blobBucketId = $config['blob_bucket_id'] ?? '';
$this->blobApi = new BlobApi($this->blobBaseUrl, $this->blobBucketId, $this->blobKey);
$config = $this->config;
$blobApi = new BlobApi($config->getBlobApiUrlInternal(), $config->getBlobBucketId(), $config->getBlobBucketKey());
$blobApi->setOAuth2Token($config->getBlobIdpUrl(), $config->getBlobIdpClientId(), $config->getBlobIdpClientSecret());
$blobApi->getFileDataByPrefix(Uuid::v4()->toRfc4122(), 0);
}

public function getSignatureForGivenRequest(Request $request): Response
Expand All @@ -73,6 +45,7 @@ public function getSignatureForGivenRequest(Request $request): Response
// TODO: Check permissions
$this->auth->checkCanUse();

$config = $this->config;
$method = 'POST';
$creationTime = rawurlencode((new \DateTime())->format('c'));

Expand All @@ -83,9 +56,11 @@ public function getSignatureForGivenRequest(Request $request): Response
$notifyEmail = $request->query->get('notifyEmail', '');
$type = $request->query->get('type', '');

$blobApi = new BlobApi($this->config->getBlobApiUrl(), $config->getBlobBucketId(), $config->getBlobBucketKey());

try {
$params = [
'bucketIdentifier' => $this->blobBucketId,
'bucketIdentifier' => $config->getBlobBucketId(),
'creationTime' => $creationTime,
'fileName' => $fileName,
'method' => $method,
Expand All @@ -95,7 +70,7 @@ public function getSignatureForGivenRequest(Request $request): Response
'type' => $type,
];

$responseUrl = $this->blobApi->getSignedBlobFilesUrl($params);
$responseUrl = $blobApi->getSignedBlobFilesUrl($params);

return new Response($responseUrl, 200);
} catch (\Exception $e) {
Expand Down
41 changes: 38 additions & 3 deletions src/Service/ConfigurationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,48 @@ public function setConfig(array $config): void
$this->config = $config;
}

public function getTypesenseBaseUrl(): string
public function getTypesenseApiUrl(): string
{
return $this->config['typesense_base_url'];
return $this->config['typesense']['api_url'];
}

public function getTypesenseApiKey(): string
{
return $this->config['typesense_api_key'];
return $this->config['typesense']['api_key'];
}

public function getBlobApiUrl(): string
{
return $this->config['blob']['api_url'];
}

public function getBlobApiUrlInternal(): string
{
return $this->config['blob']['api_url_internal'] ?? $this->getBlobApiUrl();
}

public function getBlobIdpUrl(): string
{
return $this->config['blob']['idp_url'];
}

public function getBlobIdpClientId(): string
{
return $this->config['blob']['idp_client_id'];
}

public function getBlobIdpClientSecret(): string
{
return $this->config['blob']['idp_client_secret'];
}

public function getBlobBucketId(): string
{
return $this->config['blob']['bucket_id'];
}

public function getBlobBucketKey(): string
{
return $this->config['blob']['bucket_key'];
}
}
5 changes: 4 additions & 1 deletion src/Service/HealthCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ class HealthCheck implements CheckInterface
{
private CabinetService $cabinet;
private SearchIndex $searchIndex;
private BlobService $blob;

public function __construct(CabinetService $cabinet, SearchIndex $searchIndex)
public function __construct(CabinetService $cabinet, SearchIndex $searchIndex, BlobService $blob)
{
$this->cabinet = $cabinet;
$this->searchIndex = $searchIndex;
$this->blob = $blob;
}

public function getName(): string
Expand Down Expand Up @@ -45,6 +47,7 @@ public function check(CheckOptions $options): array
return [
$this->checkMethod('Check if we can connect to the DB', [$this->cabinet, 'checkConnection']),
$this->checkMethod('Check if we can connect to Typesense', [$this->searchIndex, 'checkConnection']),
$this->checkMethod('Check if we can connect to Blob', [$this->blob, 'checkConnection']),
];
}
}
2 changes: 1 addition & 1 deletion src/TypesenseApi/TypesenseService.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function doProxyRequest(string $path, Request $request): Response
// return new Response('Try later', Response::HTTP_UNAUTHORIZED);
// var_dump($request->get('x-typesense-api-key'));

$url = $this->config->getTypesenseBaseUrl().'/'.$path;
$url = $this->config->getTypesenseApiUrl().'/'.$path;
$method = $request->getMethod();

// Forward the request to Typesense server and return the response
Expand Down
2 changes: 1 addition & 1 deletion src/TypesenseClient/SearchIndex.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class SearchIndex implements LoggerAwareInterface
public function __construct(ConfigurationService $config)
{
$this->config = $config;
$this->connection = new Connection($config->getTypesenseBaseUrl(), $config->getTypesenseApiKey());
$this->connection = new Connection($config->getTypesenseApiUrl(), $config->getTypesenseApiKey());
$this->logger = new NullLogger();
$this->schema = [];
}
Expand Down

0 comments on commit 1cf5c1e

Please sign in to comment.