Meetups — Bread and butter for Silicon Valley 🌁 developers 👨‍💻

MongoDB for you — a hardcore Java/Cloud developer

As I love robots 🤖, AI 🐲, IoT 🎛, mobile 📱, and space exploration 🌌, sometimes I need to roll my sleeves up and become a hardcore Java ☕️ / cloud ⛅️ developer 👨‍💻.

So this blogpost is about checking the response time of MongoDB managed on the Cloud in a Java EE microservice. Shall you be not afraid of Eclipse 🌙 and you are thinking about using MongoDB in the cloud ⛅️ definitely read it, or just contact me. Some similar blog posts in preps…

This post will instruct you on how to check the response time of services hosted on IBM Cloud — IBM Platform as a Service (or abbreviated PaaS). This is a very simple tool that would also show you how to do the basic CRUD operations in your Java application/microservice on strategic datasources like Cloudant, IBM Message Hub, MongoDB, Elastic Search, etc.

One of my customers asked me to help them with a simple dashboard concept that would display series of availability and response times of the CRUD operations (Create, Read, Update, Delete) of the various data services exposed on the IBM Dedicated Cloud. By coincidence it also became a good example on how one can use CRUD operations on those data services accessed from a Java Open Liberty server on a local machine, as well as bound in the cloud through VCAP configuration file.

This particular how-to post is an example on using Compose for MongoDB, that is hosted and managed in the IBM Cloud. The approach shown here is to generate a JSON response file with the report from accessing CRUD and provide the time needed to access each and every operation, in addition to the total operation time. The example of the response file you will try to create is the following:

{service: ‘mongodb’, operations: [
{type: ‘create’, response_time: 30, response_code: 200, desc:
{‘visitor id’: ‘some id’}},
{type: ‘read’, response_time: 25, response_code: 200, desc:
{‘visitor id’: ‘some id2’}},
{type: ‘update’, response_time: 49, response_code: 200, desc:
{‘visitor id’: ‘some id3’}},
{type: ‘delete’, response_time: 28, response_code: 200, desc:
{ ‘deleted visitor id’: ‘some id4’}}
], response_code: 200, desc:’operations implemented CRUD/CRUD’
}

I am not sure how extensively but expect to learn how to run Java Open Liberty server locally and also in the cloud ⛅️ — in the Platform as a Service, and how to connect to the exposed service.

Prerequisites

I assume you have some of the following software — and I develop on xOS — because of robots and stuff…:
- Git,
- Cloud Foundry CLI,
- Maven,
- and a Dedicated Bluemix account or Public Bluemix account (it needs to be a Cloud regular account, since the services aren’t Cloud lite account enabled) —

you can run plenty of cool stuff for robots, IoT, mobile, with even Watson just on the IBM Cloud LITE account, but simply you can’t do this hardcore software engineering here;

- I am also using Eclipse with Bluemix plugin to deploy the application to the cloud — however you can easily use any IDE for Java, and run Maven with Cloudfoundry CLI (command line interface) in the terminal to achieve the same results, I will not use Eclipse in this post… will work on that later.

Let us start with getting your test application. You can simply clone my github repository and change the directory to where the sample app for MongoDB is located. In order to do it use the instructions below:

$ git clone https://github.com/blumareks/BluemixTestDashboard
$ cd BluemixTestDashboard/GetStartedJavaMongoDb

In this step you need login to the IBM Cloud console. If you are using IBM Cloud Public — through http://bluemix.net URL you might search for Compose for MongoDB and Liberty (if you want to use PaaS Java EE server and not the local one). Create the Java Liberty App and create the Compose for MongoDb service. Finally bind the compose service with the Java Liberty App.

IBM Compose for MongoDB on IBM Cloud

After creating the services you need to bind Compose for MongoDB service to Open Liberty service. In order to do it you need to show Connection tab of the Open Liberty service and click on connect button, then get the Compose for MongoDB service, and select Connect button again. This action will initiate restaging process of the Open Liberty service.

The following screenshots show the process:

Adding a service as a connection to Java Liberty in IBM Cloud.
Connecting the existing service to Java Liberty

You might notice that Compose MongoDB connectivity is SSL enabled. Identify the Compose for MongoDB connection URL and Certificate — find the link at the management console of the service, or from the above VCAP file.

The HTTPS command to access the mongodb

The VCAP file could be obtained by selecting the connection tab, and from the three dot pull down menu selecting the View Credentials.

