connection issues with AWS DocumentDB via nodejs mongodb package - node.js

I have created a DocumentDB with SSL enabled and I am using mongodb package using NodeJS to connect this DB using a Bastion Host. The issue is that if I put a hardcoded string inside the MongoClient.connect function, I am able to successfully connect the DB. The hardcoded code would look like as shown below.
let MongoClient = require('mongodb').MongoClient;
let client = MongoClient.connect(
'mongodb://User:PWD#DBURL:27017/DBNAME?tls=true&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false',
{
tlsCAFile: __dirname + `rds-combined-ca-bundle.pem` //Specify the DocDB; cert
},
function(err, client) {
if(err)
throw err;
console.log("1111111 2222222!!");
//Specify the database to be used
db = client.db('DBNAME');
//Specify the collection to be used
col = db.collection('COLNAME');
console.log("1111111 connected to db!!");
client.close();
});
Now as that's not an ideal situation to put the hardcoded values in the code. I am trying to read the values from environment variables and trying to put the whole URL into a string variable and passing this variable into that function such as shown below.
const DBURL = "mongodb://"+user+":"+pwd+"#"+dbURL+":"+port+"/"+dbName+"?tls=true&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false";
let client = MongoClient.connect(DBURL,
{
tlsCAFile: __dirname + `rds-combined-ca-bundle.pem` //Specify the DocDB; cert
},
function(err, client) {
Now this one timesout to connect the DB.
Any suggestions on it or should I use any other packages to connect DocumentDB via NodeJS, do let me know.

Something like this works for me:
const { MongoClient } = require('mongodb')
const DOCUMENTDB_CONNECTION_STRING = `mongodb://${process.env.DOCDB_USER}:${process.env.DOCDB_PASS}#${process.env.DOCDB_ENDPOINT}/${process.env.DOCDB_DBNAME}?tls=true&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false`
const client = MongoClient.connect(
DOCUMENTDB_CONNECTION_STRING, {
tlsCAFile: `rds-combined-ca-bundle.pem` //Specify the DocDB cert
},
function(err, client) {
Is this what you are looking for?

Related

Can not connect to azure cosmos db from azure function App using Node.js

I am trying to send the incoming data from the IoT in the cosmos DB.
I am receiving data in the function app but sadly I am not able to connect the cosmos DB using the connection string provided( in cosmos DB quickstart and connection string blade.
Below is my node.js application:
module.exports = function (context, IoTHubMessage) {
try {
var dbName = "temp-db";
var collectionName = "messages";
context.log(`JavaScript eventhub trigger function called for message array: ${IoTHubMessage}`);
context.log(`datatype of message: ${typeof IoTHubMessage}`);
var json_message = JSON.stringify(IoTHubMessage);
context.log(`json message: ${json_message}`);
var mongoClient = require("mongodb").MongoClient;
context.log('MongoClient created');
const pass = "Q********************XTB988aNw4CecjmZsSqTpCeXkjlzCrmljzjq58T9AqeuVvSJrUPBpc4rBSSD1CQ=="
const encodedpass = encodeURIComponent(pass)
const connectionString= `mongodb://iot-db:${pass}#iot-db.documents.azure.com:10255/?ssl=true`
context.log(`connection string:\n ${connectionString}`)
mongoClient.connect(connectionString, function (err,client){
context.log('check0...');
if(err){
context.log(`Error occurred while connecting to DB ${err}`)
} else{
context.log('MongoClient connected to DB');
}
context.log('check1...');
var collection = client.db(dbName).collection(collectionName);
context.log('MongoClient collection retreived');
collection.insertOne(IoTHubMessage, {w: 1});
//collection.insertOne({"testKey": 13.56}, {w: 1});
client.close();
context.log(`Saved message: ${IoTHubMessage}`);
context.done();
});
context.log('check2...');
} catch (e){
context.log(`Error ${e}`);
}
context.log('Done called');
context.done();
};
Here are the issues that I am facing:
The above app does not give any error, but while running the call back function is not getting executed.( i know this because the prints are not happening inside the callback function.)
I tried to pass the non-URI encoded password. then it enters the callback function but complains that the password contains illegal characters.
on passing the encoded password it does not enter the callback function.
How do I check which node driver I am currently using?
How do I check if my 10255 port is open or not?
I am attaching a screenshot of the node.js app

Unable to fetch data from mongodb- atlas?

I am trying to fetch data from MongoDB-atlas using note.js which I have manually fed to the server.
The status of the collection on MongoDB-atlas sever is :
dbname: viit
collection name : viit_atts
also, I have whitelisted my id and I am able to connect to the server.
I started off by connecting to the server by using the command :
mongoose.connect("mongodb+srv://wimpy_cool:myPassWordGoesHere#cluster0-phqid.mongodb.net/test?retryWrites=true&w=majority",{},function(err,res)
{
if(err)
{
console.log("mongo lab server not connected");
console.log(err);
}
else
{
// console.log(res);
console.log("Connectd to mongolab db");
}
});
Now using mongoose I have declared schema and made a model and then use the find function to fetch the data.
var bodyParser = require('body-parser');
var mongoose =require("mongoose");
var express= require("express");
var app = express();
app.use(bodyParser.urlencoded({extended:true}));
mongoose.connect("mongodb+srv://wimpy_cool:myPassWordGoesHere#cluster0-phqid.mongodb.net/test?retryWrites=true&w=majority",{},function(err,res)
{
if(err)
{
console.log("mongo lab server not connected");
console.log(err);
}
else
{
// console.log(res);
console.log("Connectd to mongolab db");
}
});
var viit_att_schema = new mongoose.Schema({
name : String,
no_of_present: Number,
no_of_absent: Number
});
var att_history_schema = new mongoose.Schema({
time : String ,
att_stats : String,
});
var viit_att= mongoose.model("viit_att",viit_att_schema);
var att_history = mongoose.model("att_history",att_history_schema);
var list_of_all_members;
var list_of_all_members_sorted;
viit_att.find({},function(err,viit_atts)
{
if (err) {
console.log("OH NO ERROR");
}
else
{
console.log("fetching data now");
console.log(viit_atts);
list_of_all_members=viit_atts;
// console.log(list_of_all_members[0]);
// console.log(list_of_all_members);
list_of_all_members_sorted = list_of_all_members.sort(function(a,b) {
return b.no_of_present - a.no_of_present ;
});
console.log(list_of_all_members_sorted);
}
});
app.listen( process.env.PORT || 3000 , function(){
console.log("SERVER 3000 HAS STARTED");
});
But the fetching doesn't seem to take place, the console says this :
D:\MY PROJECTS\WEB\club_attendence_website>node backend.js
(node:13076) DeprecationWarning: current URL string parser is deprecated,
and will be removed in a future version. To us
e the new parser, pass option { useNewUrlParser: true } to
MongoClient.connect.
SERVER 3000 HAS STARTED
Connectd to mongolab db
fetching data now
[]
[]
The problem was that the default connection string for MongoDB atlas has a default database name as test, and will search for the same in the cluster, hence even though it will connect, nothing will be fetched.
In order to learn how to explicitly mention the dbName refer to this link: Fail to connect Mongoose to Atlas
Hi I had the same issue!
Issue:
I created a mongoDb Atlas collection name is "main"; however when I connect my nodeJs using mongoose, the collection name from the callback became "mains".
Solution:
I changed my model name to "mains" and it worked.
Try this:
‍var viit_att= mongoose.model("viit_atts",viit_att_schema);‍
Try doing it like this:
viit_att.find({}).then(content => {
console.log("data was fetched");
console.log(content);
list_of_all_members=content;
// console.log(list_of_all_members[0]);
// console.log(list_of_all_members);
list_of_all_members_sorted = list_of_all_members.sort(function(a,b) {
return b.no_of_present - a.no_of_present ;
});
console.log(list_of_all_members_sorted);
})
.catch(err => { console.log("OH NO AN ERROR") })
I got into this same problem, what worked for me, was to specify a collection name when defining your mongoose models:
module.exports = mongoose.model('App', schema, COLLECTION_NAME)
Where COLLECTION_NAME must match the mongodb atlas collection name.
For me the problem was that I was unable to fetch or get data but the connection was established with the server and I found that the few problems that can occur are:-
1: URL encoding
The text you put inside the connection string must be url encoded as said in the mongodb docs.
So, if the parameters you put inside the connection string like your database name or your password, the special characters that are : / ? # [ ] # must be url encoded (also known as percentage encoded), e.g. # becomes %40. You can use a bunch of online url encoders which are available on the internet.
2: Not added IP address from mongodb UI
You have to add the IP address of the computer from which the database will be sent a request. You can either do it in the first step while connecting by clicking 'Connect' on the cluster page or add ip address from here.
I personally kept it to be accessible by everyone, so added the ip address 0.0.0.0/0 (includes your current IP address).
3: Not specifying the correct database name
If you paste the default connection string in your app, it will point to the default database that is test. You will have to either change test to your db name or if there's nothing written, you'll have to write your db name
So, your connection string should look like this:-
mongodb+srv://<Your username>:<Your password>#cluster0.ezmvoas.mongodb.net/<Your db name>?retryWrites=true&w=majority
Troubleshoot
If there is any other problem, what you can do is to give error as an input to the callback function and try logging the error on the console.
const connectToMongo = () => {
mongoose.connect(mongoURI, (error, result) => {
console.log('Connected to MongoDB' + '\nError: ' + error);
});
}
By this way, you can get the fix for exactly the error message without trying different things.
Hope this solves the problem,
Thanks!

How do I get a MongoDB import script to close the db after inserting results?

I am running a quick little nodejs script to find documents in one collection and insert them into another collection but on the same DB. I came up with this guy, but it has no way to close because I think its running open or async?
I have tried placing the db.close() in various places and tried mongoClient.close(). No luck which had me thinking about trying to force a timeout for the async call. Added a connection Time out but it did not have the desired behaviour.
var MongoClient = require('mongodb').MongoClient
, assert = require('assert');
const async = require("async");
// Connection URL
var url = 'mongodb://localhost:27017/sourceDB';
// Use connect method to connect to the Server
MongoClient.connect(url,{connectTimeoutMS: "5"}, (err, db) => {
db.collection('source.collection', function(err, col) {
assert.equal(null, err);
col.find().forEach(function (data) {
console.log(data);
db.collection('destination.collection').insertOne(data, function(err, res) {
assert.equal(null, err);
});
console.log("Moved");
});
});
});
The script does well and picks up the collection and inserts, but the connection remains open.
It is not recommended to explicitly close the connection as shown by this SO thread.
Rather, allow the client library to manage the connection for you.

How to reconnect mongoose to another remote server?

I am totally new to node.js and mongoose, how to reconnect mongoose to another remote server ?
At the beginning of the file I have
var mongoose = require('mongoose')
and connected to localhost,
later in code I have
var uristring ='mongodb://remote_server/db';
var mongoOptions = { db: { safe: true } };
// Connect to Database
mongoose.createConnection(uristring, mongoOptions, function (err, res) {
if (err) {
console.log ('ERROR connecting to: remote' + uristring + '. ' + err);
} else {
console.log ('Successfully connected to: remote' + uristring);
}
});
and I always get Successfully connected to: remote but when I bellow that print look for document by id I get always from local database(I have schema imported like require Person = mongoose.model('Person');).
How to reconnect to remote if I already have connection to local.
There are two ways of initializate a connection in mongoose:
Using the default connection "object"
Creating a connection from the dust
Here you are creating a connection, but using a model from another. Models are tied to databases (normal databases, replica sets or clusters) so you're not accesing to the correct host.
You must use the default connection (using mongoose.connect instead of mongoose.createConnection) or create a model in that new connection you are using. In your example:
var uristring ='mongodb://remote_server/db';
var mongoOptions = { db: { safe: true } };
// Connect to Database
var newConnection = mongoose.createConnection(uristring, mongoOptions);
newConnection.model(/*whatever*/);
mongoose.model wires to mongoose.connection. That is not the new connection you have created.

How to init native Mongo in NodeJS with at Sign in password

I am trying to figure out how to connect to my mongodb db using the native node mongo driver and I have two issues:
My password contains an # sign making it break the normal user:pass#host connection string format
How do I list databases from what I have below?
Any ideas on how to address this?
Here is an attempt which does not work:
var Mongo = require('mongodb');
var server = new Mongo.Server('mongodb://myhost', 27017);
var db = new Mongo.Db('test', server);
db.open(function(err, db) {
console.log(err); //unable to connect
});
For future readers, I was able to resolve this with the connection option uri_decode_auth. You will need to encodeURIComponent(password) before embedding it in the connection string.
Here's a complete working example:
MongoClient.connect(connection, { uri_decode_auth: true }, function(err, db) {
if(err) {
return cb(err);
}
db.admin().listDatabases(function(err, dbs) {
console.log(dbs);
});
});
As mentioned on this answer:
The solution is to replace # with %40
I tested with the C# driver and it works like a charm.

Resources