refactor(config): abstract config storage and enable dependency injection
Abstract the configuration storage mechanism to allow using custom configurations, such as in-memory setups, when using the tool as a library. This aligns the configuration architecture with the session cache abstraction. - Define ConfigInterface protocol and InMemoryConfig class - Make CacheFile, InMemoryCache, ConfigFile, and InMemoryConfig explicitly inherit their interfaces - Update MdrsService and MdrsClient to accept customizable config_class and config instances - Add validation to check remote parameter consistency in create_connection - Remove unused imports across command files
This commit is contained in:
+52
-2
@@ -1,6 +1,7 @@
|
||||
import configparser
|
||||
import os
|
||||
from typing import Final
|
||||
import threading
|
||||
from typing import Final, Protocol, runtime_checkable
|
||||
|
||||
import validators
|
||||
|
||||
@@ -9,7 +10,56 @@ from mdrsclient.settings import CONFIG_DIRNAME
|
||||
from mdrsclient.utils import FileLock
|
||||
|
||||
|
||||
class ConfigFile:
|
||||
@runtime_checkable
|
||||
class ConfigInterface(Protocol):
|
||||
remote: str
|
||||
|
||||
def list(self) -> list[tuple[str, str]]: ...
|
||||
@property
|
||||
def url(self) -> str | None: ...
|
||||
@url.setter
|
||||
def url(self, url: str) -> None: ...
|
||||
@url.deleter
|
||||
def url(self) -> None: ...
|
||||
|
||||
|
||||
class InMemoryConfig(ConfigInterface):
|
||||
__configs: dict[str, str] = {}
|
||||
__lock: threading.Lock = threading.Lock()
|
||||
remote: str
|
||||
|
||||
def __init__(self, remote: str) -> None:
|
||||
self.remote = remote
|
||||
|
||||
def list(self) -> list[tuple[str, str]]:
|
||||
with self.__lock:
|
||||
return list(self.__configs.items())
|
||||
|
||||
@property
|
||||
def url(self) -> str | None:
|
||||
with self.__lock:
|
||||
return self.__configs.get(self.remote)
|
||||
|
||||
@url.setter
|
||||
def url(self, url: str) -> None:
|
||||
if not validators.url(url):
|
||||
raise IllegalArgumentException("malformed URI sequence")
|
||||
with self.__lock:
|
||||
self.__configs[self.remote] = url
|
||||
|
||||
@url.deleter
|
||||
def url(self) -> None:
|
||||
with self.__lock:
|
||||
if self.remote in self.__configs:
|
||||
del self.__configs[self.remote]
|
||||
|
||||
@classmethod
|
||||
def clear(cls) -> None:
|
||||
with cls.__lock:
|
||||
cls.__configs.clear()
|
||||
|
||||
|
||||
class ConfigFile(ConfigInterface):
|
||||
OPTION_URL: Final[str] = "url"
|
||||
CONFIG_FILENAME: Final[str] = "config.ini"
|
||||
remote: str
|
||||
|
||||
Reference in New Issue
Block a user