Skip to content

Commit f7f5a52

Browse files
authored
Merge pull request #929 from jason-fox/feature/842_ngsi_ld
Fix merge conflicts again again again again.
2 parents 0d25170 + 2ac3b07 commit f7f5a52

20 files changed

+470
-41
lines changed

CHANGES_NEXT_RELEASE

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ Add basic NGSI-LD support as experimental feature (#842)
66
- Multi-measures
77
- Lazy Attributes
88
- Commands
9+
Add: enable use group commands in device and register it in iotagent-manager
10+
Add: extends commands definition to add mqtt options (qos, retain)
11+
Add: include findTypeSilently for groups to log some false errors as debug instead of alarm
12+
Add: include `description` field in group schema
13+
Add: include from in log context (#918)
14+
Fix: Update internal attributes in Group update (#917)
915
Fix: Static attributes from service not applied if device has static attributes (#757)
1016
Move Docker secret support inside the Node Application - remove Entrypoint (#885)
11-
Fix: IOTA_EXPLICIT_ATTRS env var was not working
17+
Fix: IOTA_EXPLICIT_ATTRS env var was not working
18+
Add lax validation mode using IOTA_RELAX_TEMPLATE_VALIDATION (#920)

doc/installationguide.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ used for the same purpose. For instance:
227227
- **singleConfigurationMode**: enables the Single Configuration mode for backwards compatibility (see description in
228228
the Overview). Default to false.
229229
- **timestamp**: if this flag is activated:
230-
- For NGSIv1/NGSIv2, the IoT Agent will add a `TimeInstant` metadata attribute to all the attributes updated from device information.
230+
- For NGSIv1/NGSIv2, the IoT Agent will add a `TimeInstant` metadata attribute to all the attributes updated from device information.
231231
This flag is overwritten by `timestamp` flag in group or device
232232
- With NGSI-LD, the standard `observedAt` property-of-a-property is created instead.
233233
- **defaultResource**: default string to use as resource for the registration of new Configurations (if no resource is
@@ -255,6 +255,11 @@ used for the same purpose. For instance:
255255
Note that for backwards compatibility with NGSI v2, the `fiware-servicepath` header is already used as alternative if the `NGSILD-Path` header is not supplied. Note that NGSILD-Path has not yet been included in the NGSI-LD standard (it has been proposed for the next update of the standard, but the final decision has yet been confirmed), take into account it could change
256256
- **explicitAttrs**: if this flag is activated, only provisioned attributes will be processed to Context Broker.
257257
This flag is overwritten by `explicitAttrs` flag in group or device provision.
258+
- **relaxTemplateValidation**: if this flag is activated, `objectId` attributes for incoming devices are not validated,
259+
and may exceptionally include characters (such as semi-colons) which are
260+
[forbidden](https://fiware-orion.readthedocs.io/en/master/user/forbidden_characters/index.html) according to the NGSI
261+
specification. When provisioning devices, it is necessary that the developer provides valid `objectId`-`name` mappings
262+
whenever relaxed mode is used, to prevent the consumption of forbidden characters.
258263

259264
### Configuration using environment variables
260265

@@ -264,7 +269,7 @@ with container-based technologies, like Docker, Heroku, etc...
264269
The following table shows the accepted environment variables, as well as the configuration parameter the variable
265270
overrides.
266271

267-
| Environment variable | Configuration attribute |
272+
| Environment variable | Configuration attribute |
268273
| :------------------------------- | :------------------------------ |
269274
| IOTA_CB_URL | `contextBroker.url` |
270275
| IOTA_CB_HOST | `contextBroker.host` |
@@ -317,6 +322,8 @@ overrides.
317322
| IOTA_FALLBACK_PATH | `fallbackPath` |
318323
| IOTA_DEFAULT_EXPRESSION_LANGUAGE | `defaultExpressionLanguage` |
319324
| IOTA_EXPLICIT_ATTRS | `explicitAttrs` |
325+
| IOTA_RELAX_TEMPLATE_VALIDATION | `relaxTemplateValidation` |
320326

321327
Note:
322328
- If you need to pass more than one JSON-LD context, you can define the IOTA_JSON_LD_CONTEXT environment variable as a comma separated list of contexts (e.g. `'http://context1.json-ld,http://context2.json-ld'`)
329+

lib/commonConfig.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ function processEnvironmentVariables() {
164164
'IOTA_POLLING_DAEMON_FREQ',
165165
'IOTA_MULTI_CORE',
166166
'IOTA_DEFAULT_EXPRESSION_LANGUAGE',
167+
'IOTA_RELAX_TEMPLATE_VALIDATION',
167168
'IOTA_JSON_LD_CONTEXT',
168169
'IOTA_FALLBACK_TENANT',
169170
'IOTA_FALLBACK_PATH'
@@ -474,6 +475,11 @@ function processEnvironmentVariables() {
474475
config.defaultExpressionLanguage =
475476
process.env.IOTA_DEFAULT_EXPRESSION_LANGUAGE;
476477
}
478+
if (process.env.IOTA_RELAX_TEMPLATE_VALIDATION) {
479+
config.relaxTemplateValidation = process.env.IOTA_RELAX_TEMPLATE_VALIDATION === 'true';
480+
} else {
481+
config.relaxTemplateValidation = config.relaxTemplateValidation === true;
482+
}
477483
}
478484

479485
function setConfig(newConfig) {

lib/constants.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ module.exports = {
6262
NGSI_LD_PATH_HEADER: 'NGSILD-Path',
6363
//FIXME: check Keystone support this in lowercase, then change
6464
AUTH_HEADER: 'X-Auth-Token',
65+
X_FORWARDED_FOR_HEADER: 'x-forwarded-for',
66+
FORWARDED_HEADER: 'forwarded',
67+
X_REAL_IP_HEADER: 'x-real-ip',
6568

6669
COMMAND_RESULT_SUFIX: '_info',
6770
COMMAND_STATUS_SUFIX: '_status',

lib/fiware-iotagent-lib.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ function startServer(newConfig, iotAgent, callback) {
269269
corr: domainObj.corr,
270270
trans: domainObj.trans,
271271
op: domainObj.op,
272+
from: domainObj.from,
272273
srv: domainObj.service,
273274
subsrv: domainObj.subservice,
274275
msg: domainObj.msg,

lib/model/Group.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ var Group = new Schema({
3232
type: String,
3333
service: String,
3434
subservice: String,
35+
description: String,
3536
trust: String,
3637
cbHost: String,
3738
timezone: String,

lib/services/common/domain.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ function cleanDomain(domainToClean) {
4747
domainToClean.removeAllListeners('error');
4848
delete domainToClean.trans;
4949
delete domainToClean.corr;
50+
delete domainToClean.from;
5051
delete domainToClean.op;
5152
delete domainToClean.path;
5253
domainToClean.exit();
@@ -80,6 +81,17 @@ function requestDomain(req, res, next) {
8081
reqDomain.subservice = req.headers[constants.SUBSERVICE_HEADER];
8182
}
8283

84+
// x-forwarded-for/forwarded overwrites x-real-ip
85+
if (req.headers[constants.X_REAL_IP_HEADER]) {
86+
reqDomain.from = req.headers[constants.X_REAL_IP_HEADER];
87+
}
88+
if (req.headers[constants.X_FORWARDED_FOR_HEADER]) {
89+
reqDomain.from = req.headers[constants.X_FORWARDED_FOR_HEADER];
90+
}
91+
if (req.headers[constants.FORWARDED_HEADER]) {
92+
reqDomain.from = req.headers[constants.FORWARDED_HEADER];
93+
}
94+
8395
function requestHandler() {
8496
var corr = req.get(CORRELATOR_HEADER);
8597

lib/services/common/iotManagerService.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ function register(callback) {
5353
service_path: service.subservice,
5454
attributes: service.attributes,
5555
static_attributes: service.staticAttributes,
56+
commands: service.commands,
57+
description: service.description,
5658
timezone: service.timezone,
5759
timestamp: service.timestamp,
5860
autoprovision: service.autoprovision,

lib/services/devices/deviceService.js

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,9 @@ function mergeArrays(original, newArray) {
122122
* @param {Object} configuration Configuration data.
123123
*/
124124
function mergeDeviceWithConfiguration(fields, defaults, deviceData, configuration, callback) {
125-
logger.debug(context, 'deviceData after merge with conf: %j', deviceData);
125+
logger.debug(context, 'deviceData before merge with conf: %j', deviceData);
126126
for (let i = 0; i < fields.length; i++) {
127127
const confField = fields[i] === 'active' ? 'attributes' : fields[i];
128-
129128
if (deviceData && deviceData[fields[i]] && ['active', 'lazy', 'commands'].indexOf(fields[i]) >= 0) {
130129
deviceData[fields[i]] = deviceData[fields[i]].map(setDefaultAttributeIds);
131130
} else if (deviceData && deviceData[fields[i]] && ['internalAttributes'].indexOf(fields[i]) >= 0) {
@@ -159,7 +158,7 @@ function mergeDeviceWithConfiguration(fields, defaults, deviceData, configuratio
159158
if (configuration && configuration.cbHost) {
160159
deviceData.cbHost = configuration.cbHost;
161160
}
162-
logger.debug(context, 'deviceData before merge with conf: %j', deviceData);
161+
logger.debug(context, 'deviceData after merge with conf: %j', deviceData);
163162
callback(null, deviceData);
164163
}
165164

@@ -187,7 +186,13 @@ function findConfigurationGroup(deviceObj, callback) {
187186
} else {
188187
config
189188
.getGroupRegistry()
190-
.findType(deviceObj.service, deviceObj.subservice, deviceObj.type, deviceObj.apikey, handlerGroupFind);
189+
.findTypeSilently(
190+
deviceObj.service,
191+
deviceObj.subservice,
192+
deviceObj.type,
193+
deviceObj.apikey,
194+
handlerGroupFind
195+
);
191196
}
192197
}
193198

@@ -258,35 +263,33 @@ function registerDevice(deviceObj, callback) {
258263

259264
logger.debug(context, 'Registering device into NGSI Service:\n%s', JSON.stringify(deviceData, null, 4));
260265

261-
async.waterfall(
262-
[
263-
apply(registrationUtils.sendRegistrations, false, deviceData),
264-
apply(registrationUtils.processContextRegistration, deviceData),
265-
apply(createInitialEntity, deviceData)
266-
],
267-
function(error, results) {
268-
if (error) {
269-
callback(error);
270-
} else {
271-
deviceObj.registrationId = results.registrationId;
272-
deviceObj.name = deviceData.name;
273-
deviceObj.service = deviceData.service;
274-
deviceObj.subservice = deviceData.subservice;
275-
deviceObj.type = deviceData.type;
276-
deviceObj.staticAttributes = deviceData.staticAttributes;
277-
if ('timestamp' in deviceData && deviceData.timestamp !== undefined) {
278-
deviceObj.timestamp = deviceData.timestamp;
279-
}
280-
if ('autoprovision' in deviceData && deviceData.autoprovision !== undefined) {
281-
deviceObj.autoprovision = deviceData.autoprovision;
282-
}
283-
if ('explicitAttrs' in deviceData && deviceData.explicitAttrs !== undefined) {
284-
deviceObj.explicitAttrs = deviceData.explicitAttrs;
285-
}
286-
config.getRegistry().store(deviceObj, callback);
266+
async.waterfall([
267+
apply(registrationUtils.sendRegistrations, false, deviceData),
268+
apply(registrationUtils.processContextRegistration, deviceData),
269+
apply(createInitialEntity, deviceData)
270+
], function(error, results) {
271+
if (error) {
272+
callback(error);
273+
} else {
274+
deviceObj.registrationId = results.registrationId;
275+
deviceObj.name = deviceData.name;
276+
deviceObj.service = deviceData.service;
277+
deviceObj.subservice = deviceData.subservice;
278+
deviceObj.type = deviceData.type;
279+
deviceObj.staticAttributes = deviceData.staticAttributes;
280+
deviceObj.commands = deviceData.commands;
281+
if ('timestamp' in deviceData && deviceData.timestamp !== undefined) {
282+
deviceObj.timestamp = deviceData.timestamp;
287283
}
284+
if ('autoprovision' in deviceData && deviceData.autoprovision !== undefined) {
285+
deviceObj.autoprovision = deviceData.autoprovision;
286+
}
287+
if ('explicitAttrs' in deviceData && deviceData.explicitAttrs !== undefined) {
288+
deviceObj.explicitAttrs = deviceData.explicitAttrs;
289+
}
290+
config.getRegistry().store(deviceObj, callback);
288291
}
289-
);
292+
});
290293
}
291294

292295
async.waterfall(

lib/services/groups/groupRegistryMemory.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ exports.init = intoTrans(context, init);
277277
exports.find = intoTrans(context, find);
278278
exports.findBy = intoTrans(context, findBy);
279279
exports.findType = intoTrans(context, findBy(['service', 'subservice', 'type']));
280+
exports.findTypeSilently = intoTrans(context, findBy(['service', 'subservice', 'type']));
280281
exports.get = intoTrans(context, getSingleGroup);
281282
exports.getSilently = intoTrans(context, getSingleGroup);
282283
exports.getType = intoTrans(context, getSingleGroupType);

0 commit comments

Comments
 (0)