Skip to content

Commit

Permalink
add multientity cases
Browse files Browse the repository at this point in the history
  • Loading branch information
AlvaroVega committed Apr 9, 2024
1 parent 75fe276 commit e940fae
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 47 deletions.
81 changes: 36 additions & 45 deletions lib/services/ngsi/entities-NGSI-v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call
let entities = {}; //{entityName:{entityType:[attrs]}} //SubGoal Populate entoties data striucture
let jexlctxt = {}; //will store the whole context (not just for JEXL)
let payload = {}; //will store the final payload
let timestamp = { type: constants.TIMESTAMP_TYPE_NGSI2 }; //timestamp scafold-attr for insertions.
let plainMeasures = null; //will contain measures POJO
let idTypeSSSList = pluginUtils.getIdTypeServSubServiceFromDevice(typeInformation);

Expand Down Expand Up @@ -312,13 +311,12 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call

logger.debug(
context,
'sendUpdateValueNgsi2 called with: entityName=%s, measures=%j, typeInformation=%j, initial jexlContext=%j, timestamp=%j with value=%j',
'sendUpdateValueNgsi2 called with: entityName=%s, measures=%j, typeInformation=%j, initial jexlContext=%j, timestamp=%j',
entityName,
plainMeasures,
typeInformation,
jexlctxt,
mustInsertTimeInstant,
timestamp.value
mustInsertTimeInstant
);

//Now we can calculate the EntityName of primary entity
Expand Down Expand Up @@ -495,47 +493,6 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call
entities[entityName][typeInformation.type] = entities[entityName][typeInformation.type].concat(measures);
}

if (mustInsertTimeInstant) {
// search timestamp just in entity attrs
let timestampAttrs = null; //list of mapped TimeInstant attributes
for (let ename in entities) {
for (let etype in entities[ename]) {
timestampAttrs = entities[ename][etype].filter((item) => item.name === constants.TIMESTAMP_ATTRIBUTE);
if (timestampAttrs && timestampAttrs.length > 0) {
timestamp.value = timestampAttrs[0]['value'];
}
}
}
if (timestamp.value) {
if (!moment(timestamp.value, moment.ISO_8601, true).isValid()) {
callback(new errors.BadTimestamp(timestamp.value, entityName, typeInformation));
return;
}
} else {
if (!typeInformation.timezone) {
timestamp.value = new Date().toISOString();
jexlctxt[constants.TIMESTAMP_ATTRIBUTE] = timestamp.value;
} else {
timestamp.value = moment().tz(typeInformation.timezone).format('YYYY-MM-DD[T]HH:mm:ss.SSSZ');
jexlctxt[constants.TIMESTAMP_ATTRIBUTE] = timestamp.value;
}
}

// Add TimeInstant to all attribute metadata of all entities
for (let ename in entities) {
for (let etype in entities[ename]) {
for (let currentAttr of entities[ename][etype]) {
if (currentAttr.name !== constants.TIMESTAMP_ATTRIBUTE) {
if (!currentAttr.metadata) {
currentAttr.metadata = {};
}
currentAttr.metadata[constants.TIMESTAMP_ATTRIBUTE] = timestamp;
}
}
}
}
}

//PRE-PROCESSING FINISHED
//Explicit ATTRS and SKIPVALUES will be managed while we build NGSI payload

