diff --git a/src/lib/mongoBackend/MongoCommonUpdate.cpp b/src/lib/mongoBackend/MongoCommonUpdate.cpp
index 8593d6e084..03617d9d50 100644
--- a/src/lib/mongoBackend/MongoCommonUpdate.cpp
+++ b/src/lib/mongoBackend/MongoCommonUpdate.cpp
@@ -3504,7 +3504,7 @@ static unsigned int updateEntity
/* Build CER used for notifying (if needed) */
StringList emptyAttrL;
- ContextElementResponse* notifyCerP = new ContextElementResponse(r, emptyAttrL, true, apiVersion);
+ ContextElementResponse* notifyCerP = new ContextElementResponse(r, emptyAttrL);
// The hasField() check is needed as the entity could have been created with very old Orion version not
// supporting modification/creation dates
@@ -3921,7 +3921,7 @@ static unsigned int updateEntity
notifyCerP->release();
delete notifyCerP;
- notifyCerP = new ContextElementResponse(getObjectFieldF(reply, "value"), emptyAttrL, true, apiVersion);
+ notifyCerP = new ContextElementResponse(getObjectFieldF(reply, "value"), emptyAttrL);
}
}
else
diff --git a/src/lib/mongoBackend/MongoGlobal.cpp b/src/lib/mongoBackend/MongoGlobal.cpp
index 9b0cca0054..85308f228b 100644
--- a/src/lib/mongoBackend/MongoGlobal.cpp
+++ b/src/lib/mongoBackend/MongoGlobal.cpp
@@ -1385,11 +1385,6 @@ static bool isCustomAttr(std::string attrName)
* This method is used by queryContext. It takes a vector with entities and a vector
* with attributes as input and returns the corresponding ContextElementResponseVector or error.
*
-* Note the includeEmpty argument. This is used if we don't want the result to include empty
-* attributes, i.e. the ones that cause ''. This is aimed at
-* subscribeContext case, as empty values can cause problems in the case of federating Context
-* Brokers (the notifyContext is processed as an updateContext and in the latter case, an
-* empty value causes an error)
*/
bool entitiesQuery
(
@@ -1398,7 +1393,6 @@ bool entitiesQuery
const Restriction& res,
ContextElementResponseVector* cerV,
std::string* err,
- bool includeEmpty,
const std::string& tenant,
const std::vector& servicePath,
int offset,
@@ -1636,7 +1630,7 @@ bool entitiesQuery
// Build CER from BSON retrieved from DB
docs++;
LM_T(LmtMongo, ("retrieved document [%d]: '%s'", docs, r.toString().c_str()));
- ContextElementResponse* cer = new ContextElementResponse(r, attrL, includeEmpty, apiVersion);
+ ContextElementResponse* cer = new ContextElementResponse(r, attrL);
// Add builtin attributes and metadata (only in NGSIv2)
if (apiVersion == V2)
diff --git a/src/lib/mongoBackend/MongoGlobal.h b/src/lib/mongoBackend/MongoGlobal.h
index 9b750e01b5..caa6058e8f 100644
--- a/src/lib/mongoBackend/MongoGlobal.h
+++ b/src/lib/mongoBackend/MongoGlobal.h
@@ -230,7 +230,6 @@ extern bool entitiesQuery
const Restriction& res,
ContextElementResponseVector* cerV,
std::string* err,
- bool includeEmpty,
const std::string& tenant,
const std::vector& servicePath,
int offset = DEFAULT_PAGINATION_OFFSET_INT,
diff --git a/src/lib/mongoBackend/mongoQueryContext.cpp b/src/lib/mongoBackend/mongoQueryContext.cpp
index fd8f1799b5..32b51170f2 100644
--- a/src/lib/mongoBackend/mongoQueryContext.cpp
+++ b/src/lib/mongoBackend/mongoQueryContext.cpp
@@ -362,7 +362,6 @@ HttpStatusCode mongoQueryContext
requestP->restriction,
&rawCerV,
&err,
- true,
tenant,
servicePathV,
offset,
diff --git a/src/lib/ngsi/ContextAttributeVector.cpp b/src/lib/ngsi/ContextAttributeVector.cpp
index 81608abe78..5a11b4d89e 100644
--- a/src/lib/ngsi/ContextAttributeVector.cpp
+++ b/src/lib/ngsi/ContextAttributeVector.cpp
@@ -308,10 +308,7 @@ void ContextAttributeVector::fill(const ContextAttributeVector& caV, bool useDef
void ContextAttributeVector::fill
(
const orion::BSONObj& attrs,
- const StringList& attrL,
- bool includeEmpty,
- const std::string& locAttr,
- ApiVersion apiVersion
+ const StringList& attrL
)
{
std::set attrNames;
@@ -346,10 +343,6 @@ void ContextAttributeVector::fill
{
case orion::String:
ca.stringValue = getStringFieldF(attr, ENT_ATTRS_VALUE);
- if (!includeEmpty && ca.stringValue.empty())
- {
- continue;
- }
caP = new ContextAttribute(ca.name, ca.type, ca.stringValue);
break;
@@ -440,7 +433,7 @@ void ContextAttributeVector::fill
void ContextAttributeVector::fill(const orion::BSONObj& attrs)
{
StringList emptyList;
- return fill(attrs, emptyList, true, "", V2);
+ return fill(attrs, emptyList);
}
diff --git a/src/lib/ngsi/ContextAttributeVector.h b/src/lib/ngsi/ContextAttributeVector.h
index 05cc96c260..6c32b17a4f 100644
--- a/src/lib/ngsi/ContextAttributeVector.h
+++ b/src/lib/ngsi/ContextAttributeVector.h
@@ -52,7 +52,7 @@ typedef struct ContextAttributeVector
unsigned int size(void) const;
void release(void);
void fill(const ContextAttributeVector& caV, bool useDefaultType = false, bool cloneCompounds = false);
- void fill(const orion::BSONObj& attrs, const StringList& attrL, bool includeEmpty, const std::string& locAttr, ApiVersion apiVersion);
+ void fill(const orion::BSONObj& attrs, const StringList& attrL);
void fill(const orion::BSONObj& attrs);
int get(const std::string& attributeName) const;
diff --git a/src/lib/ngsi/ContextElementResponse.cpp b/src/lib/ngsi/ContextElementResponse.cpp
index 9d57aa0867..ba9d3ae0b2 100644
--- a/src/lib/ngsi/ContextElementResponse.cpp
+++ b/src/lib/ngsi/ContextElementResponse.cpp
@@ -98,9 +98,7 @@ ContextElementResponse::ContextElementResponse(ContextElementResponse* cerP, boo
ContextElementResponse::ContextElementResponse
(
const orion::BSONObj& entityDoc,
- const StringList& attrL,
- bool includeEmpty,
- ApiVersion apiVersion
+ const StringList& attrL
)
{
prune = false;
@@ -125,119 +123,7 @@ ContextElementResponse::ContextElementResponse
//
// Attribute vector
//
- orion::BSONObj attrs = getObjectFieldF(entityDoc, ENT_ATTRS);
- std::set attrNames;
-
- attrs.getFieldNames(&attrNames);
- for (std::set::iterator i = attrNames.begin(); i != attrNames.end(); ++i)
- {
- std::string attrName = *i;
- orion::BSONObj attr = getObjectFieldF(attrs, attrName);
- ContextAttribute* caP = NULL;
- ContextAttribute ca;
-
- // Name and type
- ca.name = dbDecode(attrName);
- ca.type = getStringFieldF(attr, ENT_ATTRS_TYPE);
-
- // Skip attribute if the attribute is in the list (or attrL is empty or includes "*")
- if (!includedAttribute(ca.name, attrL))
- {
- continue;
- }
-
- /* It could happen (although very rarely) that the value field is missing in the
- * DB for the attribute. The following is a safety check measure to protect against that */
- if (!attr.hasField(ENT_ATTRS_VALUE))
- {
- caP = new ContextAttribute(ca.name, ca.type, "");
- }
- else
- {
- switch(getFieldF(attr, ENT_ATTRS_VALUE).type())
- {
- case orion::String:
- ca.stringValue = getStringFieldF(attr, ENT_ATTRS_VALUE);
- if (!includeEmpty && ca.stringValue.empty())
- {
- continue;
- }
- caP = new ContextAttribute(ca.name, ca.type, ca.stringValue);
- break;
-
- case orion::NumberDouble:
- ca.numberValue = getNumberFieldF(attr, ENT_ATTRS_VALUE);
- caP = new ContextAttribute(ca.name, ca.type, ca.numberValue);
- break;
-
- case orion::NumberInt:
- ca.numberValue = (double) getIntFieldF(attr, ENT_ATTRS_VALUE);
- caP = new ContextAttribute(ca.name, ca.type, ca.numberValue);
- break;
-
- case orion::Bool:
- ca.boolValue = getBoolFieldF(attr, ENT_ATTRS_VALUE);
- caP = new ContextAttribute(ca.name, ca.type, ca.boolValue);
- break;
-
- case orion::jstNULL:
- caP = new ContextAttribute(ca.name, ca.type, "");
- caP->valueType = orion::ValueTypeNull;
- break;
-
- case orion::Object:
- caP = new ContextAttribute(ca.name, ca.type, "");
- caP->compoundValueP = new orion::CompoundValueNode(orion::ValueTypeObject);
- caP->valueType = orion::ValueTypeObject;
- compoundObjectResponse(caP->compoundValueP, getFieldF(attr, ENT_ATTRS_VALUE));
- break;
-
- case orion::Array:
- caP = new ContextAttribute(ca.name, ca.type, "");
- caP->compoundValueP = new orion::CompoundValueNode(orion::ValueTypeVector);
- caP->valueType = orion::ValueTypeVector;
- compoundVectorResponse(caP->compoundValueP, getFieldF(attr, ENT_ATTRS_VALUE));
- break;
-
- default:
- LM_E(("Runtime Error (unknown attribute value type in DB: %d)", getFieldF(attr, ENT_ATTRS_VALUE).type()));
- }
- }
-
- /* dateExpires is managed like a regular attribute in DB, but it is a builtin and it is shadowed */
- if (caP->name == DATE_EXPIRES)
- {
- caP->shadowed = true;
- }
-
- /* Setting custom metadata (if any) */
- if (attr.hasField(ENT_ATTRS_MD))
- {
- orion::BSONObj mds = getObjectFieldF(attr, ENT_ATTRS_MD);
- std::set mdsSet;
-
- mds.getFieldNames(&mdsSet);
- for (std::set::iterator i = mdsSet.begin(); i != mdsSet.end(); ++i)
- {
- std::string currentMd = *i;
- Metadata* md = new Metadata(dbDecode(currentMd), getObjectFieldF(mds, currentMd));
- caP->metadataVector.push_back(md);
- }
- }
-
- /* Set creDate and modDate at attribute level */
- if (attr.hasField(ENT_ATTRS_CREATION_DATE))
- {
- caP->creDate = getNumberFieldF(attr, ENT_ATTRS_CREATION_DATE);
- }
-
- if (attr.hasField(ENT_ATTRS_MODIFICATION_DATE))
- {
- caP->modDate = getNumberFieldF(attr, ENT_ATTRS_MODIFICATION_DATE);
- }
-
- entity.attributeVector.push_back(caP);
- }
+ entity.attributeVector.fill(getObjectFieldF(entityDoc, ENT_ATTRS), attrL);
/* Set creDate and modDate at entity level */
if (entityDoc.hasField(ENT_CREATION_DATE))
diff --git a/src/lib/ngsi/ContextElementResponse.h b/src/lib/ngsi/ContextElementResponse.h
index 999dd50a48..87b3bc17b1 100644
--- a/src/lib/ngsi/ContextElementResponse.h
+++ b/src/lib/ngsi/ContextElementResponse.h
@@ -61,9 +61,7 @@ typedef struct ContextElementResponse
ContextElementResponse(EntityId* eP, ContextAttribute* aP);
ContextElementResponse(ContextElementResponse* cerP, bool cloneCompound = false);
ContextElementResponse(const orion::BSONObj& entityDoc,
- const StringList& attrL,
- bool includeEmpty = true,
- ApiVersion apiVersion = V1);
+ const StringList& attrL);
ContextElementResponse(Entity* eP, bool useDefaultType = false);
std::string toJsonV1(bool asJsonObject,