Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

232 post entity will not completely override the existing entity #233

1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- add tutorial for protected endpoint with bearer authentication ([#208](https://github.com/RWTH-EBC/FiLiP/issues/208))
- update pandas version to `~=2.1.4` for `python>=3.9` ([#231](https://github.com/RWTH-EBC/FiLiP/pull/231))
- fix: wrong msg in iotac post device ([#214](https://github.com/RWTH-EBC/FiLiP/pull/214))
- add function to override the existing entity ([#232 ](https://github.com/RWTH-EBC/FiLiP/pull/232 ))

#### v0.3.0
- fix: bug in typePattern validation @richardmarston ([#180](https://github.com/RWTH-EBC/FiLiP/pull/180))
Expand Down
19 changes: 18 additions & 1 deletion filip/clients/ngsi_v2/cb.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def post_entity(self,
res.raise_for_status()
except requests.RequestException as err:
if update and err.response.status_code == 422:
return self.update_entity(
return self.override_entity(
entity=entity)
if patch and err.response.status_code == 422:
return self.patch_entity(
Expand Down Expand Up @@ -770,6 +770,23 @@ def update_existing_entity_attributes(
self.log_error(err=err, msg=msg)
raise

def override_entity(self, entity: ContextEntity):
"""
The request payload is an object representing the attributes to
override the existing entity.

Note:
If you want to manipulate you should rather use patch_entity.

Args:
entity (ContextEntity):
Returns:
None
"""
self.replace_entity_attributes(entity_id=entity.id,
entity_type=entity.type,
attrs=entity.get_properties())

def replace_entity_attributes(
self,
entity_id: str,
Expand Down
165 changes: 164 additions & 1 deletion tests/clients/test_ngsi_v2_cb.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

import paho.mqtt.client as mqtt
from datetime import datetime, timedelta

import requests
from requests import RequestException
from filip.models.base import FiwareHeader
from filip.utils.simple_ql import QueryString
Expand Down Expand Up @@ -216,7 +218,10 @@ def test_entity_operations(self):
fiware_header=self.fiware_header) as client:
client.post_entity(entity=self.entity, update=True)
res_entity = client.get_entity(entity_id=self.entity.id)
client.get_entity(entity_id=self.entity.id, attrs=['temperature'])
self.assertEqual(res_entity,
client.get_entity(
entity_id=self.entity.id,
attrs=list(res_entity.get_attribute_names())))
self.assertEqual(client.get_entity_attributes(
entity_id=self.entity.id), res_entity.get_properties(
response_format='dict'))
Expand All @@ -229,6 +234,164 @@ def test_entity_operations(self):
client.update_entity(entity=res_entity)
self.assertEqual(client.get_entity(entity_id=self.entity.id),
res_entity)
# delete attribute
res_entity.delete_attributes(attrs={'pressure': ContextAttribute(
type='Number', value=1050)})
client.post_entity(entity=res_entity, update=True)
self.assertEqual(client.get_entity(entity_id=self.entity.id),
res_entity)

@clean_test(fiware_service=settings.FIWARE_SERVICE,
fiware_servicepath=settings.FIWARE_SERVICEPATH,
cb_url=settings.CB_URL)
def test_entity_update(self):
"""
Test different ways (post, update, override, patch) to update entity
Both with the update scenario
1) append attribute
2) update existing attribute value
1) delete attribute

Returns:

"""
with ContextBrokerClient(
url=settings.CB_URL,
fiware_header=self.fiware_header) as client:
entity_init = self.entity.model_copy(deep=True)
attr_init = entity_init.get_attribute("temperature")
attr_init.metadata = {
"metadata_init": {
"type": "Text",
"value": "something"}
}
attr_append = NamedContextAttribute(**{
"name": 'pressure',
"type": 'Number',
"value": 1050})
entity_init.update_attribute(attrs=[attr_init])

# Post
if "post":
client.post_entity(entity=entity_init, update=True)
entity_post = entity_init.model_copy(deep=True)
# 1) append attribute
entity_post.add_attributes(attrs=[attr_append])
client.post_entity(entity=entity_post, patch=True)
self.assertEqual(client.get_entity(entity_id=entity_post.id),
entity_post)
# 2) update existing attribute value
attr_append_update = NamedContextAttribute(**{
"name": 'pressure',
"type": 'Number',
"value": 2050})
entity_post.update_attribute(attrs=[attr_append_update])
client.post_entity(entity=entity_post, patch=True)
self.assertEqual(client.get_entity(entity_id=entity_post.id),
entity_post)
# 3) delete attribute
entity_post.delete_attributes(attrs=[attr_append])
client.post_entity(entity=entity_post, update=True)
self.assertEqual(client.get_entity(entity_id=entity_post.id),
entity_post)
clear_all(fiware_header=self.fiware_header,
cb_url=settings.CB_URL)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@djs0109 After each step (so after post, update_entity and override_entity) I would clear the OCB and reset the variable attr_append:

clear_all(fiware_header=self.fiware_header, cb_url=settings.CB_URL)
attr_append = NamedContextAttribute(**{
    "name": 'pressure',
    "type": 'Number',
    "value": 1050})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. I add the clear_all, and use attr_append_update for updating attribute, so that the attr_append will not be touched during the whole test.

# update_entity()
if "update_entity":
client.post_entity(entity=entity_init, update=True)
entity_update = entity_init.model_copy(deep=True)
# 1) append attribute
entity_update.add_attributes(attrs=[attr_append])
# change the value of existing attributes
entity_update.temperature.value = 30
with self.assertRaises(requests.RequestException):
client.update_entity(entity=entity_update,
append_strict=True)
entity_updated = client.get_entity(entity_id=entity_update.id)
self.assertEqual(entity_updated.get_attribute_names(),
entity_update.get_attribute_names())
self.assertNotEqual(entity_updated.temperature.value,
entity_update.temperature.value)
# change back the value
entity_update.temperature.value = 20.0
# 2) update existing attribute value
attr_append_update = NamedContextAttribute(**{
"name": 'pressure',
"type": 'Number',
"value": 2050})
entity_update.update_attribute(attrs=[attr_append_update])
client.update_entity(entity=ContextEntity(
**{
"id": entity_update.id,
"type": entity_update.type,
"pressure": {
"type": 'Number',
"value": 2050
}
}
))
self.assertEqual(client.get_entity(entity_id=entity_update.id),
entity_update)
# 3) delete attribute
entity_update.delete_attributes(attrs=[attr_append])
client.update_entity(entity=entity_update)
self.assertNotEqual(client.get_entity(entity_id=entity_update.id),
entity_update)
clear_all(fiware_header=self.fiware_header,
cb_url=settings.CB_URL)

# override_entity()
if "override_entity":
client.post_entity(entity=entity_init, update=True)
entity_override = entity_init.model_copy(deep=True)
# 1) append attribute
entity_override.add_attributes(attrs=[attr_append])
client.override_entity(entity=entity_override)
self.assertEqual(client.get_entity(entity_id=entity_override.id),
entity_override)
# 2) update existing attribute value
attr_append_update = NamedContextAttribute(**{
"name": 'pressure',
"type": 'Number',
"value": 2050})
entity_override.update_attribute(attrs=[attr_append_update])
client.override_entity(entity=entity_override)
self.assertEqual(client.get_entity(entity_id=entity_override.id),
entity_override)
# 3) delete attribute
entity_override.delete_attributes(attrs=[attr_append])
client.override_entity(entity=entity_override)
self.assertEqual(client.get_entity(entity_id=entity_override.id),
entity_override)
clear_all(fiware_header=self.fiware_header,
cb_url=settings.CB_URL)

# patch_entity
if "patch_entity":
client.post_entity(entity=entity_init, update=True)
entity_patch = entity_init.model_copy(deep=True)
# 1) append attribute
entity_patch.add_attributes(attrs=[attr_append])
client.patch_entity(entity=entity_patch)
self.assertEqual(client.get_entity(entity_id=entity_patch.id),
entity_patch)
# 2) update existing attribute value
attr_append_update = NamedContextAttribute(**{
"name": 'pressure',
"type": 'Number',
"value": 2050})
entity_patch.update_attribute(attrs=[attr_append_update])
client.patch_entity(entity=entity_patch)
self.assertEqual(client.get_entity(entity_id=entity_patch.id),
entity_patch)
# 3) delete attribute
entity_patch.delete_attributes(attrs=[attr_append])
client.patch_entity(entity=entity_patch)
self.assertEqual(client.get_entity(entity_id=entity_patch.id),
entity_patch)
clear_all(fiware_header=self.fiware_header,
cb_url=settings.CB_URL)

@clean_test(fiware_service=settings.FIWARE_SERVICE,
fiware_servicepath=settings.FIWARE_SERVICEPATH,
Expand Down