import logging import re from typing import Set from amqp.model.model import AMQRoute from amqp.router.utils import sanitize_as_rabbitmq_name class RouteDatabase: def __init__(self): self.routes: Set[AMQRoute] = set() def get_routes(self) -> Set[AMQRoute]: return self.routes def pattern(self, routing_key: str) -> re.Pattern: regex = r"\.".join( [ r".*" if token == "" else r"#" if token == "#" else token for token in routing_key.split(".") ] ) if routing_key.endswith("."): regex += r"\." return re.compile(regex) def matches(self, routing_key_from_route: str, routing_key_from_message: str) -> bool: route_pattern = self.pattern(routing_key_from_route) return bool(route_pattern.match(sanitize_as_rabbitmq_name(routing_key_from_message))) def wrap_routes(self) -> str: return ",".join(str(route) for route in self.routes) def find_route(self, domain: str, path: str) -> AMQRoute | None: routing_key = sanitize_as_rabbitmq_name(f"{domain}.{path}") logging.info(f" [DBG] findRoute key:{routing_key} in:{self.wrap_routes()}") for route in self.routes: if self.matches(route.key, routing_key): return route return None def add_route(self, route: AMQRoute) -> bool: if route not in self.routes: self.routes.add(route) return True return False def remove_route(self, route: AMQRoute) -> bool: return route in self.routes and self.routes.remove(route)