Skip to content

tutorial_01_03_mongodb

Helmut Tammen edited this page Oct 21, 2016 · 1 revision

Saving data of n-odata-server App into MongoDB database

In this tutorial we will see how to save data that is created via the OData calls to our n-odata-server application into a MongoDB database.
The YaaS CF (Cloud Foundry) platform not only offers a runtime platform for Java and node.js applications but it also provides some services that can be used in custom applications easily.
One of these services is a MongoDB service that exposes a MongoDB to the applications.
In this tutorial you will see how easy it is to use such a service. You don't have to install a database, care about all that network stuff, ... You simply create a service instance for your organisation and bind you app to this service. It's a matter of minutes and you're able to save data to a database with CF (YaaS).

Source Code

The source code of this tutorial can be found on github. For each step we create a new branch. The master branch always contains the last evolution of this tutorial. The source code of this tutorial is available in branch 03_mongodb.
Check out this branch if you don't want to do all the typing yourself.

Prerequisites

If you want to follow this tutorial on you own you should have already followed the first two tutorials in this series. You can find them here:

And as mentioned in the last tutorial you need an account on SAP Hana Cloud Platform as well as on SAPs microservice platform YaaS. Both platforms can be used for development and test purposes free of charge.

CF tasks

We do some of the work of this tutorial via the CLI of the YaaS CF platform. Hence you should have installed the CF CLI tools. See the last tutorial for a link to the YaaS installation guide.
The CF command are executed in a terminal (command line) window. So you have to open one now.

Login to CF via CLI

First we have to login.
If you have more than one CF provider you firstly have to select the YaaS provider via the following command

cf api https://api.cf.us10.hana.ondemand.com

Then you can login via

cf login
Email> <enter your YaaS email address>
Password> <enter your YaaS password>

After you have been authenticated you get some information about your connection that looks like this

API endpoint:   https://api.cf.us10.hana.ondemand.com (API version: 2.59.0)   
User:           <your YaaS email address>   
Org:            <your CF organisation>   
Space:          dev 

Subscribe to MongoDB service

As we want to save our data into a MongoDB database we have to subscribe to the MongoDB service. This service is provided by SAP in the free YaaS account free of charge. To see which services are provided and how the MongoDB service is named we have a look at the CF marketplace.

cf marketplace

The result should look like this

service      plans            description   
mongodb      v3.0-container   MongoDB document-oriented database system   
postgresql   v9.4-container   PostgreSQL object-relational database system   
rabbitmq     v3.6-container   RabbitMQ messaging   
redis        v3.0-container   Redis in-memory data structure store

To create a service instance that we can use in our organisation we have to run the following command

cf create-service mongodb v3.0-container mongodb-service

create-service is the CF command
mongodb is the service we want to use (see list above)
v3.0-container is the plan that in a productive environment is used for several payment options
mongodb-service is the name we give the service instance in our landscape. You can name it as you want but have to remember it cause we use it later on.
As soon as you got an OK from CF you can check if the service instance has been created.

cf services

Here is the result (tadaa)

name              service   plan             bound apps   last operation   
mongodb-service   mongodb   v3.0-container                create succeeded 

Bind MongoDB service to app

As you can see currently no app is bound to that service instance. To be able to use it in our tutorial app. We can use the bind-service command. This command needs to know the name of the app and the name of the service. If you forgot the name of your app run

cf apps

You get the list of apps running in your organisation resp. space

name                    requested state   instances   memory   disk   urls   
n-odata-server-tut-01   started           1/1         256M     512M   n-odata-server-tut-01.cfapps.us10.hana.ondemand.com 

Now as we know the name of our app (n-odata-server-tut-01) and the name of our service instance (mongodb-service) we run the command

cf bind-service n-odata-server-tut-01 mongodb-service

CF returns with an OK and with a TIP which we follow

OK
TIP: Use 'cf restage n-odata-server-tut-01' to ensure your env variable changes take effect
cf restage n-odata-server-tut-01

This command restages the complete application which means it builds it completely new like after a cf push. At the end it should tell you that the application is running

     state     since                    cpu     memory         disk             details   
#0   running   2016-10-20 06:43:13 PM   91.0%   229M of 256M   186.3M of 512M      

To check if the service is really bound to the app enter

cf env n-odata-server-tut-01

This will display the environment variables of the app and the bound services. We will need some of this information later.

System-Provided:
{
 "VCAP_SERVICES": {
  "mongodb": [
   {
    "credentials": {
     "dbname": "6kjcovkykhddgtnv",
     "hostname": "10.11.241.3",
     "password": "****************",
     "port": "36031",
     "ports": {
      "27017/tcp": "36031",
      "28017/tcp": "47609"
     },
     "uri": "mongodb://fpa5n50e1dcwpdas:****************@10.11.241.3:36031/6kjcovkykhddgtnv",
     "username": "fpa5n50e1dcwpdas"
    },
    "label": "mongodb",
    "name": "mongodb-service",
    "plan": "v3.0-container",
    "provider": null,
    "syslog_drain_url": null,
    "tags": [
     "mongodb",
     "document"
    ],
    "volume_mounts": []
   }
  ]
 }
}

