• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

telefonicaid / iotagent-json / 6143776542

11 Sep 2023 08:18AM UTC coverage: 77.778% (+0.02%) from 77.763%
6143776542

push

github

web-flow
Merge pull request #743 from telefonicaid/task/use_apikey_find_device

Task/use apikey find device

367 of 542 branches covered (0.0%)

Branch coverage included in aggregate %.

4 of 4 new or added lines in 1 file covered. (100.0%)

837 of 1006 relevant lines covered (83.2%)

144.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.66
/lib/iotaUtils.js
1
/*
2
 * Copyright 2016 Telefonica Investigación y Desarrollo, S.A.U
3
 *
4
 * This file is part of iotagent-json
5
 *
6
 * iotagent-json is free software: you can redistribute it and/or
7
 * modify it under the terms of the GNU Affero General Public License as
8
 * published by the Free Software Foundation, either version 3 of the License,
9
 * or (at your option) any later version.
10
 *
11
 * iotagent-json is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 * See the GNU Affero General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public
17
 * License along with iotagent-json.
18
 * If not, seehttp://www.gnu.org/licenses/.
19
 *
20
 * For those usages not covered by the GNU Affero General Public License
21
 * please contact with::[contacto@tid.es]
22
 */
23

24
const iotAgentLib = require('iotagent-node-lib');
2✔
25
const errors = require('./errors');
2✔
26
const dateFormat = require('dateformat');
2✔
27
const async = require('async');
2✔
28
const apply = async.apply;
2✔
29
const constants = require('./constants');
2✔
30
const context = {
2✔
31
    op: 'IoTAgentJSON.Utils'
32
};
33
const config = require('./configService');
2✔
34

35
/**
36
 * Get the API Key for the selected service if there is any, or the default API Key if a specific one does not exist.
37
 *
38
 * @param {String} service          Name of the service whose API Key we are retrieving.
39
 * @param {String} subservice       Name of the subservice whose API Key we are retrieving.
40
 * @param {Json} device             Device object.
41
 */
42
function getEffectiveApiKey(service, subservice, device, callback) {
43
    config.getLogger().debug(context, 'Getting effective API Key');
44✔
44

45
    if (device && device.apikey) {
44!
46
        config.getLogger().debug(context, 'Using device apikey: %s', device.apikey);
×
47
        callback(null, device.apikey);
×
48
    } else {
49
        const type = device.type ? device.type : null;
44!
50
        iotAgentLib.findConfiguration(service, subservice, type, function (error, group) {
44✔
51
            if (group) {
44✔
52
                config.getLogger().debug(context, 'Using found group: %j', group);
2✔
53
                callback(null, group.apikey);
2✔
54
            } else if (config.getConfig().defaultKey) {
42!
55
                config.getLogger().debug(context, 'Using default API Key: %s', config.getConfig().defaultKey);
42✔
56
                callback(null, config.getConfig().defaultKey);
42✔
57
            } else {
58
                config.getLogger().error(context, 'Could not find any API Key information for device.');
×
59
                callback(new errors.GroupNotFound(service, subservice));
×
60
            }
61
        });
62
    }
63
}
64

65
function manageConfiguration(apiKey, deviceId, device, objMessage, sendFunction, callback) {
66
    /* eslint-disable no-unused-vars */
67
    function handleSendConfigurationError(error, results) {
68
        if (error) {
12!
69
            config.getLogger().error(
×
70
                context,
71

72
                "CONFIG-001: Couldn't get the requested values from the Context Broker: %s",
73

74
                error
75
            );
76
        } else {
77
            config
12✔
78
                .getLogger()
79
                .debug(context, 'Configuration attributes sent to the device successfully.', deviceId, apiKey);
80
        }
81

82
        callback(error);
12✔
83
    }
84

85
    if (objMessage.type === 'configuration') {
20✔
86
        async.waterfall(
12✔
87
            [
88
                apply(iotAgentLib.query, device.name, device.type, '', objMessage.fields, device),
89
                apply(sendFunction, apiKey, deviceId)
90
            ],
91
            handleSendConfigurationError
92
        );
93
    } else if (objMessage.type === 'subscription') {
8!
94
        iotAgentLib.subscribe(device, objMessage.fields, objMessage.fields, function (error) {
8✔
95
            if (error) {
8!
96
                config
×
97
                    .getLogger()
98
                    .error(
99
                        context,
100
                        'CONFIG-002: There was an error subscribing device [%s] to attributes [%j]',
101
                        device.name,
102
                        objMessage.fields
103
                    );
104
            } else {
105
                config
8✔
106
                    .getLogger()
107
                    .debug(
108
                        context,
109
                        'Successfully subscribed device [%s] to attributes[%j]',
110
                        device.name,
111
                        objMessage.fields
112
                    );
113
            }
114

115
            callback(error);
8✔
116
        });
117
    } else {
118
        config.getLogger().error(context, 'CONFIG-003: Unknown command type from device [%s]', device.name);
×
119
        callback();
×
120
    }
121
}
122

