From 22224547a5aeaa4e45eba78d1e5cdaf69adceb57 Mon Sep 17 00:00:00 2001 From: "saket.agrahari" <saket.agrahari@geant.org> Date: Wed, 27 Mar 2024 10:07:44 +0000 Subject: [PATCH] [DBOARD3-676]: creating new api for mic third party data --- inventory_provider/routes/mic.py | 84 +++++++++++++++++++++++++++ inventory_provider/tasks/worker.py | 92 +++++++++++++++++++++++++++++- 2 files changed, 173 insertions(+), 3 deletions(-) diff --git a/inventory_provider/routes/mic.py b/inventory_provider/routes/mic.py index 8ee62dee..13e9fd21 100644 --- a/inventory_provider/routes/mic.py +++ b/inventory_provider/routes/mic.py @@ -68,6 +68,76 @@ ALL_DATA_SCHEMA = { "additionalProperties": False } +THIRD_PARTY_RESPONSE_SCHEMA ={ + "schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "circuit_hierarchy": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": {"type": "integer"}, + "status": {"type": "string"}, + "name": {"type": "string"}, + "service_type": {"type": "string"}, + "contacts": { + "type": "array", + "items": {"type": "string"} + }, + "planned_work_contacts": { + "type": "array", + "items": {"type": "string"} + }, + "third_party_id": {"type": "string"} + }, + "required": ["id", "status", "name", "service_type", "contacts", "planned_work_contacts", "third_party_id"], + "additionalProperties": False + } + }, + "interface_services": { + "type": "object", + "patternProperties": { + "^.*$": { + "type": "object", + "patternProperties": { + "^.*$": { + "type": "object", + "patternProperties": { + "^.*$": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": {"type": "integer"}, + "sid": {"type": "string"}, + "status": {"type": "string"}, + "name": {"type": "string"}, + "service_type": {"type": "string"}, + "contacts": { + "type": "array", + "items": {"type": "string"} + }, + "planned_work_contacts": { + "type": "array", + "items": {"type": "string"} + }, + "third_party_id": {"type": "string"} + }, + "required": ["id", "sid", "status", "name", "service_type", "contacts", "planned_work_contacts", "third_party_id"], + "additionalProperties": False + } + } + } + } + } + } + } + } + }, + "required": ["circuit_hierarchy", "interface_services"], + "additionalProperties": False +} @routes.route("/all-data") def get_everything(): @@ -81,3 +151,17 @@ def get_everything(): status=404, mimetype="text/html") return Response(result, mimetype='application/json') + + +@routes.route("/third-party-data") +def get_third_party_data(): + cache_key = "mic:impact:third-party-data" + logger.debug(cache_key) + r = common.get_current_redis() + result = _ignore_cache_or_retrieve(request, cache_key, r) + if not result: + return Response( + response='no data found', + status=404, + mimetype="text/html") + return Response(result, mimetype='application/json') diff --git a/inventory_provider/tasks/worker.py b/inventory_provider/tasks/worker.py index 4c77d0d7..1cf01456 100644 --- a/inventory_provider/tasks/worker.py +++ b/inventory_provider/tasks/worker.py @@ -1226,6 +1226,9 @@ def transform_ims_data(data): d['contacts'] = sorted(list(c)) d['planned_work_contacts'] = sorted(list(ttc)) + if d['id'] in circuit_ids_and_third_party_ids: + d['third_party_id'] = circuit_ids_and_third_party_ids[d['id']] + # add flexils data to port_id_details and port_id_services all_ils_details = flexils_data.get(d['id']) if all_ils_details: @@ -1321,9 +1324,6 @@ def transform_ims_data(data): if c['id'] in circuit_ids_and_sids: rs[c['id']]['sid'] = circuit_ids_and_sids[c['id']] - if c['id'] in circuit_ids_and_third_party_ids: - rs[c['id']]['third_party_id'] = circuit_ids_and_third_party_ids[c['id']] - if c['sub-circuits']: for sub in c['sub-circuits']: temp_parents = \ @@ -1578,6 +1578,7 @@ def persist_ims_data(data, use_current=False): populate_poller_cache(interface_services, r) populate_mic_cache(interface_services, r) + populate_mic_with_third_party_data(interface_services, hierarchy, r) for service_type, services in services_by_type.items(): for v in services.values(): @@ -1612,6 +1613,91 @@ def persist_ims_data(data, use_current=False): rp.execute() +def populate_mic_with_third_party_data(interface_services, hierarchy, r): + cache_key = "mic:impact:third-party-data" + third_party_data = defaultdict(lambda: defaultdict(dict)) + third_party_interface_data = defaultdict(lambda: defaultdict(dict)) + + def _get_formatted_third_party_data(_circuit_data): + if _circuit_data['status'] == 'operational' and _circuit_data.get('third_party_id'): + return { + 'id': _circuit_data['id'], + 'status': _circuit_data['status'], + 'name': _circuit_data['name'], + 'service_type': 'circuit_hierarchy', + 'contacts': _circuit_data['contacts'], + 'planned_work_contacts': _circuit_data['planned_work_contacts'], + 'third_party_id': _circuit_data['third_party_id'], + } + + def _get_formatted_related_service(_d): + for rs in _d['related-services']: + if rs['status'] == 'operational' and rs.get('third_party_id'): + yield { + 'id': rs['id'], + 'sid': rs.get('sid', ''), + 'status': rs['status'], + 'name': rs['name'], + 'service_type': rs['service_type'], + 'contacts': rs['contacts'], + 'planned_work_contacts': rs['planned_work_contacts'], + 'third_party_id': rs.get('third_party_id', '') + } + + def _get_formatted_interface_service(_is): + if _is['status'] == 'operational' and _is.get('third_party_id'): + return { + 'id': _is['id'], + 'sid': _is.get('sid', ''), + 'status': _is['status'], + 'name': _is['name'], + 'service_type': 'circuit_type', + 'contacts': _is['contacts'], + 'planned_work_contacts': _is['planned_work_contacts'], + 'third_party_id': _is.get('third_party_id', '') + } + + # get circuit hierarchy items that have third party id + third_party_circuit = { + k: v for k, v in hierarchy.items() if 'third_party_id' in v + } + + # iterate over each third_party_circuit items to format and add operational once only + third_party_circuit_data = [_get_formatted_third_party_data(v) + for k, v in third_party_circuit.items() + if v and _get_formatted_third_party_data(v)] + + # add third_party_circuit_data to the third_party_data map and add the map to cache + third_party_data['circuit_hierarchy'] = third_party_circuit_data + + for services in interface_services.values(): + if services: + current_interface_services = [] + seen_ids = set() + for d in services: + if d.get('related-services'): + for rs in _get_formatted_related_service(d): + if rs['id'] not in seen_ids: + current_interface_services.append(rs) + seen_ids.add(rs['id']) + if (str(d.get('id')) + 'circuit') not in seen_ids: + _is = _get_formatted_interface_service(d) + if _is: + current_interface_services.append(_is) + seen_ids.add(str(d.get('id')) + 'circuit') + + if current_interface_services: + site = f'{services[0]["pop_name"]} ' \ + f'({services[0]["pop_abbreviation"]})' + eq_name = services[0]['equipment'] + if_name = services[0]['port'] + third_party_interface_data[site][eq_name][if_name] = current_interface_services + third_party_data['interface_services'] = third_party_interface_data + + result = json.dumps(third_party_data) + r.set(cache_key, result.encode('utf-8')) + + def populate_mic_cache(interface_services, r): cache_key = "mic:impact:all-data" all_data = defaultdict(lambda: defaultdict(dict)) -- GitLab