{
 "VCAP_APPLICATION": {
  "application_id": "d051adff-4594-4ff7-8fe6-d5893fae75ea",
  "application_name": "n-odata-server-tut-01",
  "application_uris": [
   "n-odata-server-tut-01.cfapps.us10.hana.ondemand.com"
  ],
  "application_version": "a94b501b-9fbd-4df3-926e-802656d1de13",
  "limits": {
   "disk": 512,
   "fds": 16384,
   "mem": 256
  },
  "name": "n-odata-server-tut-01",
  "space_id": "e6708a35-3b68-4288-98f9-c82e35800af5",
  "space_name": "dev",
  "uris": [
   "n-odata-server-tut-01.cfapps.us10.hana.ondemand.com"
  ],
  "users": null,
  "version": "a94b501b-9fbd-4df3-926e-802656d1de13"
 }
}

No user-defined env variables have been set

No running env variables have been set

No staging env variables have been set

Application adjustment

Now that we have prepared the CF environment we need to do some adjustments to our application.

Create MongoDB datasource

Currently we use an in-memory datasource with local file storage to store the data of our application. To store the data to the MongoDB database we have to create an according datasource.
This can be easily done with the slc command line tool.

slc loopback:datasource

Fill in the questions. Copy the data from the mongodb environment variables (see above, the **** are a placeholder for the password)

? Enter the data-source name: mongodb
? Select the connector for mongodb: MongoDB (supported by StrongLoop)
Connector-specific configuration:
? Connection String url to override other settings (eg: mongodb://username:password@hostname:port/database): mongodb://fpa5n50e1dcwpdas
:****************@10.11.241.3:36031/6kjcovkykhddgtnv
? host: 10.11.241.3
? port: 36031
? user: fpa5n50e1dcwpdas
? password: ****************
? database: 6kjcovkykhddgtnv
? Install loopback-connector-mongodb@^1.4 Yes

Answer the last question with Yes. This will automatically install the mongodb database driver (connector) for loopback. When you ran this command there is an additional dependency to the loopback-connector-mongodb in the package.json file and you see a new datasource in the file server/datasource.json

  "mongodb": {
    "host": "10.11.241.3",
    "port": 36031,
    "url": "mongodb://fpa5n50e1dcwpdas:****************@10.11.241.3:36031/6kjcovkykhddgtnv",
    "database": "6kjcovkykhddgtnv",
    "password": "****************",
    "name": "mongodb",
    "user": "fpa5n50e1dcwpdas",
    "connector": "mongodb"
  }

Change the datasource of the models

The next step is to change the datasource of all created models from db to mongodb. To achieve this you have to edit the file server/model-config.json and change the datasource of all models which data you want to be saved in the MongdDB database. Here is an example

  "person": {
    "dataSource": "mongodb",
    "public": true
  }

A nice thing about loopback is that you can uses several datasources in parallel.

Adding service to manifest.yml

Last step is to adjust the manifest.yml file. You have to add the mongodb-service. The file should look like this (notice the new services section at the end)

applications:
- path: .
  memory: 256M
  disk_quota: 512M
  instances: 1
  domain: cfapps.us10.hana.ondemand.com
  name: n-odata-server-tut-01
  host: n-odata-server-tut-01
  buildpack: nodejs_buildpack
  services:
    - mongodb-service

Push the application to YaaS (CF)

We are finished and so can push our new app to YaaS aka CF.

cf push

After some time you get this result. Your application is running. Wow !!!!

     state     since                    cpu    memory           disk           details   
#0   running   2016-10-20 10:48:26 PM   0.0%   242.5M of 256M   209M of 512M 

Use the application

The usage of the application doesn't change. It's the same as before. The only difference is that the results contain another id. This is generated by MongoDB and doesn't start with 1.
To make your life easier the requests for inserting and retrieving person object are listed below. For the other requests have a look at tutorial_01_02_yaas

Save a person

curl -X POST -H "Content-Type: application/json" -d '{
  "firstname": "Helmut",
  "lastname": "Tammen"
}' "https://<your hostname>.cfapps.us10.hana.ondemand.com/odata/people"

Result:

{
    "d": {
        "firstname": "Helmut",
        "id": "58092f1589e6de2b00b7ea1a",
        "lastname": "Tammen"
    }
}

Retrieve the saved person

curl -X GET -H "Accept: Accept: application/json" -H "Content-Type: application/json" "https://n-odata-server-tut-01.cfapps.us10.hana.ondemand.com/odata/people"

Result:

{
    "d": {
        "results": [
            {
                "__metadata": {
                    "type": "NODATASERVER.person",
                    "uri": "http://<your hostname>.cfapps.us10.hana.ondemand.com:61694/odata/people(1)"
                },
                "firstname": "Helmut",
                "id": "58092f1589e6de2b00b7ea1a",
                "lastname": "Tammen"
            }
        ]
    }
}

Notes

If you stop or restart your application via cf stop or cf restart the data you saved will not be lost anymore. This is because the data is not saved in a local file anymore but in an external database.
Now we can savely change and redeploy our app without deleting data each time.

Make sure data not saved locally

You don't believe that the data is saved in an external database?
Unfortunately YaaS doesn't offer a database management tool. But you can have a look at the local file storage/data.json to see that your new records are not saved there as before. Just run the command

cf files n-odata-server-tut-01 app/storage/data.json

This command outputs the content of the file to the console. It's content is either empty or the same as the file on your local PC (cf push pushed the file to the server). If you add new data to your OData service this will not appear in this file.

MongoDB Dashboard

Another interesting command is

cf service mongodb-service

This displays information about your service instance. It contains amongst others a link to a Dashboard. Enter this URL in your browser to get more information about the service. You can also see the logs of the database there.

Stay tuned