Skip to content

Commit

Permalink
Merge branch 'medianetlab:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
tgogos committed May 23, 2022
2 parents 6ea7f67 + be126a1 commit bcbce43
Show file tree
Hide file tree
Showing 10 changed files with 351 additions and 22 deletions.
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
# Changelog

## v1.4.1

### Migration to Python 3.9

(see commit: 2ef55ed)

- updated `tiangolo/uvicorn -gunicorn -fastapi:python3.9 (from 3.7)`
- updated `python = "3.9.7" (from 3.7)`
- updated `uvicorn = "^0.17.6" (from 0.15.0)`
- updated `fastapi = "^0.78.0" (from 0.54.1)`
- updated `pymongo = "^4.1.0" (from 3.12.1)`
- updated `requests = "^2.27.0" (from 2.23.0)`
- updated `gunicorn = "^20.1.0" (from 20.0.4)`
- removed `celery = "^4.4.2"`
- removed `alembic = "^1.4.2"`
- removed `GeoAlchemy2 = "^0.9.4"`



### 📄 docs

- add documentation for the UI (historical context, naming conventions, front-end libraries & approaches used etc...)



### Backend

- 🚫🤚 Forbid user to update cells while UEs are moving
- Add timeout values in `requests.request` 👇
- Timeout values according to https://docs.pythonrequests.org/en/master/user/advanced/#timeouts
- Fixes "hanging" UEs problem: when subscribing to NEF APIs, specific IPs included in the `notificationDestination` URL caused timeouts. Since the default for Python Requests is `None` (wait until the connection is closed) the UE "freezes" until the request times out and the exception is finally caught.

<br><br>

## v1.4.0

### Scenario `import` / `export`
Expand Down
2 changes: 1 addition & 1 deletion backend/Dockerfile.backend
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9

WORKDIR /app/

Expand Down
7 changes: 7 additions & 0 deletions backend/app/app/api/api_v1/endpoints/Cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from sqlalchemy.orm import Session
from app import crud, models, schemas
from app.api import deps
from app.api.api_v1.endpoints.utils import retrieve_ue_state

router = APIRouter()

