From d4922c476a7f191b716ee68f6696d466125eb51e Mon Sep 17 00:00:00 2001 From: JFrgs Date: Fri, 3 Mar 2023 17:20:20 +0200 Subject: [PATCH 1/7] avoid db connections within the threads fixes on Makefile --- Makefile | 7 +- .../app/api/api_v1/endpoints/ue_movement.py | 131 ++++++++++-------- 2 files changed, 75 insertions(+), 63 deletions(-) diff --git a/Makefile b/Makefile index 60a25378..3a21037a 100644 --- a/Makefile +++ b/Makefile @@ -35,8 +35,11 @@ build: build-no-cache: docker compose --profile debug build --no-cache --pull -logs: - docker compose logs -f +logs-dev: + docker compose --profile dev logs -f + +logs-debug: + docker compose --profile debug logs -f logs-backend: docker compose logs -f backend diff --git a/backend/app/app/api/api_v1/endpoints/ue_movement.py b/backend/app/app/api/api_v1/endpoints/ue_movement.py index b754f8cf..010093ea 100644 --- a/backend/app/app/api/api_v1/endpoints/ue_movement.py +++ b/backend/app/app/api/api_v1/endpoints/ue_movement.py @@ -10,6 +10,7 @@ from app.api import deps from app.schemas import Msg from app.tools import monitoring_callbacks, timer +from sqlalchemy.orm import Session #Dictionary holding threads that are running per user id. threads = {} @@ -24,14 +25,18 @@ def __init__(self, group=None, target=None, name=None, args=(), kwargs=None): self._args = args self._kwargs = kwargs self._stop_threads = False - self._db = SessionLocal() return def run(self): + db_mongo = client.fastapi + current_user = self._args[0] supi = self._args[1] - + json_cells = self._args[2] + points = self._args[3] + is_superuser = self._args[4] + active_subscriptions = { "location_reporting" : False, "ue_reachability" : False, @@ -40,57 +45,12 @@ def run(self): } try: - db_mongo = client.fastapi - - #Initiate UE - if exists - UE = crud.ue.get_supi(db=self._db, supi=supi) - if not UE: - logging.warning("UE not found") - threads.pop(f"{supi}") - return - if (UE.owner_id != current_user.id): - logging.warning("Not enough permissions") - threads.pop(f"{supi}") - return - #Insert running UE in the dictionary - - global ues - ues[f"{supi}"] = jsonable_encoder(UE) - ues[f"{supi}"].pop("id") - - if UE.Cell_id != None: - ues[f"{supi}"]["cell_id_hex"] = UE.Cell.cell_id - ues[f"{supi}"]["gnb_id_hex"] = UE.Cell.gNB.gNB_id - else: - ues[f"{supi}"]["cell_id_hex"] = None - ues[f"{supi}"]["gnb_id_hex"] = None - - - #Retrieve paths & points - path = crud.path.get(db=self._db, id=UE.path_id) - if not path: - logging.warning("Path not found") - threads.pop(f"{supi}") - return - if (path.owner_id != current_user.id): - logging.warning("Not enough permissions") - threads.pop(f"{supi}") - return - - points = crud.points.get_points(db=self._db, path_id=UE.path_id) - points = jsonable_encoder(points) - - #Retrieve all the cells - Cells = crud.cell.get_multi_by_owner(db=self._db, owner_id=current_user.id, skip=0, limit=100) - json_cells = jsonable_encoder(Cells) - - is_superuser = crud.user.is_superuser(current_user) - t = timer.SequencialTimer(logger=logging.critical) rt = None # global loss_of_connectivity_ack loss_of_connectivity_ack = "FALSE" + ''' =================================================================== 2nd Approach for updating UEs position @@ -125,7 +85,7 @@ def run(self): # find the index of the point where the UE is located for index, point in enumerate(points): - if (UE.latitude == point["latitude"]) and (UE.longitude == point["longitude"]): + if (ues[f"{supi}"]["latitude"] == point["latitude"]) and (ues[f"{supi}"]["longitude"] == point["longitude"]): current_position_index = index # start iterating from this index and keep increasing the moving_position_index... @@ -145,7 +105,7 @@ def run(self): #MonitoringEvent API - Loss of connectivity if not active_subscriptions.get("loss_of_connectivity"): - loss_of_connectivity_sub = crud_mongo.read_by_multiple_pairs(db_mongo, "MonitoringEvent", externalId = UE.external_identifier, monitoringType = "LOSS_OF_CONNECTIVITY") + loss_of_connectivity_sub = crud_mongo.read_by_multiple_pairs(db_mongo, "MonitoringEvent", externalId = ues[f"{supi}"]["external_identifier"], monitoringType = "LOSS_OF_CONNECTIVITY") if loss_of_connectivity_sub: active_subscriptions.update({"loss_of_connectivity" : True}) @@ -183,7 +143,7 @@ def run(self): #As Session With QoS API - search for active subscription in db if not active_subscriptions.get("as_session_with_qos"): - qos_sub = crud_mongo.read(db_mongo, 'QoSMonitoring', 'ipv4Addr', UE.ip_address_v4) + qos_sub = crud_mongo.read(db_mongo, 'QoSMonitoring', 'ipv4Addr', ues[f"{supi}"]["ip_address_v4"]) if qos_sub: active_subscriptions.update({"as_session_with_qos" : True}) reporting_freq = qos_sub["qosMonInfo"]["repFreqs"] @@ -218,7 +178,7 @@ def run(self): if ues[f"{supi}"]["Cell_id"] == None: if not active_subscriptions.get("ue_reachability"): - ue_reachability_sub = crud_mongo.read_by_multiple_pairs(db_mongo, "MonitoringEvent", externalId = UE.external_identifier, monitoringType = "UE_REACHABILITY") + ue_reachability_sub = crud_mongo.read_by_multiple_pairs(db_mongo, "MonitoringEvent", externalId = ues[f"{supi}"]["external_identifier"], monitoringType = "UE_REACHABILITY") if ue_reachability_sub: active_subscriptions.update({"ue_reachability" : True}) @@ -251,14 +211,13 @@ def run(self): # logging.warning(f"UE({UE.supi}) with ipv4 {UE.ip_address_v4} handovers to Cell {cell_now.get('id')}, {cell_now.get('description')}") ues[f"{supi}"]["Cell_id"] = cell_now.get('id') ues[f"{supi}"]["cell_id_hex"] = cell_now.get('cell_id') - gnb = crud.gnb.get(db=self._db, id=cell_now.get("gNB_id")) - ues[f"{supi}"]["gnb_id_hex"] = gnb.gNB_id + ues[f"{supi}"]["gnb_id_hex"] = cell_now.get('cell_id')[:6] #Monitoring Event API - Location Reporting #Retrieve the subscription of the UE by external Id | This could be outside while true but then the user cannot subscribe when the loop runs if not active_subscriptions.get("location_reporting"): - location_reporting_sub = crud_mongo.read_by_multiple_pairs(db_mongo, "MonitoringEvent", externalId = UE.external_identifier, monitoringType = "LOCATION_REPORTING") + location_reporting_sub = crud_mongo.read_by_multiple_pairs(db_mongo, "MonitoringEvent", externalId = ues[f"{supi}"]["external_identifier"], monitoringType = "LOCATION_REPORTING") if location_reporting_sub: active_subscriptions.update({"location_reporting" : True}) @@ -309,10 +268,10 @@ def run(self): # logging.info(f'User: {current_user.id} | UE: {supi} | Current location: latitude ={UE.latitude} | longitude = {UE.longitude} | Speed: {UE.speed}' ) - if UE.speed == 'LOW': + if ues[f"{supi}"]["speed"] == 'LOW': # don't skip any points, keep default speed 1m /sec moving_position_index += 1 - elif UE.speed == 'HIGH': + elif ues[f"{supi}"]["speed"] == 'HIGH': # skip 10 points --> 10m / sec moving_position_index += 10 @@ -323,10 +282,13 @@ def run(self): if self._stop_threads: logging.critical("Terminating thread...") - crud.ue.update_coordinates(db=self._db, lat=ues[f"{supi}"]["latitude"], long=ues[f"{supi}"]["longitude"], db_obj=UE) - crud.ue.update(db=self._db, db_obj=UE, obj_in={"Cell_id" : ues[f"{supi}"]["Cell_id"]}) + logging.critical("Updating UE with the latest coordinates and cell in the database (last known position)...") + db = SessionLocal() + UE = crud.ue.get_supi(db, supi) + crud.ue.update_coordinates(db=db, lat=ues[f"{supi}"]["latitude"], long=ues[f"{supi}"]["longitude"], db_obj=UE) + crud.ue.update(db=db, db_obj=UE, obj_in={"Cell_id" : ues[f"{supi}"]["Cell_id"]}) ues.pop(f"{supi}") - self._db.close() + db.close() if rt is not None: rt.stop() break @@ -403,13 +365,60 @@ def initiate_movement( *, msg: Msg, current_user: models.User = Depends(deps.get_current_active_user), + db: Session = Depends(deps.get_db) ) -> Any: """ Start the loop. """ if msg.supi in threads: raise HTTPException(status_code=409, detail=f"There is a thread already running for this supi:{msg.supi}") - t = BackgroundTasks(args= (current_user, msg.supi, )) + + #Check if UE + UE = crud.ue.get_supi(db=db, supi=msg.supi) + if not UE: + logging.warning("UE not found") + threads.pop(f"{msg.supi}") + return + if (UE.owner_id != current_user.id): + logging.warning("Not enough permissions") + threads.pop(f"{msg.supi}") + return + + #Insert running UE in the dictionary + + global ues + ues[f"{msg.supi}"] = jsonable_encoder(UE) + ues[f"{msg.supi}"].pop("id") + + if UE.Cell_id != None: + ues[f"{msg.supi}"]["cell_id_hex"] = UE.Cell.cell_id + ues[f"{msg.supi}"]["gnb_id_hex"] = UE.Cell.gNB.gNB_id + else: + ues[f"{msg.supi}"]["cell_id_hex"] = None + ues[f"{msg.supi}"]["gnb_id_hex"] = None + + + #Retrieve paths & points + path = crud.path.get(db=db, id=UE.path_id) + if not path: + logging.warning("Path not found") + threads.pop(f"{msg.supi}") + return + if (path.owner_id != current_user.id): + logging.warning("Not enough permissions") + threads.pop(f"{msg.supi}") + return + + points = crud.points.get_points(db=db, path_id=UE.path_id) + points = jsonable_encoder(points) + + #Retrieve all the cells + Cells = crud.cell.get_multi_by_owner(db=db, owner_id=current_user.id, skip=0, limit=100) + json_cells = jsonable_encoder(Cells) + + is_superuser = crud.user.is_superuser(current_user) + + t = BackgroundTasks(args= (current_user, msg.supi, json_cells, points, is_superuser)) threads[f"{msg.supi}"] = {} threads[f"{msg.supi}"][f"{current_user.id}"] = t t.start() From e91ed0c4e00c5fda6f49b738d0501e2a954a4e0e Mon Sep 17 00:00:00 2001 From: Anastasios Gogos <13665570+tgogos@users.noreply.github.com> Date: Thu, 6 Apr 2023 16:29:46 +0300 Subject: [PATCH 2/7] fix token causing 403 errors --- backend/app/app/static/js/dashboard-cells.js | 4 ++-- backend/app/app/static/js/dashboard-paths.js | 4 ++-- backend/app/app/static/js/dashboard-ues.js | 4 ++-- backend/app/app/static/js/map.js | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/app/app/static/js/dashboard-cells.js b/backend/app/app/static/js/dashboard-cells.js index 235fe794..2eda3504 100644 --- a/backend/app/app/static/js/dashboard-cells.js +++ b/backend/app/app/static/js/dashboard-cells.js @@ -566,7 +566,7 @@ function ui_initialize_edit_cell_map() { var mbAttr = 'Map data © OpenStreetMap contributors, ' + 'Imagery © Mapbox', - mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw'; + mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); @@ -602,7 +602,7 @@ function ui_initialize_add_cell_map() { var mbAttr = 'Map data © OpenStreetMap contributors, ' + 'Imagery © Mapbox', - mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw'; + mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); diff --git a/backend/app/app/static/js/dashboard-paths.js b/backend/app/app/static/js/dashboard-paths.js index 65e7a9cd..11983d17 100644 --- a/backend/app/app/static/js/dashboard-paths.js +++ b/backend/app/app/static/js/dashboard-paths.js @@ -562,7 +562,7 @@ function ui_initialize_edit_path_map() { var mbAttr = 'Map data © OpenStreetMap contributors, ' + 'Imagery © Mapbox', - mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw'; + mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); @@ -597,7 +597,7 @@ function ui_initialize_add_path_map() { var mbAttr = 'Map data © OpenStreetMap contributors, ' + 'Imagery © Mapbox', - mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw'; + mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); diff --git a/backend/app/app/static/js/dashboard-ues.js b/backend/app/app/static/js/dashboard-ues.js index 05359eeb..5ef371ef 100644 --- a/backend/app/app/static/js/dashboard-ues.js +++ b/backend/app/app/static/js/dashboard-ues.js @@ -614,7 +614,7 @@ function ui_initialize_edit_UE_map() { var mbAttr = 'Map data © OpenStreetMap contributors, ' + 'Imagery © Mapbox', - mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw'; + mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); @@ -652,7 +652,7 @@ function ui_initialize_add_UE_map() { var mbAttr = 'Map data © OpenStreetMap contributors, ' + 'Imagery © Mapbox', - mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw'; + mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); diff --git a/backend/app/app/static/js/map.js b/backend/app/app/static/js/map.js index 04547180..fc74e791 100644 --- a/backend/app/app/static/js/map.js +++ b/backend/app/app/static/js/map.js @@ -274,7 +274,7 @@ function ui_initialize_map() { var mbAttr = 'Map data © OpenStreetMap contributors, ' + 'Imagery © Mapbox', - mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw'; + mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); From 3284e117e0c8e5a31441c679dd63dc3f8b6c0091 Mon Sep 17 00:00:00 2001 From: Anastasios Gogos <13665570+tgogos@users.noreply.github.com> Date: Thu, 6 Apr 2023 17:35:44 +0300 Subject: [PATCH 3/7] add tileLayer: OpenStreetMap --- backend/app/app/static/js/dashboard-cells.js | 22 ++- backend/app/app/static/js/dashboard-paths.js | 22 ++- backend/app/app/static/js/dashboard-ues.js | 22 ++- backend/app/app/static/js/map.js | 198 ++++++++++++++----- 4 files changed, 198 insertions(+), 66 deletions(-) diff --git a/backend/app/app/static/js/dashboard-cells.js b/backend/app/app/static/js/dashboard-cells.js index 2eda3504..dcf1089d 100644 --- a/backend/app/app/static/js/dashboard-cells.js +++ b/backend/app/app/static/js/dashboard-cells.js @@ -568,8 +568,14 @@ function ui_initialize_edit_cell_map() { 'Imagery © Mapbox', mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; + var osAttr = '© OpenStreetMap', + osUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; + + + var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), - streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); + streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), + osm = L.tileLayer(osUrl, { tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); // map initialization @@ -580,7 +586,8 @@ function ui_initialize_edit_cell_map() { var baseLayers = { "Grayscale": grayscale, - "Streets": streets + "Streets": streets, + 'OpenStreetMap': osm }; var overlays = { @@ -604,8 +611,14 @@ function ui_initialize_add_cell_map() { 'Imagery © Mapbox', mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; + var osAttr = '© OpenStreetMap', + osUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; + + + var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), - streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); + streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), + osm = L.tileLayer(osUrl, { tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); // map initialization @@ -616,7 +629,8 @@ function ui_initialize_add_cell_map() { var baseLayers = { "Grayscale": grayscale, - "Streets": streets + "Streets": streets, + 'OpenStreetMap': osm }; var overlays = { diff --git a/backend/app/app/static/js/dashboard-paths.js b/backend/app/app/static/js/dashboard-paths.js index 11983d17..eee03012 100644 --- a/backend/app/app/static/js/dashboard-paths.js +++ b/backend/app/app/static/js/dashboard-paths.js @@ -564,8 +564,14 @@ function ui_initialize_edit_path_map() { 'Imagery © Mapbox', mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; + var osAttr = '© OpenStreetMap', + osUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; + + + var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), - streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); + streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), + osm = L.tileLayer(osUrl, { tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); // map initialization @@ -576,7 +582,8 @@ function ui_initialize_edit_path_map() { var baseLayers = { "Grayscale": grayscale, - "Streets": streets + "Streets": streets, + 'OpenStreetMap': osm }; var overlays = { @@ -599,8 +606,14 @@ function ui_initialize_add_path_map() { 'Imagery © Mapbox', mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; + var osAttr = '© OpenStreetMap', + osUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; + + + var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), - streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); + streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), + osm = L.tileLayer(osUrl, { tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); // map initialization @@ -611,7 +624,8 @@ function ui_initialize_add_path_map() { var baseLayers = { "Grayscale": grayscale, - "Streets": streets + "Streets": streets, + 'OpenStreetMap': osm }; var overlays = { diff --git a/backend/app/app/static/js/dashboard-ues.js b/backend/app/app/static/js/dashboard-ues.js index 5ef371ef..27b18cd9 100644 --- a/backend/app/app/static/js/dashboard-ues.js +++ b/backend/app/app/static/js/dashboard-ues.js @@ -616,8 +616,14 @@ function ui_initialize_edit_UE_map() { 'Imagery © Mapbox', mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; + var osAttr = '© OpenStreetMap', + osUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; + + + var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), - streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); + streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), + osm = L.tileLayer(osUrl, { tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); // map initialization @@ -628,7 +634,8 @@ function ui_initialize_edit_UE_map() { var baseLayers = { "Grayscale": grayscale, - "Streets": streets + "Streets": streets, + 'OpenStreetMap': osm }; var overlays = { @@ -654,8 +661,14 @@ function ui_initialize_add_UE_map() { 'Imagery © Mapbox', mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; + var osAttr = '© OpenStreetMap', + osUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; + + + var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), - streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); + streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), + osm = L.tileLayer(osUrl, { tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); // map initialization @@ -666,7 +679,8 @@ function ui_initialize_add_UE_map() { var baseLayers = { "Grayscale": grayscale, - "Streets": streets + "Streets": streets, + 'OpenStreetMap': osm }; var overlays = { diff --git a/backend/app/app/static/js/map.js b/backend/app/app/static/js/map.js index fc74e791..06a9790e 100644 --- a/backend/app/app/static/js/map.js +++ b/backend/app/app/static/js/map.js @@ -12,6 +12,8 @@ var paths = null; var moving_ues = null; +var UEs_first_paint = true; + // variables used for painting / updating the map // map layer groups @@ -84,35 +86,36 @@ $( document ).ready(function() { wait_for_UEs_data(); else { // when ready, - // 1. get and paint every path per UE - // 2. create start/stop buttons - for (const ue of ues) { + // // 1. get and paint every path per UE + // // 2. create start/stop buttons + // for (const ue of ues) { - // if no path selected, skip map paint and creation of button - if (ue.path_id == 0) { continue; } + // // if no path selected, skip map paint and creation of button + // if (ue.path_id == 0) { continue; } - // if not already fetched and painted, do so - if ( !helper_check_path_is_already_painted( ue.path_id ) ) { - api_get_specific_path(ue.path_id); - paths_painted[ue.path_id] = true; - } - ui_generate_loop_btn_for( ue ); - ui_set_loop_btn_status_for( ue ); - } + // // if not already fetched and painted, do so + // if ( !helper_check_path_is_already_painted( ue.path_id ) ) { + // api_get_specific_path(ue.path_id); + // paths_painted[ue.path_id] = true; + // } + // ui_generate_loop_btn_for( ue ); + // ui_set_loop_btn_status_for( ue ); + // } if ( ues.length >0 ) { - ui_add_ue_btn_listeners(); - ui_add_ue_all_btn_listener(); - } - else { - $('#btn-start-all').removeClass("btn-success").addClass("btn-secondary").attr("disabled",true); - } - - // edge case: UEs with no paths assigned --> disable button - if (paths_painted.length == 0) { - $('#btn-start-all').removeClass("btn-success").addClass("btn-secondary").attr("disabled",true); + // ui_add_ue_btn_listeners(); + // ui_add_ue_all_btn_listener(); + start_map_refresh_interval(); } + // else { + // $('#btn-start-all').removeClass("btn-success").addClass("btn-secondary").attr("disabled",true); + // } + + // // edge case: UEs with no paths assigned --> disable button + // if (paths_painted.length == 0) { + // $('#btn-start-all').removeClass("btn-success").addClass("btn-secondary").attr("disabled",true); + // } } }, 100); }; @@ -156,7 +159,7 @@ function start_map_refresh_interval() { if (UE_refresh_interval == null) { if ( UE_refresh_sec == 0 ) { - $('.map-reload-select').prop("disabled",false); + // $('.map-reload-select').prop("disabled",false); return; } @@ -167,11 +170,11 @@ function start_map_refresh_interval() { // start updating UE_refresh_interval = setInterval(function(){ - api_get_moving_UEs(); + api_get_UEs(); }, UE_refresh_sec); // enable the select button - $('.map-reload-select').prop("disabled",false); + // $('.map-reload-select').prop("disabled",false); $('.map-reload-select').val(UE_refresh_sec); } } @@ -183,7 +186,7 @@ function stop_map_refresh_interval() { UE_refresh_interval = null; // disable the select button - $('.map-reload-select').prop("disabled",true); + // $('.map-reload-select').prop("disabled",true); // UE_refresh_sec = 0; // $('.map-reload-select').val(0); } @@ -276,8 +279,14 @@ function ui_initialize_map() { 'Imagery © Mapbox', mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY2p0MG01MXRqMW45cjQzb2R6b2ptc3J4MSJ9.zA2W0IkI0c6KaAhJfk9bWg'; + var osAttr = '© OpenStreetMap', + osUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; + + + var grayscale = L.tileLayer(mbUrl, {id: 'mapbox/light-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), - streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); + streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}), + osm = L.tileLayer(osUrl, { tileSize: 512, zoomOffset: -1, attribution: mbAttr, maxZoom: 23}); // map initialization @@ -289,7 +298,8 @@ function ui_initialize_map() { var baseLayers = { "Grayscale": grayscale, - "Streets": streets + "Streets": streets, + 'OpenStreetMap': osm }; var overlays = { @@ -391,34 +401,114 @@ function ui_map_paint_UEs() { // console.log(ues); - for (const ue of ues) { - // create markers - this will be executed only once! - var walk_icon = L.divIcon({ - className: 'emu-pin-box', - iconSize: L.point(30,42), - iconAnchor: L.point(15,42), - popupAnchor: L.point(0,-38), - tooltipAnchor: L.point(0,0), - html: '
\ -
' - }); + // for (const ue of ues) { + // // create markers - this will be executed only once! + // var walk_icon = L.divIcon({ + // className: 'emu-pin-box', + // iconSize: L.point(30,42), + // iconAnchor: L.point(15,42), + // popupAnchor: L.point(0,-38), + // tooltipAnchor: L.point(0,0), + // html: '
\ + //
' + // }); - ue_markers[ue.supi] = L.marker([ue.latitude,ue.longitude], {icon: walk_icon}).addTo(mymap) - .bindTooltip(ue.ip_address_v4) - .bindPopup(""+ ue.name +"
"+ - // ue.description +"
"+ - "location: [" + ue.latitude.toFixed(6) + "," + ue.longitude.toFixed(6) +"]
"+ - "Cell ID: " + ( (ue.cell_id_hex==null)? "-" : ue.cell_id_hex ) +"
"+ - "External identifier: " + ue.external_identifier +"
"+ - "Speed:"+ ue.speed) - .addTo(ues_lg); // add to layer group + // ue_markers[ue.supi] = L.marker([ue.latitude,ue.longitude], {icon: walk_icon}).addTo(mymap) + // .bindTooltip(ue.ip_address_v4) + // .bindPopup(""+ ue.name +"
"+ + // // ue.description +"
"+ + // "location: [" + ue.latitude.toFixed(6) + "," + ue.longitude.toFixed(6) +"]
"+ + // "Cell ID: " + ( (ue.cell_id_hex==null)? "-" : ue.cell_id_hex ) +"
"+ + // "External identifier: " + ue.external_identifier +"
"+ + // "Speed:"+ ue.speed) + // .addTo(ues_lg); // add to layer group + + // // if ( ue.cell_id_hex==null ) { + // // L.DomUtil.addClass(ue_markers[ue.supi]._icon, 'null-cell'); + // // } else { + // // L.DomUtil.removeClass(ue_markers[ue.supi]._icon, 'null-cell'); + // // } + + // // update UE marker color + // temp_icon = L.DomUtil.get(ue_markers[ue.supi]._icon); + + // if (temp_icon == null) { + // // if the user has unchecked the UEs checkbox ✅ on the map settings + // // temp_icon is null and triggers console errors + // // if this is the case, continue... + // continue; + // } else { + // if ( ue.cell_id_hex==null ) { + // // 'null-cell' class gives a grey color + // // to UEs that are not connected to a cell + // L.DomUtil.addClass(temp_icon, 'null-cell'); + // } else { + // L.DomUtil.removeClass(temp_icon, 'null-cell'); + // } + // } + // } + for (const ue of ues) { + if (UEs_first_paint) { + // create markers - this will be executed only once! + var walk_icon = L.divIcon({ + className: 'emu-pin-box', + iconSize: L.point(30,42), + iconAnchor: L.point(15,42), + popupAnchor: L.point(0,-38), + tooltipAnchor: L.point(0,0), + html: '
\ +
' + }); + + ue_markers[ue.supi] = L.marker([ue.latitude,ue.longitude], {icon: walk_icon}).addTo(mymap) + .bindTooltip(ue.ip_address_v4) + .bindPopup(""+ ue.name +"
"+ + // ue.description +"
"+ + "location: [" + ue.latitude.toFixed(6) + "," + ue.longitude.toFixed(6) +"]
"+ + "Cell ID: " + ( (ue.cell_id_hex==null)? "-" : ue.cell_id_hex ) +"
"+ + "External identifier: " + ue.external_identifier +"
"+ + "Speed:"+ ue.speed) + .addTo(ues_lg); // add to layer group + + if ( ue.cell_id_hex==null ) { + L.DomUtil.addClass(ue_markers[ue.supi]._icon, 'null-cell'); + } else { + L.DomUtil.removeClass(ue_markers[ue.supi]._icon, 'null-cell'); + } - if ( ue.cell_id_hex==null ) { - L.DomUtil.addClass(ue_markers[ue.supi]._icon, 'null-cell'); - } else { - L.DomUtil.removeClass(ue_markers[ue.supi]._icon, 'null-cell'); + } + else { + // move existing markers + var newLatLng = [ue.latitude,ue.longitude]; + ue_markers[ue.supi].setLatLng(newLatLng); + ue_markers[ue.supi].setPopupContent(""+ ue.name +"
"+ + // ue.description +"
"+ + "location: [" + ue.latitude.toFixed(6) + "," + ue.longitude.toFixed(6) +"]
"+ + "Cell ID: " + ( (ue.cell_id_hex==null)? "-" : ue.cell_id_hex ) +"
"+ + "External identifier: " + ue.external_identifier +"
"+ + "Speed:"+ ue.speed); + + + // update UE marker color + temp_icon = L.DomUtil.get(ue_markers[ue.supi]._icon); + + if (temp_icon == null) { + // if the user has unchecked the UEs checkbox ✅ on the map settings + // temp_icon is null and triggers console errors + // if this is the case, continue... + continue; + } else { + if ( ue.cell_id_hex==null ) { + // 'null-cell' class gives a grey color + // to UEs that are not connected to a cell + L.DomUtil.addClass(temp_icon, 'null-cell'); + } else { + L.DomUtil.removeClass(temp_icon, 'null-cell'); + } + } } } + UEs_first_paint = false; } @@ -807,7 +897,7 @@ function ui_add_ue_btn_listeners(){ // start location UE loop api_start_loop({"supi":curr_supi}); - start_map_refresh_interval(); + $(this).data("running",true); $(this).removeClass('btn-success').addClass('btn-danger'); From 6a7abba069afa80b12e6ea066d10f528e40f60d8 Mon Sep 17 00:00:00 2001 From: Anastasios Gogos <13665570+tgogos@users.noreply.github.com> Date: Tue, 25 Apr 2023 14:40:44 +0300 Subject: [PATCH 4/7] restore map page functionality after wrong commit --- backend/app/app/static/js/map.js | 187 +++++++++---------------------- 1 file changed, 52 insertions(+), 135 deletions(-) diff --git a/backend/app/app/static/js/map.js b/backend/app/app/static/js/map.js index 06a9790e..a870d94c 100644 --- a/backend/app/app/static/js/map.js +++ b/backend/app/app/static/js/map.js @@ -12,8 +12,6 @@ var paths = null; var moving_ues = null; -var UEs_first_paint = true; - // variables used for painting / updating the map // map layer groups @@ -86,36 +84,35 @@ $( document ).ready(function() { wait_for_UEs_data(); else { // when ready, - // // 1. get and paint every path per UE - // // 2. create start/stop buttons - // for (const ue of ues) { + // 1. get and paint every path per UE + // 2. create start/stop buttons + for (const ue of ues) { - // // if no path selected, skip map paint and creation of button - // if (ue.path_id == 0) { continue; } + // if no path selected, skip map paint and creation of button + if (ue.path_id == 0) { continue; } - // // if not already fetched and painted, do so - // if ( !helper_check_path_is_already_painted( ue.path_id ) ) { - // api_get_specific_path(ue.path_id); - // paths_painted[ue.path_id] = true; - // } - // ui_generate_loop_btn_for( ue ); - // ui_set_loop_btn_status_for( ue ); - // } + // if not already fetched and painted, do so + if ( !helper_check_path_is_already_painted( ue.path_id ) ) { + api_get_specific_path(ue.path_id); + paths_painted[ue.path_id] = true; + } + ui_generate_loop_btn_for( ue ); + ui_set_loop_btn_status_for( ue ); + } if ( ues.length >0 ) { - // ui_add_ue_btn_listeners(); - // ui_add_ue_all_btn_listener(); - start_map_refresh_interval(); + ui_add_ue_btn_listeners(); + ui_add_ue_all_btn_listener(); + } + else { + $('#btn-start-all').removeClass("btn-success").addClass("btn-secondary").attr("disabled",true); + } + + // edge case: UEs with no paths assigned --> disable button + if (paths_painted.length == 0) { + $('#btn-start-all').removeClass("btn-success").addClass("btn-secondary").attr("disabled",true); } - // else { - // $('#btn-start-all').removeClass("btn-success").addClass("btn-secondary").attr("disabled",true); - // } - - // // edge case: UEs with no paths assigned --> disable button - // if (paths_painted.length == 0) { - // $('#btn-start-all').removeClass("btn-success").addClass("btn-secondary").attr("disabled",true); - // } } }, 100); }; @@ -159,7 +156,7 @@ function start_map_refresh_interval() { if (UE_refresh_interval == null) { if ( UE_refresh_sec == 0 ) { - // $('.map-reload-select').prop("disabled",false); + $('.map-reload-select').prop("disabled",false); return; } @@ -170,11 +167,11 @@ function start_map_refresh_interval() { // start updating UE_refresh_interval = setInterval(function(){ - api_get_UEs(); + api_get_moving_UEs(); }, UE_refresh_sec); // enable the select button - // $('.map-reload-select').prop("disabled",false); + $('.map-reload-select').prop("disabled",false); $('.map-reload-select').val(UE_refresh_sec); } } @@ -186,7 +183,7 @@ function stop_map_refresh_interval() { UE_refresh_interval = null; // disable the select button - // $('.map-reload-select').prop("disabled",true); + $('.map-reload-select').prop("disabled",true); // UE_refresh_sec = 0; // $('.map-reload-select').val(0); } @@ -401,114 +398,34 @@ function ui_map_paint_UEs() { // console.log(ues); - // for (const ue of ues) { - // // create markers - this will be executed only once! - // var walk_icon = L.divIcon({ - // className: 'emu-pin-box', - // iconSize: L.point(30,42), - // iconAnchor: L.point(15,42), - // popupAnchor: L.point(0,-38), - // tooltipAnchor: L.point(0,0), - // html: '
\ - //
' - // }); - - // ue_markers[ue.supi] = L.marker([ue.latitude,ue.longitude], {icon: walk_icon}).addTo(mymap) - // .bindTooltip(ue.ip_address_v4) - // .bindPopup(""+ ue.name +"
"+ - // // ue.description +"
"+ - // "location: [" + ue.latitude.toFixed(6) + "," + ue.longitude.toFixed(6) +"]
"+ - // "Cell ID: " + ( (ue.cell_id_hex==null)? "-" : ue.cell_id_hex ) +"
"+ - // "External identifier: " + ue.external_identifier +"
"+ - // "Speed:"+ ue.speed) - // .addTo(ues_lg); // add to layer group - - // // if ( ue.cell_id_hex==null ) { - // // L.DomUtil.addClass(ue_markers[ue.supi]._icon, 'null-cell'); - // // } else { - // // L.DomUtil.removeClass(ue_markers[ue.supi]._icon, 'null-cell'); - // // } - - // // update UE marker color - // temp_icon = L.DomUtil.get(ue_markers[ue.supi]._icon); - - // if (temp_icon == null) { - // // if the user has unchecked the UEs checkbox ✅ on the map settings - // // temp_icon is null and triggers console errors - // // if this is the case, continue... - // continue; - // } else { - // if ( ue.cell_id_hex==null ) { - // // 'null-cell' class gives a grey color - // // to UEs that are not connected to a cell - // L.DomUtil.addClass(temp_icon, 'null-cell'); - // } else { - // L.DomUtil.removeClass(temp_icon, 'null-cell'); - // } - // } - // } for (const ue of ues) { - if (UEs_first_paint) { - // create markers - this will be executed only once! - var walk_icon = L.divIcon({ - className: 'emu-pin-box', - iconSize: L.point(30,42), - iconAnchor: L.point(15,42), - popupAnchor: L.point(0,-38), - tooltipAnchor: L.point(0,0), - html: '
\ -
' - }); - - ue_markers[ue.supi] = L.marker([ue.latitude,ue.longitude], {icon: walk_icon}).addTo(mymap) - .bindTooltip(ue.ip_address_v4) - .bindPopup(""+ ue.name +"
"+ - // ue.description +"
"+ - "location: [" + ue.latitude.toFixed(6) + "," + ue.longitude.toFixed(6) +"]
"+ - "Cell ID: " + ( (ue.cell_id_hex==null)? "-" : ue.cell_id_hex ) +"
"+ - "External identifier: " + ue.external_identifier +"
"+ - "Speed:"+ ue.speed) - .addTo(ues_lg); // add to layer group - - if ( ue.cell_id_hex==null ) { - L.DomUtil.addClass(ue_markers[ue.supi]._icon, 'null-cell'); - } else { - L.DomUtil.removeClass(ue_markers[ue.supi]._icon, 'null-cell'); - } + // create markers - this will be executed only once! + var walk_icon = L.divIcon({ + className: 'emu-pin-box', + iconSize: L.point(30,42), + iconAnchor: L.point(15,42), + popupAnchor: L.point(0,-38), + tooltipAnchor: L.point(0,0), + html: '
\ +
' + }); + + ue_markers[ue.supi] = L.marker([ue.latitude,ue.longitude], {icon: walk_icon}).addTo(mymap) + .bindTooltip(ue.ip_address_v4) + .bindPopup(""+ ue.name +"
"+ + // ue.description +"
"+ + "location: [" + ue.latitude.toFixed(6) + "," + ue.longitude.toFixed(6) +"]
"+ + "Cell ID: " + ( (ue.cell_id_hex==null)? "-" : ue.cell_id_hex ) +"
"+ + "External identifier: " + ue.external_identifier +"
"+ + "Speed:"+ ue.speed) + .addTo(ues_lg); // add to layer group - } - else { - // move existing markers - var newLatLng = [ue.latitude,ue.longitude]; - ue_markers[ue.supi].setLatLng(newLatLng); - ue_markers[ue.supi].setPopupContent(""+ ue.name +"
"+ - // ue.description +"
"+ - "location: [" + ue.latitude.toFixed(6) + "," + ue.longitude.toFixed(6) +"]
"+ - "Cell ID: " + ( (ue.cell_id_hex==null)? "-" : ue.cell_id_hex ) +"
"+ - "External identifier: " + ue.external_identifier +"
"+ - "Speed:"+ ue.speed); - - - // update UE marker color - temp_icon = L.DomUtil.get(ue_markers[ue.supi]._icon); - - if (temp_icon == null) { - // if the user has unchecked the UEs checkbox ✅ on the map settings - // temp_icon is null and triggers console errors - // if this is the case, continue... - continue; - } else { - if ( ue.cell_id_hex==null ) { - // 'null-cell' class gives a grey color - // to UEs that are not connected to a cell - L.DomUtil.addClass(temp_icon, 'null-cell'); - } else { - L.DomUtil.removeClass(temp_icon, 'null-cell'); - } - } + if ( ue.cell_id_hex==null ) { + L.DomUtil.addClass(ue_markers[ue.supi]._icon, 'null-cell'); + } else { + L.DomUtil.removeClass(ue_markers[ue.supi]._icon, 'null-cell'); } } - UEs_first_paint = false; } @@ -897,7 +814,7 @@ function ui_add_ue_btn_listeners(){ // start location UE loop api_start_loop({"supi":curr_supi}); - + start_map_refresh_interval(); $(this).data("running",true); $(this).removeClass('btn-success').addClass('btn-danger'); From 9656d1cf2aac1eceb641ce1e065fbbcdd2c0006a Mon Sep 17 00:00:00 2001 From: JFrgs Date: Wed, 26 Apr 2023 17:06:49 +0300 Subject: [PATCH 5/7] integration of CAPIF Logging Service --- .gitignore | 2 + .../api/api_v1/endpoints/monitoringevent.py | 3 +- backend/app/app/api/api_v1/endpoints/utils.py | 52 +++++++++++++++++++ .../service_as_session_with_qos.json | 8 +-- .../capif_files/service_monitoring_event.json | 8 +-- 5 files changed, 64 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 431735d3..8a73fa14 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ *.csr *.pem backend/app/app/core/certificates/capif_provider_details.json +backend/app/app/core/certificates/CAPIF_service_as_session_with_qos.json +backend/app/app/core/certificates/CAPIF_service_monitoring_event.json venv/ \ No newline at end of file diff --git a/backend/app/app/api/api_v1/endpoints/monitoringevent.py b/backend/app/app/api/api_v1/endpoints/monitoringevent.py index 34fe296c..3524a0f0 100644 --- a/backend/app/app/api/api_v1/endpoints/monitoringevent.py +++ b/backend/app/app/api/api_v1/endpoints/monitoringevent.py @@ -8,7 +8,7 @@ from app.api import deps from app import tools from app.db.session import client -from app.api.api_v1.endpoints.utils import add_notifications +from app.api.api_v1.endpoints.utils import add_notifications, ccf_logs from .ue_movement import retrieve_ue_state, retrieve_ue router = APIRouter() @@ -41,6 +41,7 @@ def read_active_subscriptions( if retrieved_docs: http_response = JSONResponse(content=retrieved_docs, status_code=200) add_notifications(http_request, http_response, False) + ccf_logs(http_request, http_response, "service_monitoring_event.json", token_payload.get("sub")) return http_response else: return Response(status_code=204) diff --git a/backend/app/app/api/api_v1/endpoints/utils.py b/backend/app/app/api/api_v1/endpoints/utils.py index 70750b68..399b444e 100644 --- a/backend/app/app/api/api_v1/endpoints/utils.py +++ b/backend/app/app/api/api_v1/endpoints/utils.py @@ -12,6 +12,58 @@ from pydantic import BaseModel from app.api.api_v1.endpoints.paths import get_random_point from app.api.api_v1.endpoints.ue_movement import retrieve_ue_state +from evolved5g.sdk import CAPIFLogger +from urllib.parse import urlparse, unquote + +#Create CAPIF Logger object +def ccf_logs(input_request: Request, output_response: JSONResponse, service_api_description: str, invoker_id: str): + capif_logger = CAPIFLogger(certificates_folder="app/core/certificates", + capif_host="capifcore", + capif_https_port="443" + ) + + log_entries = [] + service_description = capif_logger.get_capif_service_description(capif_service_api_description_json_full_path= + f"app/core/certificates/CAPIF_{service_api_description}") + + api_id = service_description["apiId"] + + endpoint = input_request.url.path + if endpoint.find('monitoring') != -1: + resource = "Monitoring_Event_API" + endpoint = "/nef/api/v1/3gpp-monitoring-event/" + elif endpoint.find('session-with-qos') != -1: + resource = "AsSession_With_QoS_API" + endpoint = "/nef/api/v1/3gpp-as-session-with-qos/" + + #Request body check and trim + if(input_request.method == 'POST') or (input_request.method == 'PUT'): + req_body = input_request._body.decode("utf-8").replace('\n', '') + req_body = req_body.replace(' ', '') + else: + req_body = " " + + url_string = "https://" + input_request.url.hostname + ":4443" + endpoint + + log_entry = CAPIFLogger.LogEntry( + apiId = api_id, + apiVersion="v1", + apiName=endpoint, + resourceName=resource, + uri=url_string, + protocol="HTTP_1_1", + invocationTime= datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + invocationLatency=10, + operation=input_request.method, + result= str(output_response.status_code), + inputParameters={ "request" : req_body}, + outputParameters={ "response" : output_response.body.decode("utf-8") } + ) + + log_entries.append(log_entry) + api_invoker_id = invoker_id + capif_logger.save_log(api_invoker_id,log_entries) + return #List holding notifications from event_notifications = [] diff --git a/backend/app/app/core/capif_files/service_as_session_with_qos.json b/backend/app/app/core/capif_files/service_as_session_with_qos.json index 9017f453..a76b3da3 100644 --- a/backend/app/app/core/capif_files/service_as_session_with_qos.json +++ b/backend/app/app/core/capif_files/service_as_session_with_qos.json @@ -10,16 +10,16 @@ "resources": [ { "resourceName": "QOS_SUBSCRIPTIONS", - "commType": " SUBSCRIBE_NOTIFY", - "uri": "/{scsAsId}/subscriptions", + "commType": "SUBSCRIBE_NOTIFY", + "uri": "/scsAsId001/subscriptions", "custOpName": "http_post", "operations": ["GET","POST"], "description": "Endpoint to manage monitoring subscriptions" }, { "resourceName": "QOS_SUBSCRIPTION_SINGLE", - "commType": " SUBSCRIBE_NOTIFY", - "uri": "/{scsAsId}/subscriptions/{subscriptionId}", + "commType": "SUBSCRIBE_NOTIFY", + "uri": "/scsAsId001/subscriptions/subscriptionId001", "custOpName": "http_get", "operations": ["GET","PUT","DELETE"], "description": "Endpoint to manage single subscription" diff --git a/backend/app/app/core/capif_files/service_monitoring_event.json b/backend/app/app/core/capif_files/service_monitoring_event.json index 4b79ac37..ae6cebf0 100644 --- a/backend/app/app/core/capif_files/service_monitoring_event.json +++ b/backend/app/app/core/capif_files/service_monitoring_event.json @@ -10,16 +10,16 @@ "resources": [ { "resourceName": "MONITORING_SUBSCRIPTIONS", - "commType": " SUBSCRIBE_NOTIFY", - "uri": "/{scsAsId}/subscriptions", + "commType": "SUBSCRIBE_NOTIFY", + "uri": "/scsAsId001/subscriptions", "custOpName": "http_post", "operations": ["GET","POST"], "description": "Endpoint to manage monitoring subscriptions" }, { "resourceName": "MONITORING_SUBSCRIPTION_SINGLE", - "commType": " SUBSCRIBE_NOTIFY", - "uri": "/{scsAsId}/subscriptions/{subscriptionId}", + "commType": "SUBSCRIBE_NOTIFY", + "uri": "/scsAsId001/subscriptions/subscriptionId001", "custOpName": "http_get", "operations": ["GET","PUT","DELETE"], "description": "Endpoint to manage single subscription" From efaf93487a18867b42d599d4ef9aed805829681d Mon Sep 17 00:00:00 2001 From: JFrgs Date: Thu, 27 Apr 2023 16:19:25 +0300 Subject: [PATCH 6/7] Add more logs in CCF logging service --- .../api/api_v1/endpoints/monitoringevent.py | 154 +++++++++++++++++- .../app/api/api_v1/endpoints/qosMonitoring.py | 135 ++++++++++++++- backend/app/app/api/api_v1/endpoints/utils.py | 97 +++++------ backend/app/app/backend_pre_start.py | 11 +- .../service_as_session_with_qos.json | 4 +- .../capif_files/service_monitoring_event.json | 4 +- 6 files changed, 344 insertions(+), 61 deletions(-) diff --git a/backend/app/app/api/api_v1/endpoints/monitoringevent.py b/backend/app/app/api/api_v1/endpoints/monitoringevent.py index 3524a0f0..f93f7420 100644 --- a/backend/app/app/api/api_v1/endpoints/monitoringevent.py +++ b/backend/app/app/api/api_v1/endpoints/monitoringevent.py @@ -10,6 +10,7 @@ from app.db.session import client from app.api.api_v1.endpoints.utils import add_notifications, ccf_logs from .ue_movement import retrieve_ue_state, retrieve_ue +import logging router = APIRouter() db_collection= 'MonitoringEvent' @@ -41,7 +42,16 @@ def read_active_subscriptions( if retrieved_docs: http_response = JSONResponse(content=retrieved_docs, status_code=200) add_notifications(http_request, http_response, False) - ccf_logs(http_request, http_response, "service_monitoring_event.json", token_payload.get("sub")) + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.critical(f"Error: {error}") + return http_response else: return Response(status_code=204) @@ -73,6 +83,14 @@ def create_subscription( UE = ue.get_externalId(db=db, externalId=str(item_in.externalId), owner_id=current_user.id) if not UE: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "UE with this external identifier doesn't exist"}) + json_response.update({"status_code" : "409"}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.critical(f"Error: {error}") raise HTTPException(status_code=409, detail="UE with this external identifier doesn't exist") @@ -99,12 +117,30 @@ def create_subscription( http_response = JSONResponse(content=json_compatible_item_data, status_code=200) add_notifications(http_request, http_response, False) + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") + return http_response #Subscription elif item_in.monitoringType == "LOCATION_REPORTING" and item_in.maximumNumberOfReports>1: #Check if subscription with externalid exists if crud_mongo.read_by_multiple_pairs(db_mongo, db_collection, externalId = item_in.externalId, monitoringType = item_in.monitoringType): + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : f"There is already an active subscription for UE with external id {item_in.externalId} - Monitoring Type = {item_in.monitoringType}"}) + json_response.update({"status_code" : "409"}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.critical(f"Error: {error}") raise HTTPException(status_code=409, detail=f"There is already an active subscription for UE with external id {item_in.externalId} - Monitoring Type = {item_in.monitoringType}") json_data = jsonable_encoder(item_in.dict(exclude_unset=True)) @@ -127,8 +163,27 @@ def create_subscription( http_response = JSONResponse(content=updated_doc, status_code=201, headers=response_header) add_notifications(http_request, http_response, False) + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") + return http_response elif (item_in.monitoringType == "LOSS_OF_CONNECTIVITY" or item_in.monitoringType == "UE_REACHABILITY") and item_in.maximumNumberOfReports == 1: + + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "\"maximumNumberOfReports\" should be greater than 1 in case of LOSS_OF_CONNECTIVITY event"}) + json_response.update({"status_code" : "403"}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.critical(f"Error: {error}") return JSONResponse(content=jsonable_encoder( { "title" : "The requested parameters are out of range", @@ -141,6 +196,14 @@ def create_subscription( elif (item_in.monitoringType == "LOSS_OF_CONNECTIVITY" or item_in.monitoringType == "UE_REACHABILITY") and item_in.maximumNumberOfReports > 1: #Check if subscription with externalid && monitoringType exists if crud_mongo.read_by_multiple_pairs(db_mongo, db_collection, externalId = item_in.externalId, monitoringType = item_in.monitoringType): + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : f"There is already an active subscription for UE with external id {item_in.externalId} - Monitoring Type = {item_in.monitoringType}"}) + json_response.update({"status_code" : "409"}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.critical(f"Error: {error}") raise HTTPException(status_code=409, detail=f"There is already an active subscription for UE with external id {item_in.externalId} - Monitoring Type = {item_in.monitoringType}") json_data = jsonable_encoder(item_in.dict(exclude_unset=True)) @@ -162,6 +225,16 @@ def create_subscription( http_response = JSONResponse(content=updated_doc, status_code=201, headers=response_header) add_notifications(http_request, http_response, False) + + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") return http_response @@ -184,10 +257,26 @@ def update_subscription( try: retrieved_doc = crud_mongo.read_uuid(db_mongo, db_collection, subscriptionId) except Exception as ex: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "Please enter a valid uuid (24-character hex string)"}) + json_response.update({"status_code" : "400"}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.critical(f"Error: {error}") raise HTTPException(status_code=400, detail='Please enter a valid uuid (24-character hex string)') #Check if the document exists if not retrieved_doc: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "Subscription not found"}) + json_response.update({"status_code" : "404"}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.critical(f"Error: {error}") raise HTTPException(status_code=404, detail="Subscription not found") #If the document exists then validate the owner if not user.is_superuser(current_user) and (retrieved_doc['owner_id'] != current_user.id): @@ -206,6 +295,17 @@ def update_subscription( http_response = JSONResponse(content=updated_doc, status_code=200) add_notifications(http_request, http_response, False) + + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") + return http_response else: crud_mongo.delete_by_uuid(db_mongo, db_collection, subscriptionId) @@ -229,10 +329,25 @@ def read_subscription( try: retrieved_doc = crud_mongo.read_uuid(db_mongo, db_collection, subscriptionId) except Exception as ex: + try: + json_response = {} + json_response.update({"response" : "Please enter a valid uuid (24-character hex string)"}) + json_response.update({"status_code" : "400"}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.critical(f"Error: {error}") raise HTTPException(status_code=400, detail='Please enter a valid uuid (24-character hex string)') #Check if the document exists if not retrieved_doc: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "Subscription not found"}) + json_response.update({"status_code" : "404"}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.critical(f"Error: {error}") raise HTTPException(status_code=404, detail="Subscription not found") #If the document exists then validate the owner if not user.is_superuser(current_user) and (retrieved_doc['owner_id'] != current_user.id): @@ -245,6 +360,17 @@ def read_subscription( http_response = JSONResponse(content=retrieved_doc, status_code=200) add_notifications(http_request, http_response, False) + + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") + return http_response else: crud_mongo.delete_by_uuid(db_mongo, db_collection, subscriptionId) @@ -267,10 +393,25 @@ def delete_subscription( try: retrieved_doc = crud_mongo.read_uuid(db_mongo, db_collection, subscriptionId) except Exception as ex: + try: + json_response = {} + json_response.update({"response" : "Please enter a valid uuid (24-character hex string)"}) + json_response.update({"status_code" : "400"}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.critical(f"Error: {error}") raise HTTPException(status_code=400, detail='Please enter a valid uuid (24-character hex string)') #Check if the document exists if not retrieved_doc: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "Subscription not found"}) + json_response.update({"status_code" : "404"}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.critical(f"Error: {error}") raise HTTPException(status_code=404, detail="Subscription not found") #If the document exists then validate the owner if not user.is_superuser(current_user) and (retrieved_doc['owner_id'] != current_user.id): @@ -281,6 +422,17 @@ def delete_subscription( http_response = JSONResponse(content=retrieved_doc, status_code=200) add_notifications(http_request, http_response, False) + + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, json_response, "service_monitoring_event.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") + return http_response diff --git a/backend/app/app/api/api_v1/endpoints/qosMonitoring.py b/backend/app/app/api/api_v1/endpoints/qosMonitoring.py index 206a6f5a..9b428fd0 100644 --- a/backend/app/app/api/api_v1/endpoints/qosMonitoring.py +++ b/backend/app/app/api/api_v1/endpoints/qosMonitoring.py @@ -9,7 +9,7 @@ from app.api import deps from app.crud import crud_mongo, user, ue from app.db.session import client -from .utils import add_notifications +from .utils import add_notifications, ccf_logs from .qosInformation import qos_reference_match router = APIRouter() @@ -31,10 +31,29 @@ def read_active_subscriptions( #Check if there are any active subscriptions if not retrieved_docs: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "There are no active subscriptions"}) + json_response.update({"status_code" : "404"}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") raise HTTPException(status_code=404, detail="There are no active subscriptions") http_response = JSONResponse(content=retrieved_docs, status_code=200) add_notifications(http_request, http_response, False) + + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") + return http_response #Callback @@ -63,13 +82,15 @@ def create_subscription( fiveG_qi = qos_reference_match(item_in.qosReference) if fiveG_qi.get('type') == 'GBR' or fiveG_qi.get('type') == 'DC-GBR': if (json_request['qosMonInfo'] == None) or (json_request['qosMonInfo']['repFreqs'] == None): + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "Please enter a value in repFreqs field"}) + json_response.update({"status_code" : "400"}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") raise HTTPException(status_code=400, detail="Please enter a value in repFreqs field") - - print(f'------------------------------------Curl from script {item_in.ipv4Addr}') - # else: - # if 'EVENT_TRIGGERED' not in json_request['qosMonInfo']['repFreqs']: - # raise HTTPException(status_code=400, detail="Only 'EVENT_TRIGGERED' reporting frequency is supported at the current version. Please enter 'EVENT_TRIGGERED' in repFreqs field") - #Ensure that the user sends only one of the ipv4, ipv6, macAddr fields validate_ids(item_in.dict(exclude_unset=True)) @@ -96,6 +117,14 @@ def create_subscription( raise HTTPException(status_code=409, detail="UE not found") if doc and (doc.get("owner_id") == current_user.id): + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : f"Subscription for UE with {selected_id} ({error_var}) already exists"}) + json_response.update({"status_code" : "409"}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") raise HTTPException(status_code=409, detail=f"Subscription for UE with {selected_id} ({error_var}) already exists") #Create the document in mongodb @@ -131,7 +160,16 @@ def create_subscription( http_response = JSONResponse(content=updated_doc, status_code=201, headers=response_header) add_notifications(http_request, http_response, False) - + + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") return http_response @@ -152,10 +190,26 @@ def read_subscription( try: retrieved_doc = crud_mongo.read_uuid(db_mongo, db_collection, subscriptionId) except Exception as ex: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "Please enter a vvalid uuid (24-character hex string)"}) + json_response.update({"status_code" : "400"}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") raise HTTPException(status_code=400, detail='Please enter a valid uuid (24-character hex string)') #Check if the document exists if not retrieved_doc: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "Subscription not found"}) + json_response.update({"status_code" : "404"}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") raise HTTPException(status_code=404, detail="Subscription not found") #If the document exists then validate the owner if not user.is_superuser(current_user) and (retrieved_doc['owner_id'] != current_user.id): @@ -164,6 +218,17 @@ def read_subscription( retrieved_doc.pop("owner_id") http_response = JSONResponse(content=retrieved_doc, status_code=200) add_notifications(http_request, http_response, False) + + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") + return http_response @router.put("/{scsAsId}/subscriptions/{subscriptionId}", response_model=schemas.AsSessionWithQoSSubscription) @@ -184,10 +249,26 @@ def update_subscription( try: retrieved_doc = crud_mongo.read_uuid(db_mongo, db_collection, subscriptionId) except Exception as ex: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "Please enter a vvalid uuid (24-character hex string)"}) + json_response.update({"status_code" : "400"}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") raise HTTPException(status_code=400, detail='Please enter a valid uuid (24-character hex string)') #Check if the document exists if not retrieved_doc: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "Subscription not found"}) + json_response.update({"status_code" : "404"}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") raise HTTPException(status_code=404, detail="Subscription not found") #If the document exists then validate the owner if not user.is_superuser(current_user) and (retrieved_doc['owner_id'] != current_user.id): @@ -202,6 +283,17 @@ def update_subscription( updated_doc.pop("owner_id") http_response = JSONResponse(content=updated_doc, status_code=200) add_notifications(http_request, http_response, False) + + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") + return http_response @router.delete("/{scsAsId}/subscriptions/{subscriptionId}", response_model=schemas.AsSessionWithQoSSubscription) @@ -221,11 +313,27 @@ def delete_subscription( try: retrieved_doc = crud_mongo.read_uuid(db_mongo, db_collection, subscriptionId) except Exception as ex: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "Please enter a vvalid uuid (24-character hex string)"}) + json_response.update({"status_code" : "400"}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") raise HTTPException(status_code=400, detail='Please enter a valid uuid (24-character hex string)') #Check if the document exists if not retrieved_doc: + #CAPIF Core Function Logging Service + try: + json_response = {} + json_response.update({"response" : "Subscription not found"}) + json_response.update({"status_code" : "404"}) + ccf_logs(http_request, json_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") raise HTTPException(status_code=404, detail="Subscription not found") #If the document exists then validate the owner if not user.is_superuser(current_user) and (retrieved_doc['owner_id'] != current_user.id): @@ -234,6 +342,17 @@ def delete_subscription( crud_mongo.delete_by_uuid(db_mongo, db_collection, subscriptionId) http_response = JSONResponse(content=retrieved_doc, status_code=200) add_notifications(http_request, http_response, False) + + #CAPIF Core Function Logging Service + try: + response = http_response.body.decode("utf-8") + json_response = {} + json_response.update({"response" : response}) + json_response.update({"status_code" : str(http_response.status_code)}) + ccf_logs(http_request, http_response, "service_as_session_with_qos.json", token_payload.get("sub")) + except TypeError as error: + logging.error(f"Error: {error}") + return http_response diff --git a/backend/app/app/api/api_v1/endpoints/utils.py b/backend/app/app/api/api_v1/endpoints/utils.py index 399b444e..dffb47ee 100644 --- a/backend/app/app/api/api_v1/endpoints/utils.py +++ b/backend/app/app/api/api_v1/endpoints/utils.py @@ -13,57 +13,62 @@ from app.api.api_v1.endpoints.paths import get_random_point from app.api.api_v1.endpoints.ue_movement import retrieve_ue_state from evolved5g.sdk import CAPIFLogger -from urllib.parse import urlparse, unquote #Create CAPIF Logger object -def ccf_logs(input_request: Request, output_response: JSONResponse, service_api_description: str, invoker_id: str): - capif_logger = CAPIFLogger(certificates_folder="app/core/certificates", - capif_host="capifcore", - capif_https_port="443" - ) - - log_entries = [] - service_description = capif_logger.get_capif_service_description(capif_service_api_description_json_full_path= - f"app/core/certificates/CAPIF_{service_api_description}") - - api_id = service_description["apiId"] - - endpoint = input_request.url.path - if endpoint.find('monitoring') != -1: - resource = "Monitoring_Event_API" - endpoint = "/nef/api/v1/3gpp-monitoring-event/" - elif endpoint.find('session-with-qos') != -1: - resource = "AsSession_With_QoS_API" - endpoint = "/nef/api/v1/3gpp-as-session-with-qos/" - - #Request body check and trim - if(input_request.method == 'POST') or (input_request.method == 'PUT'): - req_body = input_request._body.decode("utf-8").replace('\n', '') - req_body = req_body.replace(' ', '') - else: - req_body = " " - - url_string = "https://" + input_request.url.hostname + ":4443" + endpoint +def ccf_logs(input_request: Request, output_response: dict, service_api_description: str, invoker_id: str): - log_entry = CAPIFLogger.LogEntry( - apiId = api_id, - apiVersion="v1", - apiName=endpoint, - resourceName=resource, - uri=url_string, - protocol="HTTP_1_1", - invocationTime= datetime.now().strftime("%Y-%m-%d %H:%M:%S"), - invocationLatency=10, - operation=input_request.method, - result= str(output_response.status_code), - inputParameters={ "request" : req_body}, - outputParameters={ "response" : output_response.body.decode("utf-8") } + try: + capif_logger = CAPIFLogger(certificates_folder="app/core/certificates", + capif_host="capifcore", + capif_https_port="443" ) - log_entries.append(log_entry) - api_invoker_id = invoker_id - capif_logger.save_log(api_invoker_id,log_entries) - return + log_entries = [] + service_description = capif_logger.get_capif_service_description(capif_service_api_description_json_full_path= + f"app/core/certificates/CAPIF_{service_api_description}") + + api_id = service_description["apiId"] + + endpoint = input_request.url.path + if endpoint.find('monitoring') != -1: + resource = "Monitoring_Event_API" + endpoint = "/nef/api/v1/3gpp-monitoring-event/" + elif endpoint.find('session-with-qos') != -1: + resource = "AsSession_With_QoS_API" + endpoint = "/nef/api/v1/3gpp-as-session-with-qos/" + + #Request body check and trim + if(input_request.method == 'POST') or (input_request.method == 'PUT'): + req_body = input_request._body.decode("utf-8").replace('\n', '') + req_body = req_body.replace(' ', '') + req_body = json.loads(req_body) + else: + req_body = " " + + url_string = "https://" + input_request.url.hostname + ":4443" + endpoint + + log_entry = CAPIFLogger.LogEntry( + apiId = api_id, + apiVersion="v1", + apiName=endpoint, + resourceName=resource, + uri=url_string, + protocol="HTTP_1_1", + invocationTime= datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + invocationLatency=10, + operation=input_request.method, + result= output_response.get("status_code"), + inputParameters=req_body, + outputParameters=output_response.get("response") + ) + + log_entries.append(log_entry) + api_invoker_id = invoker_id + capif_logger.save_log(api_invoker_id,log_entries) + except Exception as ex: + logging.critical(ex) + logging.critical("Potential cause of failure: CAPIF Core Function is not deployed or unreachable") + #List holding notifications from event_notifications = [] diff --git a/backend/app/app/backend_pre_start.py b/backend/app/app/backend_pre_start.py index 6912610b..325a9151 100644 --- a/backend/app/app/backend_pre_start.py +++ b/backend/app/app/backend_pre_start.py @@ -52,15 +52,20 @@ def capif_nef_connector(): capif_connector.publish_services(service_api_description_json_full_path="app/core/capif_files/service_monitoring_event.json") capif_connector.publish_services(service_api_description_json_full_path="app/core/capif_files/service_as_session_with_qos.json") + return True except requests.exceptions.HTTPError as err: if err.response.status_code == 409: logger.error(f'"Http Error:", {err.response.json()}') + return False except requests.exceptions.ConnectionError as err: logger.error(f'"Error Connecting:", {err}') + return False except requests.exceptions.Timeout as err: logger.error(f'"Timeout Error:", {err}') + return False except requests.exceptions.RequestException as err: logger.error(f'"Error:", {err}') + return False def main() -> None: @@ -68,8 +73,10 @@ def main() -> None: init() logger.info("Service finished initializing") logger.info("Trying to connect with CAPIF Core Function") - capif_nef_connector() - logger.info("Successfully onboard to CAPIF Core Function") + if capif_nef_connector(): + logger.info("Successfully onboard NEF in the CAPIF Core Function") + else: + logger.info("Failed to onboard NEF in the CAPIF Core Function") if __name__ == "__main__": diff --git a/backend/app/app/core/capif_files/service_as_session_with_qos.json b/backend/app/app/core/capif_files/service_as_session_with_qos.json index a76b3da3..fac360f1 100644 --- a/backend/app/app/core/capif_files/service_as_session_with_qos.json +++ b/backend/app/app/core/capif_files/service_as_session_with_qos.json @@ -39,12 +39,12 @@ ], "protocol": "HTTP_1_1", "dataFormat": "JSON", - "securityMethods": ["Oauth", "PSK"], + "securityMethods": ["OAUTH", "PSK"], "interfaceDescriptions": [ { "ipv4Addr": "127.0.0.1", "port": 8888, - "securityMethods": ["Oauth"] + "securityMethods": ["OAUTH"] } ] } diff --git a/backend/app/app/core/capif_files/service_monitoring_event.json b/backend/app/app/core/capif_files/service_monitoring_event.json index ae6cebf0..2524925d 100644 --- a/backend/app/app/core/capif_files/service_monitoring_event.json +++ b/backend/app/app/core/capif_files/service_monitoring_event.json @@ -39,12 +39,12 @@ ], "protocol": "HTTP_1_1", "dataFormat": "JSON", - "securityMethods": ["Oauth", "PSK"], + "securityMethods": ["OAUTH", "PSK"], "interfaceDescriptions": [ { "ipv4Addr": "127.0.0.1", "port": 8888, - "securityMethods": ["Oauth"] + "securityMethods": ["OAUTH"] } ] } From 2a3f5b811ed135268a487d62235a553b4dfc7235 Mon Sep 17 00:00:00 2001 From: JFrgs Date: Fri, 28 Apr 2023 12:13:08 +0300 Subject: [PATCH 7/7] Update changelog.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10512512..43d5455b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,12 @@ # Changelog +## v2.1.0 + +***Summary:*** +> - *Add functionality to support CAPIF Core Function's logging service* +> - *Avoid db connections within the threads (optimisation)* +> - *Fix token causing 403 error in mapbox front-end* +

+ ## v2.0.0 ***Summary:***