I have the following Azure Function in NodeJS which has as trigger: IoT Hub events.
And I need to transfer the messages to cosmos DB.
module.exports = function (context, IoTHubMessage) {
try {
var dbName = "db";
var collectionName = "encodedmessages";
context.log(`JavaScript eventhub trigger function called for message array: ${IoTHubMessage}`);
var mongoClient = require("mongodb").MongoClient;
context.log('MongoClient created');
mongoClient.connect("mongodb://xxx:password==@xxx.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=@db@",{useNewUrlParser: true, authSource: dbName}, function (err, client) {
if(err){
context.log(`Error occurred while connecting to DB ${err}`)
} else{
context.log('MongoClient connected to DB');
}
var collection = mongoClient.db(dbName).collection(collectionName);
context.log('MongoClient collection retreived');
collection.insertOne(IoTHubMessage, {w: 1});
//collection.insertOne({"testKey": 13.56}, {w: 1});
mongoClient.close();
context.log(`Saved message: ${IoTHubMessage}`);
context.done();
});
} catch (e){
context.log(`Error ${e}`);
}
context.log('Done called');
context.done();
};
I also have a console app sending messages to the iot hub running as explained here: https://learn.microsoft.com/en-us/azure/iot-hub/quickstart-send-telemetry-dotnet
The output is the following:
2020-10-30T12:06:41.968 [Information] JavaScript eventhub trigger function called for message array: Test Message
2020-10-30T12:06:41.972 [Information] MongoClient created
2020-10-30T12:06:41.972 [Information] Done called
2020-10-30T12:06:42.026 [Information] Executed 'Functions.ProcessEncodedMessages' (Succeeded, Id=2fcb7fa8-b194-4499-bc39-775aef86aac0, Duration=24606ms)
I dont really understand why I dont see in the logs messages in this piece of code:
if(err){
context.log(Error occurred while connecting to DB ${err}
)
} else{
context.log('MongoClient connected to DB');
}
Its like if its never reaching to that point, and I dont get any error regarding the connection string either.
I believe the insertOne
function returns a promise and you're not awaiting it hence its moving to the next statement which was mongoClient.close()
thereby closing the connection.
You can re-factor your code to use ES8 async-await and post resolving the insertOne
function's promise schedule the call to close the connection.
Here's a reference
from the official docs.
const { MongoClient } = require("mongodb");
module.exports = function (context, IoTHubMessage) {
const dbName = "db";
const collectionName = "encodedmessages";
const connectionString = `mongodb://xxx:password==@xxx.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=@db@`;
const options = {
useNewUrlParser: true,
authSource: dbName
};
context.log(`JavaScript eventhub trigger function called for message array: ${IoTHubMessage}`);
const client = new MongoClient(connectionString, options);
try {
context.log('MongoClient created');
await client.connect();
const database = client.db(dbName);
const collection = database.collection(collectionName);
context.log('MongoClient collection retreived');
const insertResult = await collection.insertOne(IoTHubMessage, {w: 1});
context.log(`Saved message: ${IoTHubMessage}`, insertResult);
context.done();
context.log('Done called');
} catch (e){
context.log(`Error ${e}`);
context.done();
} finally {
client.close();
}
};