The connection credentials from the VCAP JSON file obtained as shown above will look like this:
{“compose-for-mongodb”: [
{“credentials”: { “db_type”: “mongodb”, “maps”: [], “instance_administration_api”: { “instance_id”: “6d1dd5bf-9274–4373-aab1–5bcace1d1e5c”, “root”: “
https://composebroker-dashboard-public.eu-gb.mybluemix.net/api", “deployment_id”: “5aec531b7852900026da6301”
},
“name”: “bmix-lon-yp-6d1dd5bf-9274–4373-aab1–5bcace1d1e5c”,
“uri_cli”: “mongo — ssl — sslAllowInvalidCertificates sl-eu-lon-2-portal.9.dblayer.com:26135/compose -u admin -p <your password will be here> — authenticationDatabase admin”,
“ca_certificate_base64”: “LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURtekNDQW9PZ0F3SUJBZ0lFV3V4VEpUQU5CZ2txaGtpRzl3MEJBUTBGQURCUE1VMHdTd1lEVlFRRERFUmkKYkhWbGJXbDRMbXhwZEdWQWNtOWliM1Jw
[… removed couple lines …]
VFqMG14WGtCOWkvODFzQ01JCkYxaTd5SzUzZW1WRkt0dlN5bVNkQk9jUzFVVitYN241SmI4WU9oUHF5KzJtR3dWREpLMmJHclV2RTNnTTlLa3kKSVdDVUlJL21HdUt2RzVncElPRXQKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=”,
“deployment_id”: “5aec531b7852900026da6301”,
“uri”: “mongodb://admin:<your password will be here>@sl-eu-lon-2-portal.9.dblayer.com:26135,sl-eu-lon-2-portal.10.dblayer.com:26135/compose?authSource=admin&ssl=true”
},

“syslog_drain_url”: null, “volume_mounts”: [], “label”: “compose-for-mongodb”, “provider”: null, “plan”: “Standard”, “name”: “Compose for MongoDB-fg”, “tags”:[“big_data”,“data_management”, “ibm_created”, “ibm_dedicated_public”, “eu_access” ] } ]
}

Therefore our application will need to set several JVM system properties to ensure that the client is able to validate the TLS/SSL certificate presented by the server:
javax.net.ssl.trustStore: The path to a trust store containing the certificate of the signing authority javax.net.ssl.trustStorePassword: The password to access this trust store
The trust store is typically created with the keytool command line program provided as part of the JDK. For example:
$ keytool -importcert -trustcacerts -file <path to CA file> -keystore <path to trust store> -storepass <password>
To make this work, we need to go back to the Compose console and get the SSL certificate (the certificate authority file) available on the Overview page — find it by clicking the button to reveal it and then copy it.

After you copy the SSL certificate use a command cat in the terminal to save it in the file:

cat > mongodbcert.crt

and then paste the copied text:
— — -BEGIN CERTIFICATE — — -
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURtekNDQW9PZ0F3SUJBZ0lFV3V4VEpUQU5CZ2txaGtpRzl3MEJBUTBGQURCUE1VMHdTd1lEVlFRRERFUmkKYkhWbGJXbDRMbXhwZEdWQWNtOWliM1Jw
[… removed couple lines …]
VFqMG14WGtCOWkvODFzQ01JCkYxaTd5SzUzZW1WRkt0dlN5bVNkQk9jUzFVVitYN241SmI4WU9oUHF5KzJtR3dWREpLMmJHclV2RTNnTTlLa3kKSVdDVUlJL21HdUt2RzVncElPRXQKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo
— — -END CERTIFICATE — — -

The next step is then quite easy: The command to create the mongoDBKey store for our system is the following (you might want to change the password aftereight to something more appropriate, and you might need to delete existing mongoKeyStore forked from the Github repository):

$ keytool -importcert -trustcacerts -file ./mongodbcert.crt -keystore ./mongoKeyStore -storepass aftereight

When done place the mongoKeyStore at this location: GetStartedJavaMongoDb/src/main/resources/mongoKeyStore

Update the java source file for the class wasdev.sample.store.MongoDbVisitorStore at the createClient method if anything changes. If you do not have Maven installed (check it with the following command in your terminal: mvn — version ) you might want to use on Mac OS the following commands:

$ brew update
$ brew install maven

From the project root directory type in the terminal the following command:

$ mvn install

the document after the mvn install is going to be stored at this location:

locally: /your path to the target: GetStartedJavaMongoDb/target/TestJavaMongo-1.0-SNAPSHOT/WEB-INF/classes/mongoKeyStore

on Bluemix (after cf push command) : /home/vcap/app/wlp/usr/servers/defaultServer/apps/myapp.war/WEB-INF/classes/mongoKeyStore

A typical application will also need to set several JVM system properties to ensure that the client presents an TLS/SSL certificate to the MongoDB server:

javax.net.ssl.keyStore The path to a key store containing the client’s TLS/SSL certificates

javax.net.ssl.keyStorePassword The password to access this key store

In order to test and run the service locally you might need to install the JAXRS-2.0 feature on the local server. I am using Eclipse IDE for that purpose.

