Community

Java and Cloudant NoSQL DB on Bluemix

Share this post:

Cloudant is a stellar NoSQL DBaaS (Database as a Service) that allows developers to not worry about their database infrastructure. If you’ve never used Cloudant or a cloud database offering before, this is where you should get started. Within the large catalog of services we provide with Bluemix, Cloudant shines as one of the simplest databases to create and use. In this sample, we will quickly create a web application that talks to Cloudant using the “ektorp” client jar for Java and then push it to Bluemix. We will create this web application using a Maven project in Eclipse. I’ve chosen Maven because it is the easiest way to retrieve the dependencies we need — the “ektorp” client jars.

When pushing your application to ‘Liberty for Bluemix’ with the Cloudant service bound to it, we make the service easier to consume with a process we call “auto-configuration”. Basically, we add configuration elements to the “server.xml” of the Liberty server running your application. This aspect of Bluemix is key for making the application development process as stream-lined as possible. You can read more about what exactly the auto-config for Cloudant does here: Cloudant Docs on Bluemix

Requirements:

Steps:

  1. Open Eclipse and create a new Maven projectNew Maven Project
    • File > New > (Other) > Maven Project
    • Check “Create a simple project (skip archetype selection)” > Next
    • Set the following values
      • Group ID: com.blog
      • Artifact ID: sample
      • Version: 1
      • Packaging: war
    • Leave everything else as-is and Click Finish
  2. Ensure that the projected is faceted properlyFacets
    • Right Click your project > Properties > Project Facets
    • Check Dynamic Web Module
    • Change Java version to 1.6 or 1.7 (you may need to change the JRE of your project to match this)
    • Click Finish
  3. Copy dependencies into pom.xml in the <project> stanza

    pom.xml:


    <dependencies>
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
    </dependency>
    <dependency>
    <groupId>org.ektorp</groupId>
    <artifactId>org.ektorp</artifactId>
    <version>1.4.1</version>
    <scope>provided</scope>
    </dependency>
    </dependencies>

    Note: The “provided” tag means that the container/runtime (in our case, Liberty) will provide these dependencies for your application. This means that Eclipse does not package them in your application’s WEB-INF directory. When pushing your WAR to Bluemix, you should not include the ektorp dependencies in your WEB-INF/lib directory or you will run into classloading issues.

    Save the file

  4. Generate the web.xml which will be used for servlet-mappingGeneration
    • Right click project > Java EE Tools > Generate Deployment Descriptor Stub (may be grayed out if the web.xml already exists)
  5. Create a servlet
    • Right click Project > New > (Other) > Web > Servlet
    • Ensure source folder is sample\src\main\java
    • Java package: com.out
    • Class name: SimpleServlet
    • Click Finish
  6. Ensure servlet mapping is in the web.xml (src/main/webapp/WEB-INF/web.xml)

    <servlet>
    <display-name>SimpleServlet</display-name>
    <servlet-name>SimpleServlet</servlet-name>
    <servlet-class>com.out.SimpleServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>SimpleServlet</servlet-name>
    <url-pattern>/SimpleServlet</url-pattern>
    </servlet-mapping>
  7. Choose one of the two options to have your servlet create a database and add a document.
    Option 1 (Resource Injection):
    This method might not work when using wink servlets
    Add to your servlet (src/main/java/com/out/SimpleServlet.java — replace doGet method)

    import javax.annotation.Resource;

    import org.ektorp.CouchDbConnector;
    import org.ektorp.CouchDbInstance;

    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;

    and


    @Resource(name = "couchdb/cloudant-sample")
    protected CouchDbInstance _db;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String dbname = "my_database";
    try {
    //creates a database with the specified name
    CouchDbConnector dbc = _db.createConnector(dbname, true);
    response.getWriter().println("Created database: " + dbname);
    //create a simple doc to place into your new database
    Map<String, Object> doc = new HashMap<String, Object>();
    doc.put("_id", UUID.randomUUID().toString());
    doc.put("season", "summer");
    doc.put("climate", "arid");
    dbc.create(doc);
    response.getWriter().println("Added a simple doc!");
    } catch (Exception e) {
    response.getWriter().println(e.getMessage());
    }
    }

    Note: If you still have import issues, ensure your pom.xml is configured correctly and that your project’s Java facet is on 1.6 or 1.7

    Option 2 (JNDI lookup):
    Add to your servlet (src/main/java/com/out/SimpleServlet.java — replace doGet method)


    import javax.annotation.Resource;

    import org.ektorp.CouchDbConnector;
    import org.ektorp.CouchDbInstance;

    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;

    import javax.naming.InitialContext;


    and

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String dbname = "my_database";
    CouchDbInstance _db = null;
    try {
    _db = (CouchDbInstance) new InitialContext().lookup("java:comp/env/couchdb/cloudant-sample");
    //creates a database with the specified name
    CouchDbConnector dbc = _db.createConnector(dbname, true);
    response.getWriter().println("Created database: " + dbname);
    //create a simple doc to place into your new database
    Map<String, Object> doc = new HashMap<String, Object>();
    doc.put("_id", UUID.randomUUID().toString());
    doc.put("season", "summer");
    doc.put("climate", "arid");
    dbc.create(doc);
    response.getWriter().println("Added a simple doc!");
    } catch (Exception e) {
    response.getWriter().println(e.getMessage());
    }
    }


    and add to your web.xml (src/main/java/webapp/web.xml)

    <resource-env-ref>
    <resource-env-ref-name>couchdb/cloudant-sample</resource-env-ref-name>
    <resource-env-ref-type>org.ektorp.CouchDbInstance</resource-env-ref-type>
    </resource-env-ref>

    Note: If you still have import issues, ensure your pom.xml is configured correctly and that your project’s Java facet is on 1.6 or 1.7

  8. Right click project > Export > Web > WAR file
  9. Push your WAR file to Bluemix (First time? Learn here).
    The following command creates your application but doesn’t start it (we don’t want to start it until we bind our Cloudant service)
    cf push &lt;some_unique_app_name&gt; -m 512M -p &lt;path_to_your_war_file&gt; --no-start
  10. Create and bind a Cloudant service using CLI or ACE. The service must be named “cloudant-sample“.
    Note: The name of the service determines the name of the db connector resource in the namespace. Since we named it cloudant-sample, the resource will be under the namespace “couchdb/cloudant-sample”. All Cloudant db connector resources have the prefix “couchdb/”. The @Resource annotation/JNDI-lookup we used in the servlet complies with this.
    Cloudant Service
    Cloudant
  11. Repush. You must repush for the environment variable changes to take effect.
    Note: If you are using ACE, there may be a pop-up asking if you want to restart your application. This is insufficient — you still need to push your application using CF.

    cf push &lt;some_unique_app_name&gt; -m 512M -p &lt;path_to_your_war_file&gt;
  12. Access your application and append “/SimpleServlet” to the end of the URL. You should see a message telling you that the database has been created. For example, if my application is at myCoolApp.mybluemix.net, I would need to hit myCoolApp.mybluemix.net/SimpleServlet.
  13. Go to ACE and click your service — “cloudant-sample”. Then, launch your Cloudant dashboard using the “Launch” button. You’ll see your database “my_database” in the dashboard!
    Cloudant-sample

Developer Advocate

More stories
May 7, 2019

We’ve Moved! The IBM Cloud Blog Has a New URL

In an effort better integrate the IBM Cloud Blog with the IBM Cloud web experience, we have migrated the blog to a new URL: www.ibm.com/cloud/blog.

Continue reading

May 1, 2019

Two Tutorials: Plan, Create, and Update Deployment Environments with Terraform

Multiple environments are pretty common in a project when building a solution. They support the different phases of the development cycle and the slight differences between the environments, like capacity, networking, credentials, and log verbosity. These two tutorials will show you how to manage the environments with Terraform.

Continue reading

April 29, 2019

Transforming Customer Experiences with AI Services (Part 1)

This is an experience from a recent customer engagement on transcribing customer conversations using IBM Watson AI services.

Continue reading