From 76ea36d4d50662425baea6a825783dbe7f85a98c Mon Sep 17 00:00:00 2001 From: "j.azzam" Date: Tue, 30 Jul 2024 14:04:34 +0200 Subject: [PATCH 1/4] Making expressionLanguage attribute optional in ServiceGroup and Device. If it is set to None, it will be set to 'jexl' --- filip/models/ngsi_v2/iot.py | 4 ++-- filip/utils/validators.py | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/filip/models/ngsi_v2/iot.py b/filip/models/ngsi_v2/iot.py index 105b33b4..9972d8b3 100644 --- a/filip/models/ngsi_v2/iot.py +++ b/filip/models/ngsi_v2/iot.py @@ -250,7 +250,7 @@ def validate_cbHost(cls, value): "IoT Agents to store information along with the devices " "in the Device Registry." ) - expressionLanguage: ExpressionLanguage = Field( + expressionLanguage: Optional[ExpressionLanguage] = Field( default=ExpressionLanguage.JEXL, description="optional boolean value, to set expression language used " "to compute expressions, possible values are: " @@ -321,7 +321,7 @@ class DeviceSettings(BaseModel): description="Name of the device transport protocol, for the IoT Agents " "with multiple transport protocols." ) - expressionLanguage: ExpressionLanguage = Field( + expressionLanguage: Optional[ExpressionLanguage] = Field( default=ExpressionLanguage.JEXL, description="optional boolean value, to set expression language used " "to compute expressions, possible values are: " diff --git a/filip/utils/validators.py b/filip/utils/validators.py index 7f8ee218..b16b16ef 100644 --- a/filip/utils/validators.py +++ b/filip/utils/validators.py @@ -223,6 +223,8 @@ def validate_jexl_expression(expression, attribute_name, device_id): def validate_device_expression_language(cls, expressionLanguage): if expressionLanguage == "legacy": warnings.warn(f"Using 'LEGACY' expression language inside {cls.__name__} is deprecated. Use 'JEXL' instead.") + elif expressionLanguage is None: + expressionLanguage = "jexl" return expressionLanguage @@ -231,5 +233,7 @@ def validate_service_group_expression_language(cls, expressionLanguage): if expressionLanguage == "legacy": warnings.warn(f"Using 'LEGACY' expression language inside {cls.__name__} is deprecated and does not work " f"anymore, because each device uses 'JEXL' as default.") + elif expressionLanguage is None: + expressionLanguage = "jexl" return expressionLanguage From 8412915e06f193020dd11c8553bd19241fa8aa65 Mon Sep 17 00:00:00 2001 From: "j.azzam" Date: Tue, 30 Jul 2024 14:21:56 +0200 Subject: [PATCH 2/4] Adding tests for setting expression language to None in ServiceGroup and Device --- filip/models/ngsi_v2/iot.py | 4 ++-- tests/models/test_ngsi_v2_iot.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/filip/models/ngsi_v2/iot.py b/filip/models/ngsi_v2/iot.py index 9972d8b3..bd643432 100644 --- a/filip/models/ngsi_v2/iot.py +++ b/filip/models/ngsi_v2/iot.py @@ -254,7 +254,7 @@ def validate_cbHost(cls, value): default=ExpressionLanguage.JEXL, description="optional boolean value, to set expression language used " "to compute expressions, possible values are: " - "legacy or jexl, but legacy is deprecated." + "legacy or jexl, but legacy is deprecated. If it is set None, jexl is used." ) valid_expressionLanguage = field_validator("expressionLanguage")(validate_service_group_expression_language) explicitAttrs: Optional[bool] = Field( @@ -325,7 +325,7 @@ class DeviceSettings(BaseModel): default=ExpressionLanguage.JEXL, description="optional boolean value, to set expression language used " "to compute expressions, possible values are: " - "legacy or jexl, but legacy is deprecated." + "legacy or jexl, but legacy is deprecated. If it is set None, jexl is used." ) valid_expressionLanguage = field_validator("expressionLanguage")(validate_device_expression_language) explicitAttrs: Optional[bool] = Field( diff --git a/tests/models/test_ngsi_v2_iot.py b/tests/models/test_ngsi_v2_iot.py index fd1a3c13..fe99111b 100644 --- a/tests/models/test_ngsi_v2_iot.py +++ b/tests/models/test_ngsi_v2_iot.py @@ -215,6 +215,22 @@ def test_expression_language(self): assert len(w) == 2 + # Test for expression language set to None + service_group_null_expression = ServiceGroup( + entity_type='Thing', + apikey=api_key, + resource='/iot/json', + expressionLanguage=None) + self.assertEqual(service_group_null_expression.expressionLanguage, ExpressionLanguage.JEXL) + + device4 = Device(device_id="null_expression_device", + entity_name="null_expression_entity", + entity_type="test_entity_type", + transport=TransportProtocol.MQTT, + protocol=PayloadProtocol.IOTA_JSON, + expressionLanguage=None) + self.assertEqual(device4.expressionLanguage, ExpressionLanguage.JEXL) + def test_add_device_attributes(self): """ Test the device model regarding the behavior with devices attributes. From a5513c069af7ce135664a617d29126aa091c0b98 Mon Sep 17 00:00:00 2001 From: "j.azzam" Date: Tue, 30 Jul 2024 14:30:20 +0200 Subject: [PATCH 3/4] Fixing tutorial e8 of filip --- .../e8_multientity_and_expression_language.py | 5 +++-- .../e8_multientity_and_expression_language_solution.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tutorials/ngsi_v2/e8_multientity_and_expression_language/e8_multientity_and_expression_language.py b/tutorials/ngsi_v2/e8_multientity_and_expression_language/e8_multientity_and_expression_language.py index 9e2b6966..ad44cb0a 100644 --- a/tutorials/ngsi_v2/e8_multientity_and_expression_language/e8_multientity_and_expression_language.py +++ b/tutorials/ngsi_v2/e8_multientity_and_expression_language/e8_multientity_and_expression_language.py @@ -33,6 +33,7 @@ ExpressionLanguage) from filip.utils.cleanup import clear_all from paho.mqtt import client as mqtt_client +from paho.mqtt.client import CallbackAPIVersion # Host address of Context Broker CB_URL = "http://localhost:1026" @@ -103,7 +104,7 @@ ) iota_client.post_device(device=device2) - client = mqtt_client.Client() + client = mqtt_client.Client(callback_api_version=CallbackAPIVersion.VERSION2) client.username_pw_set(username="", password="") client.connect(MQTT_BROKER_HOST, MQTT_BROKER_PORT) client.loop_start() @@ -147,7 +148,7 @@ ) iota_client.post_device(device=device3) - client = mqtt_client.Client() + client = mqtt_client.Client(callback_api_version=CallbackAPIVersion.VERSION2) client.username_pw_set(username="", password="") client.connect(MQTT_BROKER_HOST, MQTT_BROKER_PORT) client.loop_start() diff --git a/tutorials/ngsi_v2/e8_multientity_and_expression_language/e8_multientity_and_expression_language_solution.py b/tutorials/ngsi_v2/e8_multientity_and_expression_language/e8_multientity_and_expression_language_solution.py index 2c20098c..b826d288 100644 --- a/tutorials/ngsi_v2/e8_multientity_and_expression_language/e8_multientity_and_expression_language_solution.py +++ b/tutorials/ngsi_v2/e8_multientity_and_expression_language/e8_multientity_and_expression_language_solution.py @@ -33,6 +33,7 @@ ExpressionLanguage) from filip.utils.cleanup import clear_all from paho.mqtt import client as mqtt_client +from paho.mqtt.client import CallbackAPIVersion # Host address of Context Broker CB_URL = "http://localhost:1026" @@ -114,7 +115,7 @@ ) iota_client.post_device(device=device2) - client = mqtt_client.Client() + client = mqtt_client.Client(callback_api_version=CallbackAPIVersion.VERSION2) client.username_pw_set(username="", password="") client.connect(MQTT_BROKER_HOST, MQTT_BROKER_PORT) client.loop_start() @@ -172,7 +173,7 @@ ) iota_client.post_device(device=device3) - client = mqtt_client.Client() + client = mqtt_client.Client(callback_api_version=CallbackAPIVersion.VERSION2) client.username_pw_set(username="", password="") client.connect(MQTT_BROKER_HOST, MQTT_BROKER_PORT) client.loop_start() From 5bc93e3202481ee7d8e463e8f695b1f9352e6524 Mon Sep 17 00:00:00 2001 From: JunsongDu Date: Tue, 30 Jul 2024 15:30:06 +0200 Subject: [PATCH 4/4] chore: merge the same validation functions for expressionlanguage --- filip/models/ngsi_v2/iot.py | 11 ++++++----- filip/utils/validators.py | 16 +++------------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/filip/models/ngsi_v2/iot.py b/filip/models/ngsi_v2/iot.py index bd643432..d6950954 100644 --- a/filip/models/ngsi_v2/iot.py +++ b/filip/models/ngsi_v2/iot.py @@ -14,9 +14,10 @@ BaseAttribute, \ BaseValueAttribute, \ BaseNameAttribute -from filip.utils.validators import (validate_fiware_datatype_string_protect, validate_fiware_datatype_standard, - validate_jexl_expression, validate_device_expression_language, - validate_service_group_expression_language) +from filip.utils.validators import (validate_fiware_datatype_string_protect, + validate_fiware_datatype_standard, + validate_jexl_expression, + validate_expression_language) logger = logging.getLogger() @@ -256,7 +257,7 @@ def validate_cbHost(cls, value): "to compute expressions, possible values are: " "legacy or jexl, but legacy is deprecated. If it is set None, jexl is used." ) - valid_expressionLanguage = field_validator("expressionLanguage")(validate_service_group_expression_language) + valid_expressionLanguage = field_validator("expressionLanguage")(validate_expression_language) explicitAttrs: Optional[bool] = Field( default=False, description="optional boolean value, to support selective ignore " @@ -327,7 +328,7 @@ class DeviceSettings(BaseModel): "to compute expressions, possible values are: " "legacy or jexl, but legacy is deprecated. If it is set None, jexl is used." ) - valid_expressionLanguage = field_validator("expressionLanguage")(validate_device_expression_language) + valid_expressionLanguage = field_validator("expressionLanguage")(validate_expression_language) explicitAttrs: Optional[bool] = Field( default=False, description="optional boolean value, to support selective ignore " diff --git a/filip/utils/validators.py b/filip/utils/validators.py index b16b16ef..551574b9 100644 --- a/filip/utils/validators.py +++ b/filip/utils/validators.py @@ -220,20 +220,10 @@ def validate_jexl_expression(expression, attribute_name, device_id): return expression -def validate_device_expression_language(cls, expressionLanguage): +def validate_expression_language(cls, expressionLanguage): if expressionLanguage == "legacy": - warnings.warn(f"Using 'LEGACY' expression language inside {cls.__name__} is deprecated. Use 'JEXL' instead.") + warnings.warn(f"Using 'LEGACY' expression language inside {cls.__name__} is " + f"deprecated. Use 'JEXL' instead.") elif expressionLanguage is None: expressionLanguage = "jexl" - - return expressionLanguage - - -def validate_service_group_expression_language(cls, expressionLanguage): - if expressionLanguage == "legacy": - warnings.warn(f"Using 'LEGACY' expression language inside {cls.__name__} is deprecated and does not work " - f"anymore, because each device uses 'JEXL' as default.") - elif expressionLanguage is None: - expressionLanguage = "jexl" - return expressionLanguage