Skip to content
Closed
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
1 change: 1 addition & 0 deletions simulation_bridge/config/config.yaml.template
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
simulation_bridge:
bridge_id: simulation_bridge
in_memory_mode: false

rabbitmq:
host: localhost
Expand Down
3 changes: 2 additions & 1 deletion simulation_bridge/src/core/bridge_orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ def __init__(self, config_path: str = None):
self.adapters = {}
self._running = False

self.protocol_config = load_protocol_config()
self.protocol_config = load_protocol_config(self.config_manager.config_path)
SignalManager.PROTOCOL_CONFIG = self.protocol_config
self.adapter_classes = self._import_adapter_classes()

def setup_interfaces(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from ...utils.logger import get_logger
from ..base.protocol_adapter import ProtocolAdapter
from ...utils.signal_manager import SignalManager
from ...utils.config_loader import load_protocol_config
from ...core.bridge_core import BridgeCore
from ..rabbitmq.rabbitmq_adapter import RabbitMQAdapter

Expand Down Expand Up @@ -84,47 +85,14 @@ def _handle_message(self, message: Dict[str, Any]) -> None: # pylint: disable=u
pass


class DummyAdapter(ProtocolAdapter):
"""Neutral adapter for MQTT and REST protocols."""

def __init__(self, config_manager: ConfigManager | None = None):
super().__init__(config_manager or ConfigManager(None))

def _get_config(self) -> Dict[str, Any]:
return {}

def start(self) -> None:
logger.debug("DummyAdapter started (no-op)")
self._running = True

def stop(self) -> None:
logger.debug("DummyAdapter stopped (no-op)")
self._running = False

def _handle_message(self, message: Dict[str, Any]) -> None: # noqa: D401
# This method is intentionally empty as DummyAdapter serves as a null object
# to prevent errors when MQTT/REST protocols are not used but signals expect
# these adapters to be registered
pass

def publish_result_message_mqtt(self, *_, **__) -> None:
# This method is intentionally empty as DummyAdapter serves as a null object
# to prevent errors when MQTT/REST protocols are not used but signals expect
# these adapters to be registered
pass

def publish_result_message_rest(self, *_, **__) -> None:
# This method is intentionally empty as DummyAdapter serves as a null object
# to prevent errors when MQTT/REST protocols are not used but signals expect
# these adapters to be registered
pass


class SimulationBridge:
"""Run simulations using the in-memory protocol adapter."""

def __init__(self, config_path: str | None = None) -> None:
self.config_manager = ConfigManager(config_path)
SignalManager.PROTOCOL_CONFIG = load_protocol_config(
self.config_manager.config_path)
self.inmemory_adapter = InMemoryAdapter(self.config_manager)
self.rabbitmq_adapter = RabbitMQAdapter(self.config_manager)

Expand All @@ -140,12 +108,6 @@ def __init__(self, config_path: str | None = None) -> None:
SignalManager.register_adapter_instance(
"rabbitmq", self.rabbitmq_adapter)

# Required to satisfy signals expecting these adapters.
# Acts as a "null object" to avoid errors when MQTT/REST are unused.
dummy = DummyAdapter()
SignalManager.register_adapter_instance("mqtt", dummy)
SignalManager.register_adapter_instance("rest", dummy)

SignalManager.connect_all_signals()

self.inmemory_adapter.start()
Expand Down
21 changes: 21 additions & 0 deletions simulation_bridge/src/protocol_adapters/inmemory_signal.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"protocols": {
"rabbitmq": {
"enabled": true,
"signals": {
"message_received_input_rabbitmq": "BridgeCore.handle_input_message",
"message_received_result_rabbitmq": "BridgeCore.handle_result_rabbitmq_message",
"message_received_result_unknown": "BridgeCore.handle_result_unknown_message"
},
"class": ".rabbitmq.rabbitmq_adapter.RabbitMQAdapter"
},
"inmemory": {
"enabled": true,
"signals": {
"message_received_input_inmemory": "BridgeCore.handle_input_message",
"message_received_result_inmemory": "InMemoryAdapter._handle_result"
},
"class": ".inmemory.inmemory_adapter.InMemoryAdapter"
}
}
}
23 changes: 17 additions & 6 deletions simulation_bridge/src/utils/config_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,22 @@ def _substitute_env_vars(
return config


def load_protocol_config() -> Dict[str, list]:
"""
Load the protocol configuration from a JSON file.
def load_protocol_config(config_path: Optional[Union[str, Path]] = None) -> Dict[str, list]:
"""Load the protocol configuration based on in-memory mode.

If the provided configuration file (or the default one) contains
``in_memory_mode: true`` under ``simulation_bridge``, the reduced
``inmemory_signal.json`` file will be loaded instead of the full
``adapters_signal.json``.
"""
config_file = Path(__file__).parent.parent / \
"protocol_adapters/adapters_signal.json"
with open(config_file, 'r', encoding='utf-8') as f:
cfg_path = Path(config_path) if config_path else Path(__file__).parent.parent.parent.parent / "config.yaml"
in_memory = False
try:
cfg = load_config(str(cfg_path))
in_memory = cfg.get("simulation_bridge", {}).get("in_memory_mode", False)
except Exception: # noqa: BLE001
logger.debug("Configuration not found or invalid, using defaults")
json_name = "inmemory_signal.json" if in_memory else "adapters_signal.json"
config_file = Path(__file__).parent.parent / f"protocol_adapters/{json_name}"
with open(config_file, "r", encoding="utf-8") as f:
return json.load(f)["protocols"]
4 changes: 3 additions & 1 deletion simulation_bridge/src/utils/config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class PerformanceConfig(BaseModel):
class SimulationBridgeConfig(BaseModel):
"""Configuration for simulation bridge."""
bridge_id: str
in_memory_mode: bool = False


class Config(BaseModel):
Expand Down Expand Up @@ -237,7 +238,8 @@ def get_default_config(self) -> Dict[str, Any]:
"""Get default configuration as dictionary."""
return Config(
simulation_bridge=SimulationBridgeConfig(
bridge_id="simulation_bridge"),
bridge_id="simulation_bridge",
in_memory_mode=False),
rabbitmq=RabbitMQConfig(
host="localhost",
port=5672,
Expand Down
22 changes: 11 additions & 11 deletions simulation_bridge/test/integration/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ def fake_ensure_certificates(**kwargs): # pylint: disable=unused-argument
MagicMock())
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.load_protocol_config",
lambda: {})
lambda *a, **k: {})
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.BridgeOrchestrator._import_adapter_classes",
lambda self: {})
Expand All @@ -344,7 +344,7 @@ def fake_ensure_certificates(**kwargs): # pylint: disable=unused-argument
MagicMock())
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.load_protocol_config",
lambda: {})
lambda *a, **k: {})
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.BridgeOrchestrator._import_adapter_classes",
lambda self: {})
Expand All @@ -367,7 +367,7 @@ def fake_ensure_certificates(**kwargs):
MagicMock())
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.load_protocol_config",
lambda: {})
lambda *a, **k: {})
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.BridgeOrchestrator._import_adapter_classes",
lambda self: {})
Expand All @@ -385,7 +385,7 @@ def test_bridge_orchestrator_start_and_stop(monkeypatch, mock_config_manager):
lambda *a, **k: mock_config_manager)
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.load_protocol_config",
lambda: {})
lambda *a, **k: {})
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.BridgeOrchestrator._import_adapter_classes",
lambda self: {})
Expand All @@ -412,7 +412,7 @@ def test_bridge_orchestrator_logs_bridge_id(monkeypatch, caplog):
'rabbitmq': {}}))
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.load_protocol_config",
lambda: {})
lambda *a, **k: {})
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.BridgeOrchestrator._import_adapter_classes",
lambda self: {})
Expand Down Expand Up @@ -507,7 +507,7 @@ def test_bridge_orchestrator_logs_error_on_exception(monkeypatch, caplog):
'rabbitmq': {}}))
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.load_protocol_config",
lambda: {})
lambda *a, **k: {})
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.BridgeOrchestrator._import_adapter_classes",
lambda self: {})
Expand Down Expand Up @@ -550,7 +550,7 @@ def mock_ensure_certificates(**kwargs):
'rabbitmq': {}}))
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.load_protocol_config",
lambda: {})
lambda *a, **k: {})
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.BridgeOrchestrator._import_adapter_classes",
lambda self: {})
Expand Down Expand Up @@ -622,7 +622,7 @@ def mock_ensure_certificates(**kwargs):
'rabbitmq': {}}))
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.load_protocol_config",
lambda: {})
lambda *a, **k: {})
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.BridgeOrchestrator._import_adapter_classes",
lambda self: {})
Expand Down Expand Up @@ -657,7 +657,7 @@ def mock_ensure_certificates(**kwargs):
'rabbitmq': {}}))
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.load_protocol_config",
lambda: {})
lambda *a, **k: {})
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.BridgeOrchestrator._import_adapter_classes",
lambda self: {})
Expand Down Expand Up @@ -698,7 +698,7 @@ def mock_ensure_certificates(**kwargs):
'rabbitmq': {}}))
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.load_protocol_config",
lambda: {})
lambda *a, **k: {})
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.BridgeOrchestrator._import_adapter_classes",
lambda self: {})
Expand Down Expand Up @@ -729,7 +729,7 @@ def mock_ensure_certificates(**kwargs):
'rabbitmq': {}}))
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.load_protocol_config",
lambda: {})
lambda *a, **k: {})
monkeypatch.setattr(
"simulation_bridge.src.core.bridge_orchestrator.BridgeOrchestrator._import_adapter_classes",
lambda self: {})
Expand Down
Loading