Expand Down Expand Up @@ -68,6 +69,12 @@ def update_Cell(
"""
Update a cell.
"""
UEs = crud.ue.get_multi_by_owner(db=db, owner_id=current_user.id, skip=0, limit=1000)

for ue in UEs:
if retrieve_ue_state(ue.supi, current_user.id):
raise HTTPException(status_code=400, detail="You are not allowed to edit cells while UEs are moving")

Cell = crud.cell.get_Cell_id(db=db, id=cell_id)
if not Cell:
raise HTTPException(status_code=404, detail="Cell not found")
Expand Down
2 changes: 1 addition & 1 deletion backend/app/app/api/api_v1/endpoints/qosInformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def qos_reference_match(qos_reference):
for q in qos_5qi:
if q.get('value') == qos_reference:
qos_characteristics = q.copy()
print(qos_characteristics)
print(f"Inside qos_reference_match at qosInformation.py {qos_characteristics}")

if not qos_characteristics:
raise HTTPException(status_code=400, detail=f"The 5QI (qosReference) {qos_reference} does not exist")
Expand Down
2 changes: 1 addition & 1 deletion backend/app/app/api/api_v1/endpoints/qosMonitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def create_subscription(

#Create the document in mongodb

send_qos_gnb(item_in.qosReference, db_mongo, UE) ##Validate if qos reference matches any of the standardized 5qi values and create/send the QoS Profile to NG-RAN
# send_qos_gnb(item_in.qosReference, db_mongo, UE) ##Validate if qos reference matches any of the standardized 5qi values and create/send the QoS Profile to NG-RAN

json_data = jsonable_encoder(item_in.dict(exclude_unset=True))
json_data.update({'owner_id' : current_user.id})
Expand Down
25 changes: 18 additions & 7 deletions backend/app/app/api/api_v1/endpoints/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def run(self):


flag = True

while True:
for point in points:

Expand All @@ -93,15 +93,15 @@ def run(self):

if cell_now != None:
if UE.Cell_id != cell_now.get('id'): #Cell has changed in the db "handover"
logging.info(f"UE({UE.supi}) with ipv4 {UE.ip_address_v4} handovers to Cell {cell_now.get('id')}, {cell_now.get('description')}")
logging.warning(f"UE({UE.supi}) with ipv4 {UE.ip_address_v4} handovers to Cell {cell_now.get('id')}, {cell_now.get('description')}")
crud.ue.update(db=db, db_obj=UE, obj_in={"Cell_id" : cell_now.get('id')})

#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
sub = crud.monitoring.get_sub_externalId(db=db, externalId=UE.external_identifier, owner_id=current_user.id)

#Validation of subscription
if not sub:
logging.warning("Subscription not found")
logging.warning("Monitoring Event subscription not found")
elif not crud.user.is_superuser(current_user) and (sub.owner_id != current_user.id):
logging.warning("Not enough permissions")
else:
Expand All @@ -128,8 +128,9 @@ def run(self):
else:
gbr = 'QOS_GUARANTEED'

logging.critical(gbr)
logging.warning(gbr)
qos_notification_control(gbr ,current_user, UE.ip_address_v4)
logging.critical("Bypassed qos notification control")
else:
crud.ue.update(db=db, db_obj=UE, obj_in={"Cell_id" : None})

Expand Down Expand Up @@ -208,7 +209,7 @@ def qos_notification_control(gbr_status: str, current_user, ipv4):

#Check if the document exists
if not doc:
logging.info("Subscription not found")
logging.warning("AsSessionWithQoS subscription not found")
return
#If the document exists then validate the owner
if not crud.user.is_superuser(current_user) and (doc['owner_id'] != current_user.id):
Expand All @@ -220,11 +221,21 @@ def qos_notification_control(gbr_status: str, current_user, ipv4):
logging.critical(qos_standardized)
logging.critical(qos_standardized.get('type'))

logging.critical(doc.get('notificationDestination'))
logging.critical(doc.get('link'))

if qos_standardized.get('type') == 'GBR' or qos_standardized.get('type') == 'DC-GBR':
try:
logging.critical("Before response")
response = qos_callback(doc.get('notificationDestination'), doc.get('link'), gbr_status, ipv4)
logging.critical(response.json())
except requests.exceptions.ConnectionError as ex:
logging.critical(f"Response from {doc.get('notificationDestination')}")
except requests.exceptions.Timeout as ex:
logging.critical("Failed to send the callback request")
logging.critical(ex)
except requests.exceptions.TooManyRedirects as ex:
logging.critical("Failed to send the callback request")
logging.critical(ex)
except requests.exceptions.RequestException as ex:
logging.critical("Failed to send the callback request")
logging.critical(ex)
else:
Expand Down
1 change: 0 additions & 1 deletion backend/app/app/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from fastapi import FastAPI, Request
from starlette.middleware.cors import CORSMiddleware

from app.api.api_v1.api import api_router, nef_router
from app.core.config import settings

Expand Down
12 changes: 10 additions & 2 deletions backend/app/app/tools/send_callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ def location_callback(UE_model, callbackurl, subscription):
'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data=payload)
#Timeout values according to https://docs.python-requests.org/en/master/user/advanced/#timeouts
#First value of the tuple "3.05" corresponds to connect and second "27" to read timeouts
#(i.e., connect timeout means that the server is unreachable and read that the server is reachable but the client does not receive a response within 27 seconds)

response = requests.request("POST", url, headers=headers, data=payload, timeout=(3.05, 27))

return response

Expand Down Expand Up @@ -61,6 +65,10 @@ def qos_callback(callbackurl, resource, qos_status, ipv4):
'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data=payload)
#Timeout values according to https://docs.python-requests.org/en/master/user/advanced/#timeouts
#First value of the tuple "3.05" corresponds to connect and second "27" to read timeouts
#(i.e., connect timeout means that the server is unreachable and read that the server is reachable but the client does not receive a response within 27 seconds)

response = requests.request("POST", url, headers=headers, data=payload, timeout=(3.05, 27))

return response
15 changes: 6 additions & 9 deletions backend/app/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,22 @@ description = ""
authors = ["Admin <[email protected]>"]

[tool.poetry.dependencies]
python = "^3.7"
uvicorn = "^0.15.0"
fastapi = "^0.54.1"
pymongo = "^3.12.1"
python = "3.9.7"
uvicorn = "^0.17.6"
fastapi = "^0.78.0"
pymongo = "^4.1.0"
python-multipart = "^0.0.5"
email-validator = "^1.0.5"
requests = "^2.23.0"
celery = "^4.4.2"
requests = "^2.27.0"
passlib = {extras = ["bcrypt"], version = "^1.7.2"}
tenacity = "^6.1.0"
pydantic = "^1.4"
emails = "^0.5.15"
raven = "^6.10.0"
gunicorn = "^20.0.4"
gunicorn = "^20.1.0"
jinja2 = "3.0.3"
psycopg2-binary = "^2.8.5"
alembic = "^1.4.2"
sqlalchemy = "^1.3.16"
GeoAlchemy2 = "^0.9.4"
pytest = "^5.4.1"
python-jose = {extras = ["cryptography"], version = "^3.1.0"}
aiofiles = "^0.6.0"
Expand Down
Loading

0 comments on commit bcbce43

Please sign in to comment.