123
function createConfigurationNotification(results) {
124
    const configurations = {};
16✔
125
    const now = new Date();
16✔
126

127
    // If it is the result of a subscription, results is an array
128
    if (Array.isArray(results)) {
16✔
129
        for (let i = 0; i < results.length; i++) {
4✔
130
            configurations[results[i].name] = results[i].value;
8✔
131
        }
132
    } else {
133
        for (var att in results) {
12✔
134
            configurations[att] = results[att].value;
48✔
135
        }
136
    }
137

138
    configurations.dt = dateFormat(now, constants.DATE_FORMAT);
16✔
139
    return configurations;
16✔
140
}
141

142
function findOrCreate(deviceId, transport, apikey, group, callback) {
143
    iotAgentLib.getDeviceSilently(deviceId, apikey, group.service, group.subservice, function (error, device) {
44✔
144
        if (!error && device) {
44✔
145
            if (
20!
146
                (!('apikey' in device) || device.apikey === undefined) &&
80✔
147
                'apikey' in group &&
148
                group.apikey !== undefined
149
            ) {
150
                config
20✔
151
                    .getLogger()
152
                    .info(context, 'Update provisioned device %j with measure/group apikey %j', device, group.apikey);
153
                device.apikey = group.apikey; // group apikey is the same of current measure apikey
20✔
154
                iotAgentLib.updateDevice(device, function (error) {
20✔
155
                    callback(error, device, group);
20✔
156
                });
157
            } else {
158
                callback(null, device, group);
×
159
            }
160
        } else if (error.name === 'DEVICE_NOT_FOUND') {
24!
161
            const newDevice = {
24✔
162
                id: deviceId,
163
                service: group.service,
164
                subservice: group.subservice,
165
                type: group.type
166
            };
167
            if (
24!
168
                config.getConfig().iota &&
48!
169
                config.getConfig().iota.iotManager &&
170
                config.getConfig().iota.iotManager.protocol
171
            ) {
172
                newDevice.protocol = config.getConfig().iota.iotManager.protocol;
×
173
            }
174
            // Fix transport depending on binding
175
            if (!newDevice.transport) {
24!
176
                newDevice.transport = transport;
24✔
177
            }
178
            if ('ngsiVersion' in group && group.ngsiVersion !== undefined) {
24!
179
                newDevice.ngsiVersion = group.ngsiVersion;
×
180
            }
181
            if (
24!
182
                (!('apikey' in newDevice) || newDevice.apikey === undefined) &&
72!
183
                'apikey' in group &&
184
                group.apikey !== undefined
185
            ) {
186
                newDevice.apikey = group.apikey;
24✔
187
            }
188
            // Check autoprovision flag in order to register or not device
189
            if (group.autoprovision === undefined || group.autoprovision === true) {
24!
190
                config
24✔
191
                    .getLogger()
192
                    .debug(context, 'Registering autoprovision of Device %j for its conf %j', newDevice, group);
193
                iotAgentLib.register(newDevice, function (error, device) {
24✔
194
                    callback(error, device, group);
24✔
195
                });
196
            } else {
197
                config
×
198
                    .getLogger()
199
                    .info(
200
                        context,
201
                        'Device %j not provisioned due autoprovision is disabled by its conf %j',
202
                        newDevice,
203
                        group
204
                    );
205
                callback(new errors.DeviceNotFound(deviceId));
×
206
            }
207
        } else {
208
            callback(error);
×
209
        }
210
    });
211
}
212

213
/**
214
 * Retrieve a device from the device repository based on the given APIKey and DeviceID, creating one if none is
215
 * found for the given data.
216
 *
217
 * @param {String} deviceId         Device ID of the device that wants to be retrieved or created.
218
 * @param {String} apiKey           APIKey of the Device Group (or default APIKey).
219
 */
220
function retrieveDevice(deviceId, apiKey, transport, callback) {
221
    if (apiKey === config.getConfig().defaultKey) {
180✔
222
        iotAgentLib.getDevicesByAttribute('id', deviceId, null, null, function (error, devices) {
136✔
223
            if (error) {
136!
224
                callback(error);
×
225
            } else if (devices && devices.length === 1) {
136!
226
                callback(null, devices[0]);
136✔
227
            } else {
228
                config.getLogger().error(
×
229
                    context,
230

231
                    "MEASURES-001: Couldn't find device data for APIKey [%s] and DeviceId[%s]",
232

233
                    apiKey,
234
                    deviceId
235
                );
236

237
                callback(new errors.DeviceNotFound(deviceId));
×
238
            }
239
        });
240
    } else {
241
        async.waterfall(
44✔
242
            [
243
                apply(iotAgentLib.getConfigurationSilently, config.getConfig().iota.defaultResource || '', apiKey),
44!
244
                apply(findOrCreate, deviceId, transport, apiKey), // group.apikey and apikey are the same
245
                apply(
246
                    iotAgentLib.mergeDeviceWithConfiguration,
247
                    ['lazy', 'active', 'staticAttributes', 'commands', 'subscriptions'],
248
                    [null, null, [], [], [], [], []]
249
                )
250
            ],
251
            callback
252
        );
253
    }
254
}
255

256
exports.createConfigurationNotification = createConfigurationNotification;
2✔
257
exports.getEffectiveApiKey = getEffectiveApiKey;
2✔
258
exports.manageConfiguration = manageConfiguration;
2✔
259
exports.retrieveDevice = retrieveDevice;
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc