feat: add services configuration accessors
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -14,6 +14,7 @@ class TenantConfiguration extends JsonSerializableObject
|
|||||||
protected TenantFirewall $firewall;
|
protected TenantFirewall $firewall;
|
||||||
protected TenantStores $stores;
|
protected TenantStores $stores;
|
||||||
protected TenantPreview $preview;
|
protected TenantPreview $preview;
|
||||||
|
protected array $services = [];
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -36,6 +37,10 @@ class TenantConfiguration extends JsonSerializableObject
|
|||||||
return $this->firewall;
|
return $this->firewall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function services(): array {
|
||||||
|
return $this->services;
|
||||||
|
}
|
||||||
|
|
||||||
public function stores(): TenantStores {
|
public function stores(): TenantStores {
|
||||||
return $this->stores;
|
return $this->stores;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,4 +73,15 @@ class TenantService
|
|||||||
{
|
{
|
||||||
return $this->store->storeSettings($identifier, $settings);
|
return $this->store->storeSettings($identifier, $settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function fetchServiceConfiguration(string $identifier, string $name): ?array
|
||||||
|
{
|
||||||
|
return $this->store->fetchServiceConfiguration($identifier, $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function storeServiceConfiguration(string $identifier, string $name, array $configuration): bool
|
||||||
|
{
|
||||||
|
return $this->store->storeServiceConfiguration($identifier, $name, $configuration);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,29 +77,40 @@ class TenantStore
|
|||||||
$this->dataStore->selectCollection(self::COLLECTION_NAME)->deleteOne(['_id' => new ObjectId($id)]);
|
$this->dataStore->selectCollection(self::COLLECTION_NAME)->deleteOne(['_id' => new ObjectId($id)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// =========================================================================
|
||||||
* Atomically creates or replaces one logical store reference.
|
// Configuration Operations
|
||||||
*
|
// =========================================================================
|
||||||
* @param array{provider: string, service: string|int, namespace: string} $reference
|
|
||||||
*/
|
public function fetchConfiguration(string $identifier, string $path): ?array
|
||||||
public function storeConfigurationStore(string $identifier, string $name, array $reference): bool
|
{
|
||||||
|
$entry = $this->dataStore->selectCollection(self::COLLECTION_NAME)->findOne(
|
||||||
|
['identifier' => $identifier],
|
||||||
|
['projection' => ['configuration.' . $path => 1]],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!$entry) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = $this->readPath($entry, "configuration.{$path}");
|
||||||
|
return $value === null ? null : (array) $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function storeConfiguration(string $identifier, string $path, array $value): bool
|
||||||
{
|
{
|
||||||
$result = $this->dataStore->selectCollection(self::COLLECTION_NAME)->updateOne(
|
$result = $this->dataStore->selectCollection(self::COLLECTION_NAME)->updateOne(
|
||||||
['identifier' => $identifier],
|
['identifier' => $identifier],
|
||||||
['$set' => ["configuration.stores.{$name}" => $reference]],
|
['$set' => ['configuration.' . $path => $value]],
|
||||||
);
|
);
|
||||||
|
|
||||||
return $result->getMatchedCount() > 0;
|
return $result->getMatchedCount() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function removeConfiguration(string $identifier, string $path): ?bool
|
||||||
* Atomically removes one logical store reference.
|
|
||||||
*/
|
|
||||||
public function removeConfigurationStore(string $identifier, string $name): ?bool
|
|
||||||
{
|
{
|
||||||
$result = $this->dataStore->selectCollection(self::COLLECTION_NAME)->updateOne(
|
$result = $this->dataStore->selectCollection(self::COLLECTION_NAME)->updateOne(
|
||||||
['identifier' => $identifier],
|
['identifier' => $identifier],
|
||||||
['$unset' => ["configuration.stores.{$name}" => '']],
|
['$unset' => ['configuration.' . $path => '']],
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($result->getMatchedCount() === 0) {
|
if ($result->getMatchedCount() === 0) {
|
||||||
@@ -162,4 +173,54 @@ class TenantStore
|
|||||||
return $result->getMatchedCount() > 0;
|
return $result->getMatchedCount() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomically creates or replaces one logical store reference.
|
||||||
|
*
|
||||||
|
* @param array{provider: string, service: string|int, namespace: string} $reference
|
||||||
|
*/
|
||||||
|
public function storeConfigurationStore(string $identifier, string $name, array $reference): bool
|
||||||
|
{
|
||||||
|
return $this->storeConfiguration($identifier, "stores.{$name}", $reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomically removes one logical store reference.
|
||||||
|
*/
|
||||||
|
public function removeConfigurationStore(string $identifier, string $name): ?bool
|
||||||
|
{
|
||||||
|
return $this->removeConfiguration($identifier, "stores.{$name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fetchServiceConfiguration(string $identifier, string $name): ?array
|
||||||
|
{
|
||||||
|
$this->validateServiceName($name);
|
||||||
|
return $this->fetchConfiguration($identifier, "services.{$name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Save one service atomically. */
|
||||||
|
public function storeServiceConfiguration(string $identifier, string $name, array $configuration): bool
|
||||||
|
{
|
||||||
|
$this->validateServiceName($name);
|
||||||
|
return $this->storeConfiguration($identifier, "services.{$name}", $configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function validateServiceName(string $name): void
|
||||||
|
{
|
||||||
|
if (preg_match('/^[a-z][a-z0-9_]*$/D', $name) !== 1) {
|
||||||
|
throw new \InvalidArgumentException('Invalid service name.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function readPath(array $data, string $path): mixed
|
||||||
|
{
|
||||||
|
$value = $data;
|
||||||
|
foreach (explode('.', $path) as $segment) {
|
||||||
|
if (!is_array($value) || !array_key_exists($segment, $value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$value = $value[$segment];
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user