Skip to content

Commit

Permalink
Merge branch 'master' into Fix_for_4261
Browse files Browse the repository at this point in the history
  • Loading branch information
PradyumnAgrawal05 authored Feb 8, 2024
2 parents 1be685a + 839d303 commit 3bb609b
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 34 deletions.
4 changes: 4 additions & 0 deletions CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
- Fix: memory leak in POST /v2/op/notify operation (#4261)
- Fix: changed the default value of `-dbTimeout` to 0 to resolve conflict with `-dbURI` (#4496)
- Fix: wrong INFO startup log showing ORION_MONGO_TIMEOUT, ORION_IN_REQ_PAYLOAD_MAX_SIZE and ORION_OUT_REQ_MSG_MAX_SIZE env var values (#4496)
- Fix: return 400 Bad Request when subject.entities exists but it is an empty array (#4499)

8 changes: 6 additions & 2 deletions src/app/contextBroker/contextBroker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ PaArgument paArgs[] =
{ "-dbDisableRetryWrites", &dbDisableRetryWrites, "MONGO_DISABLE_RETRY_WRITES", PaBool, PaOpt, false, false, true, DBDISABLERETRYWRITES_DESC },

{ "-db", dbName, "MONGO_DB", PaString, PaOpt, _i "orion", PaNL, PaNL, DB_DESC },
{ "-dbTimeout", &dbTimeout, "MONGO_TIMEOUT", PaULong, PaOpt, 10000, 0, UINT_MAX, DB_TMO_DESC },
{ "-dbTimeout", &dbTimeout, "MONGO_TIMEOUT", PaULong, PaOpt, 0, 0, UINT_MAX, DB_TMO_DESC },
{ "-dbPoolSize", &dbPoolSize, "MONGO_POOL_SIZE", PaInt, PaOpt, 10, 1, 10000, DBPS_DESC },

{ "-ipv4", &useOnlyIPv4, "USEIPV4", PaBool, PaOpt, false, false, true, USEIPV4_DESC },
Expand Down Expand Up @@ -979,13 +979,17 @@ static void logEnvVars(void)
{
LM_I(("env var ORION_%s (%s): %d", aP->envName, aP->option, *((int*) aP->varP)));
}
else if (aP->type == PaULong)
{
LM_I(("env var ORION_%s (%s): %d", aP->envName, aP->option, *((unsigned long*) aP->varP)));
}
else if (aP->type == PaDouble)
{
LM_I(("env var ORION_%s (%s): %d", aP->envName, aP->option, *((double*) aP->varP)));
}
else
{
LM_I(("env var ORION_%s (%s): %d", aP->envName, aP->option));
LM_E(("cannot show env var ORION_%s (%s) due to unrecognized type: %d", aP->envName, aP->option, aP->type));
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/lib/jsonParseV2/parseSubscription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,11 @@ static std::string parseSubject(ConnectionInfo* ciP, SubscriptionUpdate* subsP,
return badInput(ciP, errorString);
}

if (subsP->subject.entities.size() == 0)
{
return badInput(ciP, "subject entities is empty");
}

// Condition
if (subject.HasMember("condition"))
{
Expand Down
2 changes: 1 addition & 1 deletion src/lib/mongoDriver/mongoConnectionPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ static std::string composeMongoUri
optionPrefix = "&";
}
}

LM_T(LmtMongo, ("MongoDB connection URI: '%s'", offuscatePassword(uri, passwd).c_str()));

return uri;
Expand Down
43 changes: 13 additions & 30 deletions src/lib/ngsiNotify/Notifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ static bool setPayload
const std::string& notifPayload,
const SubscriptionId& subscriptionId,
Entity& en,
const std::string& service,
const std::string& token,
std::map<std::string, std::string>* replacementsP,
const std::vector<std::string>& attrsFilter,
bool blacklist,
const std::vector<std::string>& metadataFilter,
Expand Down Expand Up @@ -171,9 +170,7 @@ static bool setPayload
}
else
{
std::map<std::string, std::string> replacements;
buildReplacementsMap(en, service, token, &replacements);
if (!macroSubstitute(payloadP, notifPayload, &replacements, ""))
if (!macroSubstitute(payloadP, notifPayload, replacementsP, ""))
{
return false;
}
Expand All @@ -197,19 +194,12 @@ static bool setPayload
static bool setJsonPayload
(
orion::CompoundValueNode* json,
const Entity& en,
const std::string& service,
const std::string& token,
std::map<std::string, std::string>* replacementsP,
std::string* payloadP,
std::string* mimeTypeP
)
{
// Prepare a map for macro replacements. We firstly tried to pass Entity object to
// orion::CompoundValueNode()::toJson(), but the include Entity.h in CompoundValueNode.h
// makes compiler to cry (maybe some kind of circular dependency problem?)
std::map<std::string, std::string> replacements;
buildReplacementsMap(en, service, token, &replacements);
*payloadP = json->toJson(&replacements);
*payloadP = json->toJson(replacementsP);
*mimeTypeP = "application/json"; // this can be overriden by headers field
return true;
}
Expand Down Expand Up @@ -247,21 +237,14 @@ static bool setNgsiPayload
const Entity& ngsi,
const SubscriptionId& subscriptionId,
Entity& en,
const std::string& service,
const std::string& token,
std::map<std::string, std::string>* replacementsP,
const std::vector<std::string>& attrsFilter,
bool blacklist,
const std::vector<std::string>& metadataFilter,
std::string* payloadP,
RenderFormat renderFormat
)
{
// Prepare a map for macro replacements. We firstly tried to pass Entity object to
// orion::CompoundValueNode()::toJson(), but the include Entity.h in CompoundValueNode.h
// makes compiler to cry (maybe some kind of circular dependency problem?)
std::map<std::string, std::string> replacements;
buildReplacementsMap(en, service, token, &replacements);

NotifyContextRequest ncr;
ContextElementResponse cer;

Expand All @@ -273,7 +256,7 @@ static bool setNgsiPayload
else
{
// If id is not found in the replacements macro, we use en.id.
effectiveId = removeQuotes(smartStringValue(ngsi.id, &replacements, '"' + en.id + '"'));
effectiveId = removeQuotes(smartStringValue(ngsi.id, replacementsP, '"' + en.id + '"'));
}

std::string effectiveType;
Expand All @@ -284,7 +267,7 @@ static bool setNgsiPayload
else
{
// If type is not found in the replacements macro, we use en.type.
effectiveType = removeQuotes(smartStringValue(ngsi.type, &replacements, '"' + en.type + '"'));
effectiveType = removeQuotes(smartStringValue(ngsi.type, replacementsP, '"' + en.type + '"'));
}

cer.entity.fill(effectiveId, effectiveType, en.isPattern, en.servicePath);
Expand All @@ -310,11 +293,11 @@ static bool setNgsiPayload

if ((renderFormat == NGSI_V2_SIMPLIFIEDNORMALIZED) || (renderFormat == NGSI_V2_SIMPLIFIEDKEYVALUES))
{
*payloadP = ncr.toJson(renderFormat, attrsFilter, blacklist, metadataFilter, &replacements);
*payloadP = ncr.toJson(renderFormat, attrsFilter, blacklist, metadataFilter, replacementsP);
}
else
{
*payloadP = ncr.toJson(NGSI_V2_NORMALIZED, attrsFilter, blacklist, metadataFilter, &replacements);
*payloadP = ncr.toJson(NGSI_V2_NORMALIZED, attrsFilter, blacklist, metadataFilter, replacementsP);
}

return true;
Expand Down Expand Up @@ -354,7 +337,7 @@ static SenderThreadParams* buildSenderParamsCustom

// Used by several macroSubstitute() calls along this function
std::map<std::string, std::string> replacements;
buildReplacementsMap(en, service, xauthToken, &replacements);
buildReplacementsMap(en, tenant, xauthToken, &replacements);

//
// 1. Verb/Method
Expand Down Expand Up @@ -396,7 +379,7 @@ static SenderThreadParams* buildSenderParamsCustom
{
bool includePayload = (notification.type == ngsiv2::HttpNotification ? notification.httpInfo.includePayload : notification.mqttInfo.includePayload);
std::string notifPayload = (notification.type == ngsiv2::HttpNotification ? notification.httpInfo.payload : notification.mqttInfo.payload);
if (!setPayload(includePayload, notifPayload, subscriptionId, en, tenant, xauthToken, attrsFilter, blacklist, metadataFilter, &payload, &mimeType, &renderFormat))
if (!setPayload(includePayload, notifPayload, subscriptionId, en, &replacements, attrsFilter, blacklist, metadataFilter, &payload, &mimeType, &renderFormat))
{
// Warning already logged in macroSubstitute()
return NULL;
Expand All @@ -405,14 +388,14 @@ static SenderThreadParams* buildSenderParamsCustom
else if (customPayloadType == ngsiv2::CustomPayloadType::Json)
{
orion::CompoundValueNode* json = (notification.type == ngsiv2::HttpNotification ? notification.httpInfo.json : notification.mqttInfo.json);
setJsonPayload(json, en, tenant, xauthToken, &payload, &mimeType);
setJsonPayload(json, &replacements, &payload, &mimeType);
renderFormat = NGSI_V2_CUSTOM;
}
else // customPayloadType == ngsiv2::CustomPayloadType::Ngsi
{
// Important to use const& for Entity here. Otherwise problems may occur in the object release logic
const Entity& ngsi = (notification.type == ngsiv2::HttpNotification ? notification.httpInfo.ngsi : notification.mqttInfo.ngsi);
if (!setNgsiPayload(ngsi, subscriptionId, en, tenant, xauthToken, attrsFilter, blacklist, metadataFilter, &payload, renderFormat))
if (!setNgsiPayload(ngsi, subscriptionId, en, &replacements, attrsFilter, blacklist, metadataFilter, &payload, renderFormat))
{
// Warning already logged in macroSubstitute()
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion test/functionalTest/cases/3658_env_vars/env_vars.test
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Extended Usage: contextBroker [option '-U' (extended usage)]
[option '-dbSSL' (enable SSL connection to DB)] ORION_MONGO_SSL FALSE /FALSE/
[option '-dbDisableRetryWrites' (set retryWrite parameter to false in DB connect] ORION_MONGO_DISABLE_RETRY_WRITES FALSE /FALSE/
[option '-db' <database name>] ORION_MONGO_DB 'orion' /'orion'/
[option '-dbTimeout' <timeout in milliseconds for connections to the replica set] ORION_MONGO_TIMEOUT 0 <= 10000 /10000/ <= 4294967295
[option '-dbTimeout' <timeout in milliseconds for connections to the replica set] ORION_MONGO_TIMEOUT 0 <= 0 /0/ <= 4294967295
[option '-dbPoolSize' <database connection pool size>] ORION_MONGO_POOL_SIZE 1 <= 10 /10/ <= 10000
[option '-ipv4' (use ip v4 only)] ORION_USEIPV4 FALSE /FALSE/
[option '-ipv6' (use ip v6 only)] ORION_USEIPV6 FALSE /FALSE/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
# Copyright 2024 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--
Subscription without entities return error

--SHELL-INIT--
dbInit CB
brokerStart CB

--SHELL--

#
# 01. Create subscription without subject.entities field, see error
# 02. Create subscription with subject.entities field with 0 items, see error
# 03. Create subscription
# 04. Update subscription without subject.entities field, see error
# 05. Update subscription with subject.entities field with 0 items, see error
#


echo "01. Create subscription without subject.entities field, see error"
echo "================================================================="
payload='{
"subject": {
},
"notification": {
"http": {
"url": "http://127.0.0.1:'${LISTENER_PORT}'/notify"
}
}
}'
orionCurl --url /v2/subscriptions --payload "$payload"
echo
echo


echo "02. Create subscription with subject.entities field with 0 items, see error"
echo "==========================================================================="
payload='{
"subject": {
"entities": [
]
},
"notification": {
"http": {
"url": "http://127.0.0.1:'${LISTENER_PORT}'/notify"
}
}
}'
orionCurl --url /v2/subscriptions --payload "$payload"
echo
echo


echo "03. Create subscription"
echo "======================="
payload='{
"subject": {
"entities": [
{
"id" : "E",
"type": "T"
}
]
},
"notification": {
"http": {
"url": "http://127.0.0.1:'${LISTENER_PORT}'/notify"
}
}
}'
orionCurl --url /v2/subscriptions --payload "$payload"
echo
echo


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


echo "04. Update subscription without subject.entities field, see error"
echo "================================================================="
payload='{
"subject": {
}
}'
orionCurl --url /v2/subscriptions/$SUB_ID -X PATCH --payload "$payload"
echo
echo


echo "05. Update subscription with subject.entities field with 0 items, see error"
echo "==========================================================================="
payload='{
"subject": {
"entities": [
]
}
}'
orionCurl --url /v2/subscriptions/$SUB_ID -X PATCH --payload "$payload"
echo
echo


--REGEXPECT--
01. Create subscription without subject.entities field, see error
=================================================================
HTTP/1.1 400 Bad Request
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
Content-Length: 68

{
"description": "no subject entities specified",
"error": "BadRequest"
}


02. Create subscription with subject.entities field with 0 items, see error
===========================================================================
HTTP/1.1 400 Bad Request
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
Content-Length: 64

{
"description": "subject entities is empty",
"error": "BadRequest"
}


03. Create subscription
=======================
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



04. Update subscription without subject.entities field, see error
=================================================================
HTTP/1.1 400 Bad Request
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
Content-Length: 68

{
"description": "no subject entities specified",
"error": "BadRequest"
}


05. Update subscription with subject.entities field with 0 items, see error
===========================================================================
HTTP/1.1 400 Bad Request
Date: REGEX(.*)
Fiware-Correlator: REGEX([0-9a-f\-]{36})
Content-Type: application/json
Content-Length: 64

{
"description": "subject entities is empty",
"error": "BadRequest"
}


--TEARDOWN--
brokerStop CB
dbDrop CB

0 comments on commit 3bb609b

Please sign in to comment.