Trang chủ‎ > ‎IT‎ > ‎IBM Bluemix‎ > ‎

Java and Cloudant NoSQL DB on Bluemix

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:

    [code language=”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>
    [/code]

    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)

    [code language=”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>
    [/code]

  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)

    [code language=”java”]
    import javax.annotation.Resource;

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

    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    [/code]

    and

    [code language=”java”]
    @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());
    }
    }
    [/code]

    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)
    [code language=”java”]
    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;
    [/code]
    and
    [code language=”java”]
    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());
    }
    }
    [/code]

    and add to your web.xml (src/main/java/webapp/web.xml)
    [code language=”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>
    [/code]

    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 <some_unique_app_name> -m 512M -p <path_to_your_war_file> --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 <some_unique_app_name> -m 512M -p <path_to_your_war_file>
  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 hitmyCoolApp.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
Comments