From e06cf115c2929fec51796970a8c6898caf87273a Mon Sep 17 00:00:00 2001 From: "j.azzam" Date: Tue, 6 Aug 2024 10:16:04 +0200 Subject: [PATCH 1/6] feat: Adding a custom exception class to make detailed exception handling inside different filip methods --- filip/clients/exceptions.py | 17 +++++++++++++++++ filip/clients/ngsi_v2/iota.py | 4 ++-- tests/clients/test_ngsi_v2_iota.py | 20 +++++++++++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 filip/clients/exceptions.py diff --git a/filip/clients/exceptions.py b/filip/clients/exceptions.py new file mode 100644 index 00000000..18386a3d --- /dev/null +++ b/filip/clients/exceptions.py @@ -0,0 +1,17 @@ +""" +Module for client specific exceptions +""" +import requests.models + + +class BaseHttpClientException(Exception): + """ + Base exception class for all HTTP clients. The response of a request will be available in the exception. + + Args: + message (str): Error message + response (Response): Response object + """ + def __init__(self, message: str, response: requests.models.Response): + super().__init__(message) + self.response = response diff --git a/filip/clients/ngsi_v2/iota.py b/filip/clients/ngsi_v2/iota.py index 49cd28ed..3bae2273 100644 --- a/filip/clients/ngsi_v2/iota.py +++ b/filip/clients/ngsi_v2/iota.py @@ -13,6 +13,7 @@ from pydantic.type_adapter import TypeAdapter from filip.config import settings from filip.clients.base_http_client import BaseHttpClient +from filip.clients.exceptions import BaseHttpClientException from filip.models.base import FiwareHeader from filip.models.ngsi_v2.iot import Device, ServiceGroup @@ -299,8 +300,7 @@ def post_devices(self, *, devices: Union[Device, List[Device]], if update: return self.update_devices(devices=devices, add=False) msg = "Could not post devices" - self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def post_device(self, *, device: Device, update: bool = False) -> None: """ diff --git a/tests/clients/test_ngsi_v2_iota.py b/tests/clients/test_ngsi_v2_iota.py index 8518a285..4ef0cfa3 100644 --- a/tests/clients/test_ngsi_v2_iota.py +++ b/tests/clients/test_ngsi_v2_iota.py @@ -5,6 +5,7 @@ import unittest import logging import requests +import json from uuid import uuid4 @@ -12,6 +13,7 @@ from filip.clients.ngsi_v2 import \ ContextBrokerClient, \ IoTAClient +from filip.clients.exceptions import BaseHttpClientException from filip.models.ngsi_v2.iot import \ ServiceGroup, \ Device, \ @@ -380,6 +382,23 @@ def test_patch_device(self): new_device.__getattribute__(key)) cb_client.close() + @clean_test(fiware_service=settings.FIWARE_SERVICE, + fiware_servicepath=settings.FIWARE_SERVICEPATH, + cb_url=settings.CB_URL, + iota_url=settings.IOTA_JSON_URL) + def test_device_exceptions(self): + """ + Test for exceptions when handling a Device + """ + with IoTAClient(url=settings.IOTA_JSON_URL, fiware_header=self.fiware_header) as client: + device = Device(**self.device) + client.post_device(device=device) + + try: + client.post_device(device=device) + except BaseHttpClientException as err: + self.assertEqual(json.loads(err.response.text)["name"], "DUPLICATE_DEVICE_ID") + def test_service_group(self): """ Test of querying service group based on apikey and resource. @@ -467,4 +486,3 @@ def tearDown(self) -> None: clear_all(fiware_header=self.fiware_header, cb_url=settings.CB_URL, iota_url=settings.IOTA_JSON_URL) - From 7962f185498857870411320e8d4bfc997290a5b4 Mon Sep 17 00:00:00 2001 From: "j.azzam" Date: Tue, 8 Oct 2024 15:37:25 +0200 Subject: [PATCH 2/6] Added detailed exception handling in the IoT Agent --- filip/clients/ngsi_v2/iota.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/filip/clients/ngsi_v2/iota.py b/filip/clients/ngsi_v2/iota.py index 3bae2273..49492a9f 100644 --- a/filip/clients/ngsi_v2/iota.py +++ b/filip/clients/ngsi_v2/iota.py @@ -119,7 +119,7 @@ def post_groups(self, res.raise_for_status() except requests.RequestException as err: self.log_error(err=err, msg=None) - raise + raise BaseHttpClientException(message=err.response.text, response=err.response) from err def post_group(self, service_group: ServiceGroup, update: bool = False): """ @@ -156,7 +156,7 @@ def get_group_list(self) -> List[ServiceGroup]: res.raise_for_status() except requests.RequestException as err: self.log_error(err=err, msg=None) - raise + raise BaseHttpClientException(message=err.response.text, response=err.response) from err def get_group(self, *, resource: str, apikey: str) -> ServiceGroup: """ @@ -238,7 +238,7 @@ def update_group(self, *, service_group: ServiceGroup, res.raise_for_status() except requests.RequestException as err: self.log_error(err=err, msg=None) - raise + raise BaseHttpClientException(message=err.response.text, response=err.response) from err def delete_group(self, *, resource: str, apikey: str): """ @@ -267,7 +267,7 @@ def delete_group(self, *, resource: str, apikey: str): msg = f"Could not delete ServiceGroup with resource " \ f"'{resource}' and apikey '{apikey}'!" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err # DEVICE API def post_devices(self, *, devices: Union[Device, List[Device]], @@ -369,7 +369,7 @@ def get_device_list(self, *, res.raise_for_status() except requests.RequestException as err: self.log_error(err=err, msg=None) - raise + raise BaseHttpClientException(message=err.response.text, response=err.response) from err def get_device(self, *, device_id: str) -> Device: """ @@ -393,7 +393,7 @@ def get_device(self, *, device_id: str) -> Device: except requests.RequestException as err: msg = f"Device {device_id} was not found" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def update_device(self, *, device: Device, add: bool = True) -> None: """ @@ -426,7 +426,7 @@ def update_device(self, *, device: Device, add: bool = True) -> None: except requests.RequestException as err: msg = f"Could not update device '{device.device_id}'" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def update_devices(self, *, devices: Union[Device, List[Device]], add: False) -> None: @@ -493,7 +493,7 @@ def delete_device(self, *, device_id: str, except requests.RequestException as err: msg = f"Could not delete device {device_id}!" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err if delete_entity: # An entity can technically belong to multiple devices @@ -506,6 +506,7 @@ def delete_device(self, *, device_id: str, f"{device_id} was not deleted because it is " f"linked to multiple devices. ") else: + cb_client_local = None try: from filip.clients.ngsi_v2 import ContextBrokerClient @@ -513,7 +514,7 @@ def delete_device(self, *, device_id: str, cb_client_local = deepcopy(cb_client) else: warnings.warn("No `ContextBrokerClient` " - "object providesd! Will try to generate " + "object provided! Will try to generate " "one. This usage is not recommended.") cb_client_local = ContextBrokerClient( @@ -531,7 +532,8 @@ def delete_device(self, *, device_id: str, # this methode, not if this methode actively deleted it pass - cb_client_local.close() + if cb_client_local: + cb_client_local.close() def patch_device(self, device: Device, From 09fb1329cdd890f5a57d572b24a46ac26f382d9c Mon Sep 17 00:00:00 2001 From: "j.azzam" Date: Tue, 8 Oct 2024 16:43:36 +0200 Subject: [PATCH 3/6] Added detailed exception handling in OCB Client module --- filip/clients/ngsi_v2/cb.py | 65 +++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/filip/clients/ngsi_v2/cb.py b/filip/clients/ngsi_v2/cb.py index 8b8455b4..657498d9 100644 --- a/filip/clients/ngsi_v2/cb.py +++ b/filip/clients/ngsi_v2/cb.py @@ -32,6 +32,7 @@ from filip.models.ngsi_v2.base import AttrsFormat from filip.models.ngsi_v2.subscriptions import Subscription, Message from filip.models.ngsi_v2.registrations import Registration +from filip.clients.exceptions import BaseHttpClientException if TYPE_CHECKING: from filip.clients.ngsi_v2.iota import IoTAClient @@ -157,7 +158,7 @@ def get_version(self) -> Dict: res.raise_for_status() except requests.RequestException as err: self.logger.error(err) - raise + raise BaseHttpClientException(message=err.response.text, response=err.response) from err def get_resources(self) -> Dict: """ @@ -174,7 +175,7 @@ def get_resources(self) -> Dict: res.raise_for_status() except requests.RequestException as err: self.logger.error(err) - raise + raise BaseHttpClientException(message=err.response.text, response=err.response) from err # STATISTICS API def get_statistics(self) -> Dict: @@ -191,7 +192,7 @@ def get_statistics(self) -> Dict: res.raise_for_status() except requests.RequestException as err: self.logger.error(err) - raise + raise BaseHttpClientException(message=err.response.text, response=err.response) from err # CONTEXT MANAGEMENT API ENDPOINTS # Entity Operations @@ -267,7 +268,7 @@ def post_entity( return self.update_entity_key_values(entity=entity) msg = f"Could not post entity {entity.id}" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def get_entity_list( self, @@ -413,7 +414,7 @@ def get_entity_list( except requests.RequestException as err: msg = "Could not load entities" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def get_entity( self, @@ -476,7 +477,7 @@ def get_entity( except requests.RequestException as err: msg = f"Could not load entity {entity_id}" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def get_entity_attributes( self, @@ -539,7 +540,7 @@ def get_entity_attributes( except requests.RequestException as err: msg = f"Could not load attributes from entity {entity_id} !" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def update_entity(self, entity: ContextEntity, append_strict: bool = False): """ @@ -678,7 +679,7 @@ def delete_entity( except requests.RequestException as err: msg = f"Could not delete entity {entity_id} !" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err if delete_devices: from filip.clients.ngsi_v2 import IoTAClient @@ -826,7 +827,7 @@ def update_or_append_entity_attributes( except requests.RequestException as err: msg = f"Could not update or append attributes of entity" f" {entity.id} !" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def update_entity_key_values(self, entity: Union[ContextEntityKeyValues, dict],): @@ -863,7 +864,7 @@ def update_entity_key_values(self, msg = f"Could not update attributes of entity" \ f" {entity.id} !" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def update_entity_attributes_key_values(self, entity_id: str, @@ -969,7 +970,7 @@ def update_existing_entity_attributes( except requests.RequestException as err: msg = f"Could not update attributes of entity" f" {entity.id} !" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def override_entity(self, entity: Union[ContextEntity, ContextEntityKeyValues], @@ -1065,7 +1066,7 @@ def replace_entity_attributes( except requests.RequestException as err: msg = f"Could not replace attribute of entity {entity_id} !" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err # Attribute operations def get_attribute( @@ -1112,7 +1113,7 @@ def get_attribute( f"Could not load attribute '{attr_name}' from entity" f"'{entity_id}' " ) self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def update_entity_attribute(self, entity_id: str, @@ -1198,7 +1199,7 @@ def update_entity_attribute(self, f"Could not update attribute '{attr_name}' of entity" f"'{entity_id}' " ) self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def delete_entity_attribute( self, entity_id: str, attr_name: str, entity_type: str = None @@ -1235,7 +1236,7 @@ def delete_entity_attribute( f"Could not delete attribute '{attr_name}' of entity '{entity_id}'" ) self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err # Attribute value operations def get_attribute_value( @@ -1272,7 +1273,7 @@ def get_attribute_value( f"entity'{entity_id}' " ) self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def update_attribute_value(self, *, entity_id: str, @@ -1330,7 +1331,7 @@ def update_attribute_value(self, *, f"entity '{entity_id}' " ) self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err # Types Operations def get_entity_types( @@ -1364,7 +1365,7 @@ def get_entity_types( except requests.RequestException as err: msg = "Could not load entity types!" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def get_entity_type(self, entity_type: str) -> Dict[str, Any]: """ @@ -1387,7 +1388,7 @@ def get_entity_type(self, entity_type: str) -> Dict[str, Any]: except requests.RequestException as err: msg = f"Could not load entities of type" f"'{entity_type}' " self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err # SUBSCRIPTION API ENDPOINTS def get_subscription_list(self, limit: PositiveInt = inf) -> List[Subscription]: @@ -1414,7 +1415,7 @@ def get_subscription_list(self, limit: PositiveInt = inf) -> List[Subscription]: except requests.RequestException as err: msg = "Could not load subscriptions!" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def post_subscription( self, @@ -1499,7 +1500,7 @@ def post_subscription( except requests.RequestException as err: msg = "Could not send subscription!" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def get_subscription(self, subscription_id: str) -> Subscription: """ @@ -1521,7 +1522,7 @@ def get_subscription(self, subscription_id: str) -> Subscription: except requests.RequestException as err: msg = f"Could not load subscription {subscription_id}" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def update_subscription( self, subscription: Subscription, skip_initial_notification: bool = False @@ -1575,7 +1576,7 @@ def update_subscription( except requests.RequestException as err: msg = f"Could not update subscription {subscription.id}" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def delete_subscription(self, subscription_id: str) -> None: """ @@ -1596,7 +1597,7 @@ def delete_subscription(self, subscription_id: str) -> None: except requests.RequestException as err: msg = f"Could not delete subscription {subscription_id}" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err # Registration API def get_registration_list(self, *, limit: PositiveInt = None) -> List[Registration]: @@ -1624,7 +1625,7 @@ def get_registration_list(self, *, limit: PositiveInt = None) -> List[Registrati except requests.RequestException as err: msg = "Could not load registrations!" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def post_registration(self, registration: Registration): """ @@ -1654,7 +1655,7 @@ def post_registration(self, registration: Registration): except requests.RequestException as err: msg = f"Could not send registration {registration.id}!" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def get_registration(self, registration_id: str) -> Registration: """ @@ -1677,7 +1678,7 @@ def get_registration(self, registration_id: str) -> Registration: except requests.RequestException as err: msg = f"Could not load registration {registration_id} !" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def update_registration(self, registration: Registration): """ @@ -1707,7 +1708,7 @@ def update_registration(self, registration: Registration): except requests.RequestException as err: msg = f"Could not update registration {registration.id} !" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def delete_registration(self, registration_id: str) -> None: """ @@ -1727,7 +1728,7 @@ def delete_registration(self, registration_id: str) -> None: except requests.RequestException as err: msg = f"Could not delete registration {registration_id} !" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err # Batch operation API def update(self, @@ -1811,7 +1812,7 @@ def update(self, except requests.RequestException as err: msg = f"Update operation '{action_type}' failed!" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def query( self, @@ -1862,7 +1863,7 @@ def query( except requests.RequestException as err: msg = "Query operation failed!" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def notify(self, message: Message) -> None: """ @@ -1901,7 +1902,7 @@ def notify(self, message: Message) -> None: f"{message.model_dump_json(indent=2)}" ) self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def post_command( self, From 4da841db5ad30690a2d0fe8364209461b673f6f3 Mon Sep 17 00:00:00 2001 From: "j.azzam" Date: Tue, 8 Oct 2024 16:46:03 +0200 Subject: [PATCH 4/6] Added detailed exception handling in QuantumLeap Client --- filip/clients/ngsi_v2/quantumleap.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/filip/clients/ngsi_v2/quantumleap.py b/filip/clients/ngsi_v2/quantumleap.py index f9471f83..36c63155 100644 --- a/filip/clients/ngsi_v2/quantumleap.py +++ b/filip/clients/ngsi_v2/quantumleap.py @@ -22,6 +22,7 @@ AttributeValues, \ TimeSeries, \ TimeSeriesHeader +from filip.clients.exceptions import BaseHttpClientException logger = logging.getLogger(__name__) @@ -71,7 +72,7 @@ def get_version(self) -> Dict: res.raise_for_status() except requests.exceptions.RequestException as err: self.logger.error(err) - raise + raise BaseHttpClientException(message=err.response.text, response=err.response) from err def get_health(self) -> Dict: """ @@ -94,7 +95,7 @@ def get_health(self) -> Dict: res.raise_for_status() except requests.exceptions.RequestException as err: self.logger.error(err) - raise + raise BaseHttpClientException(message=err.response.text, response=err.response) from err def post_config(self): """ @@ -134,7 +135,7 @@ def post_notification(self, notification: Message): msg = f"Could not post notification for subscription id " \ f"{notification.subscriptionId}" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err def post_subscription(self, cb_url: Union[AnyHttpUrl, str], @@ -256,7 +257,7 @@ def delete_entity_type(self, entity_type: str) -> str: except requests.exceptions.RequestException as err: msg = f"Could not delete entities of type {entity_type}" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err # QUERY API ENDPOINTS def __query_builder(self, @@ -392,7 +393,7 @@ def __query_builder(self, else: msg = "Could not load entity data" self.log_error(err=err, msg=msg) - raise + raise BaseHttpClientException(message=msg, response=err.response) from err self.logger.info("Successfully retrieved entity data") return res_q From 6d58faaffdaeec6f8bb78e80fd32adc1f844ee8a Mon Sep 17 00:00:00 2001 From: "j.azzam" Date: Wed, 9 Oct 2024 09:34:04 +0200 Subject: [PATCH 5/6] Removing error logs from the iota client module and added tests for iota operations --- filip/clients/ngsi_v2/iota.py | 8 -------- tests/clients/test_ngsi_v2_iota.py | 15 ++++++++++++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/filip/clients/ngsi_v2/iota.py b/filip/clients/ngsi_v2/iota.py index 49492a9f..c8adb2fa 100644 --- a/filip/clients/ngsi_v2/iota.py +++ b/filip/clients/ngsi_v2/iota.py @@ -118,7 +118,6 @@ def post_groups(self, else: res.raise_for_status() except requests.RequestException as err: - self.log_error(err=err, msg=None) raise BaseHttpClientException(message=err.response.text, response=err.response) from err def post_group(self, service_group: ServiceGroup, update: bool = False): @@ -155,7 +154,6 @@ def get_group_list(self) -> List[ServiceGroup]: return ta.validate_python(res.json()['services']) res.raise_for_status() except requests.RequestException as err: - self.log_error(err=err, msg=None) raise BaseHttpClientException(message=err.response.text, response=err.response) from err def get_group(self, *, resource: str, apikey: str) -> ServiceGroup: @@ -237,7 +235,6 @@ def update_group(self, *, service_group: ServiceGroup, else: res.raise_for_status() except requests.RequestException as err: - self.log_error(err=err, msg=None) raise BaseHttpClientException(message=err.response.text, response=err.response) from err def delete_group(self, *, resource: str, apikey: str): @@ -266,7 +263,6 @@ def delete_group(self, *, resource: str, apikey: str): except requests.RequestException as err: msg = f"Could not delete ServiceGroup with resource " \ f"'{resource}' and apikey '{apikey}'!" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err # DEVICE API @@ -368,7 +364,6 @@ def get_device_list(self, *, return devices res.raise_for_status() except requests.RequestException as err: - self.log_error(err=err, msg=None) raise BaseHttpClientException(message=err.response.text, response=err.response) from err def get_device(self, *, device_id: str) -> Device: @@ -392,7 +387,6 @@ def get_device(self, *, device_id: str) -> Device: res.raise_for_status() except requests.RequestException as err: msg = f"Device {device_id} was not found" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def update_device(self, *, device: Device, add: bool = True) -> None: @@ -425,7 +419,6 @@ def update_device(self, *, device: Device, add: bool = True) -> None: res.raise_for_status() except requests.RequestException as err: msg = f"Could not update device '{device.device_id}'" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def update_devices(self, *, devices: Union[Device, List[Device]], @@ -492,7 +485,6 @@ def delete_device(self, *, device_id: str, res.raise_for_status() except requests.RequestException as err: msg = f"Could not delete device {device_id}!" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err if delete_entity: diff --git a/tests/clients/test_ngsi_v2_iota.py b/tests/clients/test_ngsi_v2_iota.py index 4ef0cfa3..156ce1b4 100644 --- a/tests/clients/test_ngsi_v2_iota.py +++ b/tests/clients/test_ngsi_v2_iota.py @@ -394,10 +394,19 @@ def test_device_exceptions(self): device = Device(**self.device) client.post_device(device=device) - try: + with self.assertRaises(BaseHttpClientException) as context: client.post_device(device=device) - except BaseHttpClientException as err: - self.assertEqual(json.loads(err.response.text)["name"], "DUPLICATE_DEVICE_ID") + self.assertEqual(json.loads(context.exception.response.text)["name"], "DUPLICATE_DEVICE_ID") + + with self.assertRaises(BaseHttpClientException) as context: + client.update_device(device=device, add=False) + self.assertEqual(json.loads(context.exception.response.text)["name"], "ENTITY_GENERIC_ERROR") + + client.delete_device(device_id=device.device_id) + + with self.assertRaises(BaseHttpClientException) as context: + client.delete_device(device_id=device.device_id) + self.assertEqual(json.loads(context.exception.response.text)["name"], "DEVICE_NOT_FOUND") def test_service_group(self): """ From 383fd2f50b7c5acef6050f8b0e6fbfd7822743a3 Mon Sep 17 00:00:00 2001 From: "j.azzam" Date: Wed, 9 Oct 2024 10:26:07 +0200 Subject: [PATCH 6/6] Added test for testing exceptions of OCB operations and removed error logs from the cb module --- filip/clients/ngsi_v2/cb.py | 29 ----------------------------- tests/clients/test_ngsi_v2_cb.py | 13 +++++++++++++ 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/filip/clients/ngsi_v2/cb.py b/filip/clients/ngsi_v2/cb.py index 657498d9..4432696a 100644 --- a/filip/clients/ngsi_v2/cb.py +++ b/filip/clients/ngsi_v2/cb.py @@ -267,7 +267,6 @@ def post_entity( else: return self.update_entity_key_values(entity=entity) msg = f"Could not post entity {entity.id}" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def get_entity_list( @@ -413,7 +412,6 @@ def get_entity_list( except requests.RequestException as err: msg = "Could not load entities" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def get_entity( @@ -476,7 +474,6 @@ def get_entity( res.raise_for_status() except requests.RequestException as err: msg = f"Could not load entity {entity_id}" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def get_entity_attributes( @@ -539,7 +536,6 @@ def get_entity_attributes( res.raise_for_status() except requests.RequestException as err: msg = f"Could not load attributes from entity {entity_id} !" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def update_entity(self, entity: ContextEntity, append_strict: bool = False): @@ -678,7 +674,6 @@ def delete_entity( res.raise_for_status() except requests.RequestException as err: msg = f"Could not delete entity {entity_id} !" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err if delete_devices: @@ -826,7 +821,6 @@ def update_or_append_entity_attributes( res.raise_for_status() except requests.RequestException as err: msg = f"Could not update or append attributes of entity" f" {entity.id} !" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def update_entity_key_values(self, @@ -863,7 +857,6 @@ def update_entity_key_values(self, except requests.RequestException as err: msg = f"Could not update attributes of entity" \ f" {entity.id} !" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def update_entity_attributes_key_values(self, @@ -969,7 +962,6 @@ def update_existing_entity_attributes( res.raise_for_status() except requests.RequestException as err: msg = f"Could not update attributes of entity" f" {entity.id} !" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def override_entity(self, @@ -1065,7 +1057,6 @@ def replace_entity_attributes( res.raise_for_status() except requests.RequestException as err: msg = f"Could not replace attribute of entity {entity_id} !" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err # Attribute operations @@ -1112,7 +1103,6 @@ def get_attribute( msg = ( f"Could not load attribute '{attr_name}' from entity" f"'{entity_id}' " ) - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def update_entity_attribute(self, @@ -1198,7 +1188,6 @@ def update_entity_attribute(self, msg = ( f"Could not update attribute '{attr_name}' of entity" f"'{entity_id}' " ) - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def delete_entity_attribute( @@ -1235,7 +1224,6 @@ def delete_entity_attribute( msg = ( f"Could not delete attribute '{attr_name}' of entity '{entity_id}'" ) - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err # Attribute value operations @@ -1272,7 +1260,6 @@ def get_attribute_value( f"Could not load value of attribute '{attr_name}' from " f"entity'{entity_id}' " ) - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def update_attribute_value(self, *, @@ -1330,7 +1317,6 @@ def update_attribute_value(self, *, f"Could not update value of attribute '{attr_name}' from " f"entity '{entity_id}' " ) - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err # Types Operations @@ -1364,7 +1350,6 @@ def get_entity_types( res.raise_for_status() except requests.RequestException as err: msg = "Could not load entity types!" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def get_entity_type(self, entity_type: str) -> Dict[str, Any]: @@ -1387,7 +1372,6 @@ def get_entity_type(self, entity_type: str) -> Dict[str, Any]: res.raise_for_status() except requests.RequestException as err: msg = f"Could not load entities of type" f"'{entity_type}' " - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err # SUBSCRIPTION API ENDPOINTS @@ -1414,7 +1398,6 @@ def get_subscription_list(self, limit: PositiveInt = inf) -> List[Subscription]: return adapter.validate_python(items) except requests.RequestException as err: msg = "Could not load subscriptions!" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def post_subscription( @@ -1499,7 +1482,6 @@ def post_subscription( res.raise_for_status() except requests.RequestException as err: msg = "Could not send subscription!" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def get_subscription(self, subscription_id: str) -> Subscription: @@ -1521,7 +1503,6 @@ def get_subscription(self, subscription_id: str) -> Subscription: res.raise_for_status() except requests.RequestException as err: msg = f"Could not load subscription {subscription_id}" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def update_subscription( @@ -1575,7 +1556,6 @@ def update_subscription( res.raise_for_status() except requests.RequestException as err: msg = f"Could not update subscription {subscription.id}" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def delete_subscription(self, subscription_id: str) -> None: @@ -1596,7 +1576,6 @@ def delete_subscription(self, subscription_id: str) -> None: res.raise_for_status() except requests.RequestException as err: msg = f"Could not delete subscription {subscription_id}" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err # Registration API @@ -1624,7 +1603,6 @@ def get_registration_list(self, *, limit: PositiveInt = None) -> List[Registrati return adapter.validate_python(items) except requests.RequestException as err: msg = "Could not load registrations!" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def post_registration(self, registration: Registration): @@ -1654,7 +1632,6 @@ def post_registration(self, registration: Registration): res.raise_for_status() except requests.RequestException as err: msg = f"Could not send registration {registration.id}!" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def get_registration(self, registration_id: str) -> Registration: @@ -1677,7 +1654,6 @@ def get_registration(self, registration_id: str) -> Registration: res.raise_for_status() except requests.RequestException as err: msg = f"Could not load registration {registration_id} !" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def update_registration(self, registration: Registration): @@ -1707,7 +1683,6 @@ def update_registration(self, registration: Registration): res.raise_for_status() except requests.RequestException as err: msg = f"Could not update registration {registration.id} !" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def delete_registration(self, registration_id: str) -> None: @@ -1727,7 +1702,6 @@ def delete_registration(self, registration_id: str) -> None: res.raise_for_status() except requests.RequestException as err: msg = f"Could not delete registration {registration_id} !" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err # Batch operation API @@ -1811,7 +1785,6 @@ def update(self, res.raise_for_status() except requests.RequestException as err: msg = f"Update operation '{action_type}' failed!" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def query( @@ -1862,7 +1835,6 @@ def query( return items except requests.RequestException as err: msg = "Query operation failed!" - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def notify(self, message: Message) -> None: @@ -1901,7 +1873,6 @@ def notify(self, message: Message) -> None: f"Sending notifcation message failed! \n " f"{message.model_dump_json(indent=2)}" ) - self.log_error(err=err, msg=msg) raise BaseHttpClientException(message=msg, response=err.response) from err def post_command( diff --git a/tests/clients/test_ngsi_v2_cb.py b/tests/clients/test_ngsi_v2_cb.py index ad0416d3..93a9ee07 100644 --- a/tests/clients/test_ngsi_v2_cb.py +++ b/tests/clients/test_ngsi_v2_cb.py @@ -27,6 +27,7 @@ Query, \ ActionType, \ ContextEntityKeyValues +from filip.clients.exceptions import BaseHttpClientException from filip.models.ngsi_v2.base import AttrsFormat, EntityPattern, Status, \ NamedMetadata @@ -1897,6 +1898,18 @@ def test_does_entity_exist(self): entity_type=entity.type) ) + @clean_test(fiware_service=settings.FIWARE_SERVICE, + fiware_servicepath=settings.FIWARE_SERVICEPATH, + cb_url=settings.CB_URL) + def test_entity_exceptions(self): + entity1 = self.entity.model_copy(deep=True) + self.client.post_entity(entity1) + + with self.assertRaises(BaseHttpClientException) as context: + self.client.post_entity(entity1) + self.assertEqual(json.loads(context.exception.response.text)["description"], "Already Exists") + + def tearDown(self) -> None: """ Cleanup test server