diff --git a/mapping_provider/api/map.py b/mapping_provider/api/map.py index 8a16ac574f9aa6202a7ce14b920ebdc39b32df5d..0fb98c2ebffa91a72af6f3a091ab0ddacb597a59 100644 --- a/mapping_provider/api/map.py +++ b/mapping_provider/api/map.py @@ -162,4 +162,4 @@ def get_trunks() -> services.ServiceList: """ handler for /trunks """ - return services.build_service_info_list() + return services.build_service_info_list(service_type='IP TRUNK') diff --git a/mapping_provider/backends/services.py b/mapping_provider/backends/services.py index aabafda1243bd1c4086bc9a0f9360eb6f4da55b1..ae8c537eb69f6d0b3cbd208934a11c67be4ca596 100644 --- a/mapping_provider/backends/services.py +++ b/mapping_provider/backends/services.py @@ -7,24 +7,14 @@ logger = logging.getLogger(__name__) class Endpoint(BaseModel): - hostname: str + equipment: str interface: str - @classmethod - def from_inprov_endpoint(cls, endpoint: dict[str, Any]) -> 'Endpoint': - return cls( - hostname = endpoint['hostname'], - interface = endpoint['interface'], - ) class Overlays(BaseModel): speed: int + up: bool - @classmethod - def from_inprov_overlays(cls, overlays: dict[str, Any]) -> 'Overlays': - return cls( - speed = overlays['speed'], - ) class Service(BaseModel): sid: str @@ -38,28 +28,64 @@ class ServiceList(BaseModel): services: list[Service] -def _services() -> Generator[Service, None, None]: +def _services(service_type: str | None = None) -> Generator[Service, None, None]: + """ + load the cached backend data and yield map service records + + only return operational services that match the service type, if provided + """ + # TOOD: maybe remove loading of inventory/poller/interfaces & /map/services try: - inprov_map_services = cache.get(inventory.INPROV_MAP_SERVICES_CACHE_FILENAME) + # inprov_map_services = cache.get(inventory.INPROV_MAP_SERVICES_CACHE_FILENAME) scid_current = cache.get(inventory.REPORTING_SCID_CURRENT_CACHE_FILENAME) - poller_interfaces = cache.get(inventory.INPROV_POLLER_INTERFACES_CACHE_FILENAME) + # poller_interfaces = cache.get(inventory.INPROV_POLLER_INTERFACES_CACHE_FILENAME) correlator_state = cache.get(correlator.CACHED_CORRELATOR_STATE_FILENAME) except FileNotFoundError: logger.exception('not enough data available to build the service list') return - - for service in inprov_map_services: - overlays = Overlays(speed = service['overlays']['speed']) - endpoints = list(map(Endpoint.from_inprov_endpoint, service['endpoints'])) + def _get_down_correlator_services(): + for _e in correlator_state['endpoints']: + if _e['up']: + continue + for _s in _e['services']: + if 'sid' in _s: + yield _s['sid'] + + + down_service_sids = set(_get_down_correlator_services()) + + for _s in scid_current: + + if _s['status'] != 'operational': + continue + + if service_type and _s['service_type'] != service_type: + continue + + overlays = Overlays( + speed = _s['speed'], + up = _s['sid'] not in down_service_sids, + ) + + endpoints = [] + for _e in _s['endpoints']: + equipment = _e['hostname'] if 'hostname' in _e else _e['equipment'] + interface = _e['interface'] if 'interface' in _e else _e['port'] + endpoints.append(Endpoint(equipment=equipment, interface=interface)) + yield Service( - sid = service['sid'], - name = service['name'], - type = service['type'], + sid = _s['sid'], + scid = _s['scid'], + name = _s['name'], + type = _s['service_type'], endpoints = endpoints, overlays = overlays, ) -def build_service_info_list() -> ServiceList: - return ServiceList(services=_services()) +def build_service_info_list(service_type: str | None = None) -> ServiceList: + """ + return a list of mappable info about all operational services + """ + return ServiceList(services=_services(service_type)) diff --git a/test/conftest.py b/test/conftest.py index 512fb7a15f9d46c714259b65f510622be783e0e4..ee017fe6146c15d098e425afc406feadbf96ab09 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -47,8 +47,9 @@ def client(dummy_config_filename): os.environ['SETTINGS_FILENAME'] = dummy_config_filename with tempfile.TemporaryDirectory() as tmp_dir: - cache.init(tmp_dir) # there's no rmq in config, so workers won't start + # there's no rmq in the test config data, so cache won't be initialized + cache.init(tmp_dir) cache.set(inventory.INPROV_MAP_SERVICES_CACHE_FILENAME, load_test_data('inprov-services.json')) cache.set(inventory.REPORTING_SCID_CURRENT_CACHE_FILENAME, load_test_data('scid-current.json')) cache.set(inventory.INPROV_POLLER_INTERFACES_CACHE_FILENAME, load_test_data('poller-interfaces.json'))