LTanase
LTanase

Reputation: 307

connecting azure web app to azure cosmos db

I am trying to replicate the tutorial for connecting an azure web app (based on express) to azure cosmos db using mongoose Using Mongoose Framework with Azure Cosmos DB

However I am not able to connect to my database named testdb. I have a server.js file where I put all the code for simplicity and an .env file which contains the connection string and the name of the database as described in the tutorial.

I have inserted the code contained by server.js, below. The code is based on the one in the tutorial, just that I added the pug template engine, for the app, with the intention that once i create a collection I may get info from it and integrated with the pug template.

The pug file is displayed by the app but no collection is created in the database and I do not know where is the problem.

One issue that seems striking in the tutorial is that the connection string of the azure cosmos db already contains "?ssl=true&replicaSet=globaldb" and i do not understand why the tutorial is appending it again when connecting to database. I have removed from the connection string saved in the .env file that part but nothing happens either. I have also encoded the special character in the connection string like (==, @, ? or /).

Seems to me that I cannot form correctly the connection string, but I do not know how to solve this issue. What is the correct pattern for the connection string when you are trying to create a collection in an empty database? There should be slashes between connection string and db name and between db name and the query?

Another question is related to the fact that the code from the tutorial is containing calls of console.log function for displaying message on the console. My question is, on which console that messages are supposed to be displayed, on the browser console or on the node console? In the browser there are not displayed any messages.

Any guidance will be appreciated.

Many thanks!

const express = require('express');
const http = require('http');

const mongoose= require('mongoose');
const env = require('dotenv').load();    //Use the .env file to load the variables

const app = express();
var port = process.env.PORT || 5050; //normalizePort(process.env.PORT || '5050');
app.set('port', port);
app.set('views', 'views');
app.set('view engine', 'pug');

mongoose.connect(process.env.COSMOSDB_CONNSTR+process.env.COSMOSDB_DBNAME+"?ssl=true&replicaSet=globaldb"); //Creates a new DB, if it doesn't already exist
//mongoose.connect(dbc);
let db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log("Connected to DB");
});

const cities = mongoose.model('cities', new mongoose.Schema({
    name: String,
    country: String
}));

const city = new cities({
 name: "Paris",
 country: "France"
});

city.save( function (err, savedCity) {
    console.log(JSON.stringify(savedCity));
});

app.get('/', function(req, res) {
    res.render('index', {
        panelTitle: "Azure CosmosDB Test",  
        panelBody:"Testing how to access Azure ComsosDB",
    });
});


app.use(express.static(__dirname + '/public'));

const server = http.createServer(app);
server.listen(port);

Upvotes: 1

Views: 2288

Answers (3)

LTanase
LTanase

Reputation: 307

As I mentioned in my comments to Yuri Doganjiev answer, his code and the suggestion of enabling the preview features on the dashboard of azure cosmos db account resulted in succeeding in connecting to azure cosmosdb and create collection and querying the database. The version of mongoose used by me is 5.0.14.

The actual connection code used is below, where [host], [port], [username] and [password] are the value mentioned in connection string tab on azure dashboard. The [dbname] is the name of the database to which wish to connect.I did not escaped any special characters like (/, =, ?).Actually when I tried to escape some of them I got error messages.

mongoose.connect(`mongodb://[host]:[port]/[dbname]?ssl=true`, {
    auth: {
      user: `[username]`,
      password: `[password]`
    }
  })
  .then(() => console.log('connection successful'))
  .catch((err) => console.error(err));

The problem for me was that I was not able to receive any error messages besides the generic one like 404 - not found or 500 - internal error problem.

Only after I have run npm start in the kudu console under the root directory of the app I started to receive meaningful error messages which helped me to identify were the problem is. Furthermore the console.log function used in the app code printed its message in the kudu console, showing if the connection is successful or displaying the newly inserted objects in the collection.

Another issue that I have encountered is that you cannot end the node process in kudu console by Ctrl + C. The only way to end the process that I found is the process explorer in kudu that is displaying the running processes and lets you kill them. So even when I have made changes to the code, such changes where not reflected in the browser immediately as the old node process (using the old code) was still running.

I do not know what kind of process manager uses Azure Web App but not always changes in the code are reflected in the browser.

Upvotes: 1

Yuri Dogandjiev
Yuri Dogandjiev

Reputation: 208

I recently completed the tutorial here that walks you through building an Express-based server that uses Mongoose to connect to Cosmos DB. You can see the end result here: https://github.com/ydogandjiev/react-cosmosdb

A couple of issues I ran into were:

  1. I had to use the following syntax to connect to the database (or escape the password string):

    mongoose.connect(`mongodb://${env.user}.documents.azure.com:${env.port}/?        ssl=true`, {
      auth: {
        user: env.user,
        password: env.password
      }
    });
    
  2. Using the latest version of the Mongo client requires you to enable the preview features on your CosmosDB instance: CosmosDB Preview Features

Upvotes: 2

navicore
navicore

Reputation: 2119

mongoose.connect wants the string to have a /DBNAME between the network part of the conn str and the options part.

mongoose.connect('mongodb://username:password@host:port/database?options...');

Take the connection string from the CosmosDB portal and insert the dbname with a slash /dbname before the ?ssl=true...

You can do this by setting COSMOSDB_CONNSTR to be just the part of the connection string up until but not including the ? and making sure it ends with a /

See http://mongoosejs.com/docs/connections.html

Upvotes: 1

Related Questions