From 585842daad2f6081b48b68b76c163e9ec76c64de Mon Sep 17 00:00:00 2001 From: Erik Reid <erik.reid@geant.org> Date: Fri, 12 Apr 2019 15:56:08 +0200 Subject: [PATCH] moved some parsing into coriant classifier handler --- inventory_provider/routes/classifier.py | 42 ++++++++++++++++--------- test/test_classifier_routes.py | 32 +++++++++++++------ 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/inventory_provider/routes/classifier.py b/inventory_provider/routes/classifier.py index 0cfac3b4..90b8d9da 100644 --- a/inventory_provider/routes/classifier.py +++ b/inventory_provider/routes/classifier.py @@ -1,5 +1,6 @@ import ipaddress import json +import logging import re from flask import Blueprint, Response, current_app @@ -9,6 +10,8 @@ from inventory_provider.db import opsdb, db routes = Blueprint("inventory-data-classifier-support-routes", __name__) +logger = logging.getLogger(__name__) + class ClassifierRequestError(Exception): status_code = 500 @@ -280,37 +283,46 @@ def get_trap_metadata(source_equipment, interface, circuit_id): return Response(result, mimetype="application/json") -@routes.route("/coriant-info/" - "<equipment_name>/<card_id>/<port_number>", +@routes.route('/coriant-info/<equipment_name>/<path:entity_string>', methods=['GET', 'POST']) @common.require_accepts_json -def get_coriant_info(equipment_name, card_id, port_number): +def get_coriant_info(equipment_name, entity_string): r = common.get_redis() - cache_key = 'classifier-cache:coriant:%s:%s:%s' % ( - equipment_name, card_id, port_number) + cache_key = 'classifier-cache:coriant:%s:%s' % ( + equipment_name, entity_string) result = r.get(cache_key) if result: result = result.decode('utf-8') else: + m = re.match(r'^(\d+\-\d+)\.(\d+)', entity_string) + if not m: + logger.warning( + 'invalid coriant entity string format: %r' % entity_string) + return Response( + response="no available info for '{}' '{}'".format( + equipment_name, entity_string), + status=404, + mimetype="text/html") + result = { + 'equipment name': equipment_name, + 'card id': m.group(1), + 'port number': m.group(2) + } + config = current_app.config['INVENTORY_PROVIDER_CONFIG'] with db.connection(config['ops-db']) as cx: path = opsdb.lookup_coriant_path( - cx, equipment_name, card_id, port_number) + cx, equipment_name, result['card id'], result['port number']) - if not path: - return Response( - response="no available info for {} {} {}".format( - equipment_name, card_id, port_number), - status=404, - mimetype="text/html") - - result = json.dumps({'path': path}) + if path: + result['path'] = path # cache this data for the next call - r.set(cache_key, result.encode('utf-8')) + result = json.dumps(result).encode('utf-8') + r.set(cache_key, result) return Response(result, mimetype="application/json") diff --git a/test/test_classifier_routes.py b/test/test_classifier_routes.py index 413565fd..65aca5f9 100644 --- a/test/test_classifier_routes.py +++ b/test/test_classifier_routes.py @@ -278,16 +278,14 @@ def test_coriant_info(client, mocker): """ just check the correct method is called, but mock out all sql access """ - expected_path = { - 'C': 'bogus connection', - 'E': 'bogus equipment name', - 'CID': 'bogus card id', - 'P': 'bogus card number' - } + CONNECTION = 'bogus connection' + EQUIPMENT = 'bogus equipment name' + CARD_ID = '123-456' + PORT_NUMBER = '789' @contextlib.contextmanager def mocked_connection(ignored): - yield expected_path['C'] + yield CONNECTION mocker.patch( 'inventory_provider.db.db.connection', mocked_connection) @@ -296,14 +294,28 @@ def test_coriant_info(client, mocker): lambda a, b, c, d: {'C': a, 'E': b, 'CID': c, 'P': d}) rv = client.get( - '/classifier/coriant-info/{E}/{CID}/{P}'.format(**expected_path), + '/classifier/coriant-info/{eq}/{cid}.{pn}abc.234 af/23'.format( + eq=EQUIPMENT, + cid=CARD_ID, + pn=PORT_NUMBER), headers=DEFAULT_REQUEST_HEADERS) assert rv.status_code == 200 assert rv.is_json response_data = json.loads(rv.data.decode('utf-8')) - expected_response = {'path': expected_path} + expected_response = { + 'equipment name': EQUIPMENT, + 'card id': CARD_ID, + 'port number': PORT_NUMBER, + 'path': { + 'C': CONNECTION, + 'E': EQUIPMENT, + 'CID': CARD_ID, + 'P': PORT_NUMBER + } + } + assert response_data == expected_response @@ -323,7 +335,7 @@ def test_coriant_info_not_found(client, mocker): lambda a, b, c, d: None) rv = client.get( - '/classifier/coriant-info/aaa/bbb/ccc', + '/classifier/coriant-info/aaa/unparseableentitystring', headers=DEFAULT_REQUEST_HEADERS) assert rv.status_code == 404 -- GitLab