Skip to content

Commit

Permalink
Merge pull request #4436 from telefonicaid/bug/4435-ngsi-patching-spe…
Browse files Browse the repository at this point in the history
…cial-attr-types

FIX DateTime and geo:json support in custom notifications using ngsi patching
  • Loading branch information
danielvillalbamota authored Oct 17, 2023
2 parents 6689aa1 + 470932c commit 865c60b
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
- Add: servicePath field to builtin attributes (#2877)
- Add: notification.mqtt.retain and notification.mqttCustom.retain flag for MQTT retain in notifications (#4388)
- Fix: DateTime and geo:json types were not supported in custom notifications using ngsi patching (#4435)
- Fix: logDeprecate not working correctly (`geo:json` wrongly considered as deprecated)
- Fix: improve error traces (#4387)
- Add: CLI parameter -dbUri / env var ORION_MONGO_URI (#3794)
Expand Down
2 changes: 1 addition & 1 deletion src/lib/jsonParseV2/jsonRequestTreat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ std::string jsonRequestTreat
case EntityAttributeRequest:
releaseP->attribute = &parseDataP->attr.attribute;
releaseP->attribute->name = compV[4];
answer = parseContextAttribute(ciP, &parseDataP->attr.attribute);
answer = parseContextAttribute(ciP, &parseDataP->attr.attribute, true);
if (answer != "OK")
{
return answer;
Expand Down
16 changes: 9 additions & 7 deletions src/lib/jsonParseV2/parseContextAttribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ static std::string parseContextAttributeObject
(
const rapidjson::Value& start,
ContextAttribute* caP,
bool* compoundVector
bool* compoundVector,
bool checkAttrSpecialTypes
)
{
// This is NGSIv2 parsing and in NGSIv2, no value means implicit null. Note that
Expand Down Expand Up @@ -215,7 +216,7 @@ static std::string parseContextAttributeObject
}

// Is it a (not null) date?
if (((caP->type == DATE_TYPE) || (caP->type == DATE_TYPE_ALT)) && (caP->valueType != orion::ValueTypeNull))
if (checkAttrSpecialTypes && ((caP->type == DATE_TYPE) || (caP->type == DATE_TYPE_ALT)) && (caP->valueType != orion::ValueTypeNull))
{
caP->numberValue = parse8601Time(caP->stringValue);

Expand All @@ -230,7 +231,7 @@ static std::string parseContextAttributeObject
}

// It is a safe GeoJSON?
if (caP->type == GEO_JSON)
if (checkAttrSpecialTypes && caP->type == GEO_JSON)
{
std::string r = checkGeoJson(caP);
if (r != "OK")
Expand All @@ -252,7 +253,8 @@ std::string parseContextAttribute
(
ConnectionInfo* ciP,
const rapidjson::Value::ConstMemberIterator& iter,
ContextAttribute* caP
ContextAttribute* caP,
bool checkAttrSpecialTypes
)
{
std::string name = iter->name.GetString();
Expand Down Expand Up @@ -354,7 +356,7 @@ std::string parseContextAttribute
// Attribute has a regular structure, in which 'value' is mandatory (except in v2)
if (iter->value.HasMember("value") || ciP->apiVersion == V2)
{
std::string r = parseContextAttributeObject(iter->value, caP, &compoundVector);
std::string r = parseContextAttributeObject(iter->value, caP, &compoundVector, checkAttrSpecialTypes);
if (r == "max deep reached")
{
alarmMgr.badInput(clientIp, "max deep reached", "found in ContextAttributeObject::Object");
Expand Down Expand Up @@ -398,7 +400,7 @@ std::string parseContextAttribute
*
* parseContextAttribute -
*/
std::string parseContextAttribute(ConnectionInfo* ciP, ContextAttribute* caP)
std::string parseContextAttribute(ConnectionInfo* ciP, ContextAttribute* caP, bool checkAttrSpecialTypes)
{
rapidjson::Document document;

Expand Down Expand Up @@ -426,7 +428,7 @@ std::string parseContextAttribute(ConnectionInfo* ciP, ContextAttribute* caP)
}

bool compoundVector = false;
std::string r = parseContextAttributeObject(document, caP, &compoundVector);
std::string r = parseContextAttributeObject(document, caP, &compoundVector, checkAttrSpecialTypes);

if (r == "max deep reached")
{
Expand Down
5 changes: 3 additions & 2 deletions src/lib/jsonParseV2/parseContextAttribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ extern std::string parseContextAttribute
(
ConnectionInfo* ciP,
const rapidjson::Value::ConstMemberIterator& iter,
ContextAttribute* caP
ContextAttribute* caP,
bool checkAttrSpecialTypes
);


Expand All @@ -50,6 +51,6 @@ extern std::string parseContextAttribute
*
* parseContextAttribute -
*/
extern std::string parseContextAttribute(ConnectionInfo* ciP, ContextAttribute* caP);
extern std::string parseContextAttribute(ConnectionInfo* ciP, ContextAttribute* caP, bool checkAttrSpecialTypes);

#endif // SRC_LIB_JSONPARSEV2_PARSECONTEXTATTRIBUTE_H_
2 changes: 1 addition & 1 deletion src/lib/jsonParseV2/parseEntity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ std::string parseEntity(ConnectionInfo* ciP, Entity* eP, bool eidInURL)

eP->attributeVector.push_back(caP);

std::string r = parseContextAttribute(ciP, iter, caP);
std::string r = parseContextAttribute(ciP, iter, caP, true);
if (r == "max deep reached")
{
OrionError oe(SccBadRequest, ERROR_DESC_PARSE_MAX_JSON_NESTING, ERROR_PARSE);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/jsonParseV2/parseEntityObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ std::string parseEntityObject

ContextAttribute* caP = new ContextAttribute();

r = parseContextAttribute(ciP, iter, caP);
r = parseContextAttribute(ciP, iter, caP, true);
if (r == "OK")
{
eP->attributeVector.push_back(caP);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/jsonParseV2/parseSubscription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ static std::string parseCustomPayload

ngsi->attributeVector.push_back(caP);

std::string r = parseContextAttribute(ciP, iter, caP);
std::string r = parseContextAttribute(ciP, iter, caP, false);

if (r == "max deep reached")
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
# Copyright 2023 Telefonica Investigacion y Desarrollo, S.A.U
#
# This file is part of Orion Context Broker.
#
# Orion Context Broker is free software: you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# Orion Context Broker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
#
# For those usages not covered by this license please contact with
# iot_support at tid dot es

# VALGRIND_READY - to mark the test ready for valgrindTestSuite.sh

--NAME--
Custom notification NGSI patching special attr types

--SHELL-INIT--
dbInit CB
brokerStart CB 0-255

--SHELL--

#
# 01. Create custom subscription with ngsi patching with DateTime and geo:json
# 02. Get subscription
# 03. Update custom subscription with ngsi patching with DateTime and geo:json
# 04. Get subscription
#

echo "01. Create custom subscription with ngsi patching with DateTime and geo:json"
echo "============================================================================"
payload='{
"description": "DateTime test",
"status": "active",
"subject": {
"entities": [
{
"idPattern": ".*",
"type": "NoiseLevelObserved"
}
],
"condition": {
"attrs": [
"TimeInstant"
],
"notifyOnMetadataChange": true
}
},
"notification": {
"attrs": [
"dateobservedto",
"mylocation"
],
"onlyChangedAttrs": false,
"attrsFormat": "normalized",
"httpCustom": {
"url": "http://127.0.0.1:'${LISTENER_PORT}'/notify",
"ngsi": {
"dateobservedto": {
"type": "DateTime",
"value": "${TimeInstant}"
},
"mylocation": {
"type": "geo:json",
"value": "${location}"
}
}
}
}
}'
orionCurl --url /v2/subscriptions --payload "$payload"
echo
echo


SUB_ID=$(echo "$_responseHeaders" | grep Location | awk -F/ '{ print $4 }' | tr -d "\r\n")


echo "02. Get subscriptions"
echo "====================="
orionCurl --url /v2/subscriptions/$SUB_ID
echo
echo


echo "03. Update custom subscription with ngsi patching with DateTime and geo:json"
echo "============================================================================"
payload='{
"notification": {
"attrs": [
"dateobservedto2",
"mylocation2"
],
"onlyChangedAttrs": false,
"attrsFormat": "normalized",
"httpCustom": {
"url": "http://127.0.0.1:'${LISTENER_PORT}'/notify",
"ngsi": {
"dateobservedto2": {
"type": "DateTime",
"value": "${TimeInstant}"
},
"mylocation2": {
"type": "geo:json",
"value": "${location}"
}
}
}
}
}'
orionCurl --url /v2/subscriptions/$SUB_ID -X PATCH --payload "$payload"
echo
echo


echo "04. Get subscriptions"
echo "====================="
orionCurl --url /v2/subscriptions/$SUB_ID
echo
echo


--REGEXPECT--
01. Create custom subscription with ngsi patching with DateTime and geo:json
============================================================================
HTTP/1.1 201 Created
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Location: /v2/subscriptions/REGEX([0-9a-f]{24})
Content-Length: 0



02. Get subscriptions
=====================
HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
Content-Length: 524

{
"description": "DateTime test",
"id": "REGEX([0-9a-f]{24})",
"notification": {
"attrs": [
"dateobservedto",
"mylocation"
],
"attrsFormat": "normalized",
"covered": false,
"httpCustom": {
"ngsi": {
"dateobservedto": {
"type": "DateTime",
"value": "${TimeInstant}"
},
"mylocation": {
"type": "geo:json",
"value": "${location}"
}
},
"url": "http://127.0.0.1:9997/notify"
},
"onlyChangedAttrs": false
},
"status": "active",
"subject": {
"condition": {
"attrs": [
"TimeInstant"
],
"notifyOnMetadataChange": true
},
"entities": [
{
"idPattern": ".*",
"type": "NoiseLevelObserved"
}
]
}
}


03. Update custom subscription with ngsi patching with DateTime and geo:json
============================================================================
HTTP/1.1 204 No Content
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})



04. Get subscriptions
=====================
HTTP/1.1 200 OK
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
Content-Length: 528

{
"description": "DateTime test",
"id": "REGEX([0-9a-f]{24})",
"notification": {
"attrs": [
"dateobservedto2",
"mylocation2"
],
"attrsFormat": "normalized",
"covered": false,
"httpCustom": {
"ngsi": {
"dateobservedto2": {
"type": "DateTime",
"value": "${TimeInstant}"
},
"mylocation2": {
"type": "geo:json",
"value": "${location}"
}
},
"url": "http://127.0.0.1:9997/notify"
},
"onlyChangedAttrs": false
},
"status": "active",
"subject": {
"condition": {
"attrs": [
"TimeInstant"
],
"notifyOnMetadataChange": true
},
"entities": [
{
"idPattern": ".*",
"type": "NoiseLevelObserved"
}
]
}
}


--TEARDOWN--
brokerStop CB
dbDrop CB

0 comments on commit 865c60b

Please sign in to comment.