And the source of the local Liberty Server managed by Eclipse IDE looks like this:
<server description=”new server”>
<! — Enable features →
<featureManager>
<feature>localConnector-1.0</feature>
<feature>servlet-3.1</feature>
<feature>jaxrs-2.0</feature>
</featureManager>
<applicationMonitor updateTrigger=”mbean”/>
<webApplication contextRoot=”TestJavaMongo” id=”GetStartedJavaMongoDb” location=”TestJavaMongo.war” name=”GetStartedJavaMongoDb”/>
</server>

After building the project with the GUI command: mvn install I am able to run it on the above configured local server.

The results after calling the service locally are following:

🌙 Eclipse IDE screenshot

The round trip of about 5 sec for the first call (we needed to create the DB, run everything remotely) isn’t impressive. The next step would show running the same service in IBM Cloud, and the response times will be at least 10x better. Please mind that the following calls (after the above mentioned first one) were faster (our db was already created, a connection established, etc.):
{service: ‘mongodb’, operations: [
{type: ‘create’, response_time: 386, response_code: 200, desc: {‘visitor id’: ‘5aec8faf17683ad076f4fc58’}},
{type: ‘read’, response_time:
303, response_code: 200, desc: {‘visitor id’: ‘5aec8faf17683ad076f4fc58’}},
{type: ‘update’, response_time:
579, response_code: 200, desc: {‘visitor id’: ‘5aec8faf17683ad076f4fc58’}},
{type: ‘delete’, response_time:
164, response_code: 200, desc: { ‘deleted visitor id’: ‘5aec8faf17683ad076f4fc58’}}
], response_code: 200, desc:’operations implemented CRUD/CRUD’}

There are at least two ways you can deploy and run this service in the cloud. You can either manually adjust the Cloudfoundry files and run it with CF CLI, or use the IBM Cloud connector for Eclipse.
Since it is the first blogpost in the series you will learn on how to do it manually with Cloudfoundry Command Line Interface cf CLI for short.

In this process you would need to download CLI from IBM Cloud. Start with visiting the Liberty service and selecting the Getting started tab, and download the Bluemix Command Line Interface.

As soon as the CLI is installed you can run the version command:

$ bx — version
bx version 0.6.6+d4d59ab5–2018–03–20T07:49:59+00:00

Now you can connect and login to the service — follow instructions in the Getting started file at step 3.

$ bluemix api https://api.<your access point here>

The api access point depends on the cloud location in US, EU, AU, etc.

$ bluemix login -u <your-email>
(alternatively if you use federated login: $ bluemix login -sso )

After you login in you can select easily and interactively the org and space for your commands. Run this command to do it:

$ bx target -cf (use two dashes “-”+“-” instead of one ;) — can’t type it here — Medium daemons 👻 can’t get it☝️)

Now edit the Cloudfoundry configuration file: manifest.yml.

The file should have name of the application (your Liberty service), and the bound Compose for MongoDB service.

In this example it looks like this:

applications:
- name: <your service name>
random-route: true
path: target/TestJavaMongo.war
memory: 256M
instances: 1
name: test-java-mongodb
host: test-java-mongodb
#(256 MB should be sufficient to run our microservice here)

Reflect the location of the KeyStore in cloud in the java class file: MongoDbVisitorStore.java (and this is not the way you should do it in the future I am afraid, you will start using VCAP file for automatic certificate configuration from the next blog post).

You can now build the app for the cloud with Maven:

$ mvn clean and mvn install

After it finishes without errors, you are ready to push it to cloud (takes a minute or two to get the service running — just enough to get a coffee :-)

$ bx app push <your service name>

You might want to look at the logs of the document both on the dashboard of the service (tab logs), or just use the CLI in the terminal for that — the command to get the logs trail is the following:

$ bx cf logs<your service name>

But check out this out:

the CRUD operation in the cloud ⛅️ is 100 times faster than the first call, and 10 times faster than remote (from your local machine) calls.

{service: ‘mongodb’, operations: [
{type: ‘create’,
response_time: 12, response_code: 200, desc: {‘visitor id’: ‘5aecb5b0705978002421614a’}},
{type: ‘read’,
response_time: 18, response_code: 200, desc: {‘visitor id’: ‘5aecb5b0705978002421614a’}},
{type: ‘update’,
response_time: 11, response_code: 200, desc: {‘visitor id’: ‘5aecb5b0705978002421614a’}},
{type: ‘delete’,
response_time: 8, response_code: 200, desc: { ‘deleted visitor id’: ‘5aecb5b0705978002421614a’}}], response_code: 200, desc:’operations implemented CRUD/CRUD’}

The next How-to blog post will be on adding an app to read, parse and store the results. Stay tuned and please subscribe to this blog post. Please follow me on Twitter at blumareks

Further reading and references:

I am a technology advocate for autonomous robots, AI, mobile and Internet of Things - with a view from both the enterprise and a robotics startup founder.