Expand All @@ -548,6 +505,31 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call
let e = {};
e.id = String(ename);
e.type = String(etype);
let timestamp = { type: constants.TIMESTAMP_TYPE_NGSI2 }; //timestamp scafold-attr for insertions.
let timestampAttrs = null;
if (mustInsertTimeInstant) {
// get timestamp for current entity

timestampAttrs = entities[ename][etype].filter((item) => item.name === constants.TIMESTAMP_ATTRIBUTE);
if (timestampAttrs && timestampAttrs.length > 0) {
timestamp.value = timestampAttrs[0]['value'];
}

if (timestamp.value) {
if (!moment(timestamp.value, moment.ISO_8601, true).isValid()) {
callback(new errors.BadTimestamp(timestamp.value, entityName, typeInformation));
return;
}
} else {
if (!typeInformation.timezone) {
timestamp.value = new Date().toISOString();
jexlctxt[constants.TIMESTAMP_ATTRIBUTE] = timestamp.value; // nosense
} else {
timestamp.value = moment().tz(typeInformation.timezone).format('YYYY-MM-DD[T]HH:mm:ss.SSSZ');
jexlctxt[constants.TIMESTAMP_ATTRIBUTE] = timestamp.value; // nosense
}
}
}
//extract attributes
let isEmpty = true;
for (let attr of entities[ename][etype]) {
Expand All @@ -566,6 +548,15 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call
if (attr.name !== constants.TIMESTAMP_ATTRIBUTE) {
isEmpty = false;
}
if (mustInsertTimeInstant) {
// Add TimeInstant to all attribute metadata of all entities
if (attr.name !== constants.TIMESTAMP_ATTRIBUTE) {
if (!attr.metadata) {
attr.metadata = {};
}
attr.metadata[constants.TIMESTAMP_ATTRIBUTE] = timestamp;
}
}
e[attr.name] = { type: attr.type, value: attr.value, metadata: attr.metadata };
}
}
Expand Down
141 changes: 141 additions & 0 deletions test/functional/testCases.js
Original file line number Diff line number Diff line change
Expand Up @@ -2327,6 +2327,147 @@ const testCases = [
}
]
},
{
describeName: '0433 - Simple group with active attribute + several timestamp mappings defined',
provision: {
url: 'http://localhost:' + config.iota.server.port + '/iot/services',
method: 'POST',
json: {
services: [
{
resource: '/iot/json',
apikey: globalEnv.apikey,
timestamp: true,
entity_type: globalEnv.entity_type,
commands: [],
lazy: [],
attributes: [
{
object_id: 'a',
name: 'a',
type: 'Text'
},
{
object_id: 'mydatetime1',
name: 'TimeInstant',
type: 'DateTime',
entity_name: 'TestType:TestDevice1',
entity_type: 'TestType'
},
{
object_id: 'mydatetime2',
name: 'TimeInstant',
type: 'DateTime',
entity_name: 'TestType:TestDevice2',
entity_type: 'TestType'
},
{
object_id: 'a1',
name: 'a1',
type: 'Text',
expression: 'a',
entity_name: 'TestType:TestDevice1',
entity_type: 'TestType'
},
{
object_id: 'a2',
name: 'a2',
type: 'Text',
expression: 'a',
entity_name: 'TestType:TestDevice2',
entity_type: 'TestType'
}
]
}
]
},
headers: {
'fiware-service': globalEnv.service,
'fiware-servicepath': globalEnv.servicePath
}
},
should: [
{
shouldName:
'A - WHEN sending a measure through http IT should map the measure to timestamp attributes and use it for timestmap and other metadata attributes sent to Context Broker',
type: 'multientity',
isRegex: true,
measure: {
url: 'http://localhost:' + config.http.port + '/iot/json',
method: 'POST',
qs: {
i: globalEnv.deviceId,
k: globalEnv.apikey
},
json: {
a: 23,
mydatetime1: '2011-01-01T01:11:11.111Z',
mydatetime2: '2022-02-02T02:22:22.222Z'
}
},
expectation: {
actionType: 'append',
entities: [
{
id: globalEnv.entity_name,
type: globalEnv.entity_type,
a: {
value: 23,
type: 'Text',
metadata: {
TimeInstant: {
value: _.isDateString,
type: 'DateTime'
}
}
},
TimeInstant: {
value: _.isDateString,
type: 'DateTime'
}
},
{
id: 'TestType:TestDevice1',
type: globalEnv.entity_type,
a1: {
value: 23,
type: 'Text',
metadata: {
TimeInstant: {
value: '2011-01-01T01:11:11.111Z',
type: 'DateTime'
}
}
},
TimeInstant: {
value: '2011-01-01T01:11:11.111Z',
type: 'DateTime'
}
},
{
id: 'TestType:TestDevice2',
type: globalEnv.entity_type,
a2: {
value: 23,
type: 'Text',
metadata: {
TimeInstant: {
value: '2022-02-02T02:22:22.222Z',
type: 'DateTime'
}
}
},
TimeInstant: {
value: '2022-02-02T02:22:22.222Z',
type: 'DateTime'
}
}
]
}
}
]
},

// 0500 - EXPLICIT ATTRIBUTES TESTS
{
describeName: '0500 - Group with explicit attrs:false (boolean) + active atributes',
Expand Down
36 changes: 34 additions & 2 deletions test/unit/ngsiv2/plugins/multientity-plugin_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,38 @@ const iotAgentConfig = {
}
]
},
WeatherStation10: {
commands: [],
type: 'WeatherStation',
lazy: [],
active: [
{
object_id: 'p',
name: 'pressure',
type: 'Hgmm'
},
{
object_id: 'h',
name: 'humidity',
type: 'Percentage',
entity_name: 'Higro2000',
entity_type: 'Higrometer',
metadata: {
unitCode: {
type: 'Text',
value: 'Hgmm'
}
}
},
{
object_id: 'TimeInstant',
name: 'TimeInstant',
type: 'DateTime',
entity_name: 'Higro2000',
entity_type: 'Higrometer'
}
]
},
Sensor001: {
commands: [],
type: 'Sensor',
Expand Down Expand Up @@ -1488,7 +1520,7 @@ describe('NGSI-v2 - Multi-entity plugin', function () {

describe('NGSI-v2 - Multi-entity plugin is executed before timestamp process plugin', function () {
beforeEach(function (done) {
logger.setLevel('FATAL');
logger.setLevel('DEBUG');
iotAgentConfig.timestamp = true;
iotAgentLib.activate(iotAgentConfig, function () {
iotAgentLib.clearAll(function () {
Expand Down Expand Up @@ -1635,7 +1667,7 @@ describe('NGSI-v2 - Multi-entity plugin is executed before timestamp process plu
value: '2018-06-13T13:28:34.611Z'
}
];
iotAgentLib.update('ws5', 'WeatherStation', '', tsValue, function (error) {
iotAgentLib.update('ws5', 'WeatherStation10', '', tsValue, function (error) {
should.not.exist(error);
contextBrokerMock.done();
done();
Expand Down

0 comments on commit e940fae

Please sign in to comment.