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/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:***
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/monitoringevent.py b/backend/app/app/api/api_v1/endpoints/monitoringevent.py
index 34fe296c..f93f7420 100644
--- a/backend/app/app/api/api_v1/endpoints/monitoringevent.py
+++ b/backend/app/app/api/api_v1/endpoints/monitoringevent.py
@@ -8,8 +8,9 @@
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
+import logging
router = APIRouter()
db_collection= 'MonitoringEvent'
@@ -41,6 +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)
+ #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)
@@ -72,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")
@@ -98,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))
@@ -126,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",
@@ -140,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))
@@ -161,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
@@ -183,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):
@@ -205,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)
@@ -228,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):
@@ -244,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)
@@ -266,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):
@@ -280,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/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()
diff --git a/backend/app/app/api/api_v1/endpoints/utils.py b/backend/app/app/api/api_v1/endpoints/utils.py
index 70750b68..dffb47ee 100644
--- a/backend/app/app/api/api_v1/endpoints/utils.py
+++ b/backend/app/app/api/api_v1/endpoints/utils.py
@@ -12,6 +12,63 @@
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
+
+#Create CAPIF Logger object
+def ccf_logs(input_request: Request, output_response: dict, service_api_description: str, invoker_id: str):
+
+ try:
+ 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(' ', '')
+ 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/static/js/dashboard-cells.js b/backend/app/app/static/js/dashboard-cells.js
index 235fe794..dcf1089d 100644
--- a/backend/app/app/static/js/dashboard-cells.js
+++ b/backend/app/app/static/js/dashboard-cells.js
@@ -566,10 +566,16 @@ 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 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 = {
@@ -602,10 +609,16 @@ 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 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 65e7a9cd..eee03012 100644
--- a/backend/app/app/static/js/dashboard-paths.js
+++ b/backend/app/app/static/js/dashboard-paths.js
@@ -562,10 +562,16 @@ 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 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 = {
@@ -597,10 +604,16 @@ 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 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 05359eeb..27b18cd9 100644
--- a/backend/app/app/static/js/dashboard-ues.js
+++ b/backend/app/app/static/js/dashboard-ues.js
@@ -614,10 +614,16 @@ 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 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 = {
@@ -652,10 +659,16 @@ 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 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 04547180..a870d94c 100644
--- a/backend/app/app/static/js/map.js
+++ b/backend/app/app/static/js/map.js
@@ -274,10 +274,16 @@ 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 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 +295,8 @@ function ui_initialize_map() {
var baseLayers = {
"Grayscale": grayscale,
- "Streets": streets
+ "Streets": streets,
+ 'OpenStreetMap': osm
};
var overlays = {