Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions diracx-cli/src/diracx/cli/internal/legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ def generate_helm_values(
},
}

if global_os_prefix := cfg["Systems"].get("NoSQLDatabases", {}).get("IndexPrefix"):
os_dbs["GlobalIndexPrefix"] = global_os_prefix

for entry_point in select_from_extension(group=DiracEntryPoint.OS_DB):
db_name = entry_point.name
db_config = all_db_configs.get(db_name, {})
Expand Down
6 changes: 6 additions & 0 deletions diracx-core/src/diracx/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
__all__ = [
"AuthSettings",
"DevelopmentSettings",
"FactorySettings",
"LocalFileUrl",
"SandboxStoreSettings",
"ServiceSettingsBase",
Expand Down Expand Up @@ -390,6 +391,11 @@ class FactorySettings(ServiceSettingsBase):
)
"""The url for the redis server to manage tasks"""

os_global_prefix: str = Field(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I understand, the prefix must be lower case.

default="", validation_alias="DIRACX_FACTORY_OS_GLOBAL_PREFIX"
)
"""Global prefix for OpenSearch database indices."""

enabled_services: dict[str, bool] = Field(default_factory=dict)
"""The following environment variables dictates which routers are enabled."""

Expand Down
6 changes: 5 additions & 1 deletion diracx-db/src/diracx/db/os/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,17 @@ class BaseOSDB(metaclass=ABCMeta):
@abstractmethod
def index_name(self, vo: str, doc_id: int) -> str: ...

def __init__(self, connection_kwargs: dict[str, Any]) -> None:
def __init__(
self, connection_kwargs: dict[str, Any], *, global_prefix: str = ""
) -> None:
self._client: AsyncOpenSearch | None = None
self._connection_kwargs = connection_kwargs
# We use a ContextVar to make sure that self._conn
# is specific to each context, and avoid parallel
# route executions to overlap
self._conn: ContextVar[bool] = ContextVar("_conn", default=False)
if global_prefix:
self.index_prefix = f"{global_prefix}_{self.index_prefix}"

@classmethod
def available_implementations(cls, db_name: str) -> list[type[BaseOSDB]]:
Expand Down
5 changes: 4 additions & 1 deletion diracx-routers/src/diracx/routers/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,14 @@ def create_app_inner(
app.dependency_overrides[source_cls.create] = source.read

# Add the OpenSearch DBs to the application
os_global_prefix = FactorySettings().os_global_prefix
available_os_db_classes: set[type[BaseOSDB]] = set()
for db_name, connection_kwargs in os_database_conn_kwargs.items():
os_db_classes = BaseOSDB.available_implementations(db_name)
# The first DB is the highest priority one
os_db = os_db_classes[0](connection_kwargs=connection_kwargs)
os_db = os_db_classes[0](
connection_kwargs=connection_kwargs, global_prefix=os_global_prefix
)
app.lifetime_functions.append(os_db.client_context)
# Add overrides for all the DB classes, including those from extensions
# This means vanilla DiracX routers get an instance of the extension's DB
Expand Down
5 changes: 4 additions & 1 deletion diracx-tasks/src/diracx/tasks/plumbing/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,12 @@ async def setup_dependency_overrides(
)

# --- OS databases ---
os_global_prefix = FactorySettings().os_global_prefix

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you can create a variable to encapsulate a FactorySettings instance so that you can reuse it with config_backend_url.

for db_name, conn_kwargs in BaseOSDB.available_urls().items():
os_db_classes = BaseOSDB.available_implementations(db_name)
os_db = os_db_classes[0](connection_kwargs=conn_kwargs)
os_db = os_db_classes[0](
connection_kwargs=conn_kwargs, global_prefix=os_global_prefix
)
await stack.enter_async_context(os_db.client_context())
for os_db_class in os_db_classes:
overrides[os_db_class.session] = partial(_db_context, os_db)
Expand Down
4 changes: 3 additions & 1 deletion diracx-testing/src/diracx/testing/mock_osdb.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How complex would it be to add a unit test against the mock OS DB?

Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class JobParametersDB(MockOSDBMixin, JobParametersDB):
JobParametersDB = type("JobParametersDB", (MockOSDBMixin, JobParametersDB), {})
"""

def __init__(self, connection_kwargs: dict[str, Any]) -> None:
def __init__(
self, connection_kwargs: dict[str, Any], global_prefix: str = ""
) -> None:
from sqlalchemy import JSON, Column, DateTime, Integer, MetaData, String, Table

# Dynamically create a subclass of BaseSQLDB so we get clearer errors
Expand Down
5 changes: 5 additions & 0 deletions docs/admin/reference/env-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ The hashed API key for the legacy exchange endpoint.
*Optional*, default value: `redis://localhost`
The url for the redis server to manage tasks

### `DIRACX_FACTORY_OS_GLOBAL_PREFIX`

*Optional*, default value: \`\`
Global prefix for OpenSearch database indices.

### `ENABLED_SERVICES`

*Optional*
Expand Down
Empty file added toto

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file seems unexpected 🥲

Empty file.
Loading