Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created blog file cloudant-with-open-liberty.adoc #4160

Merged
merged 23 commits into from
Dec 6, 2024
Merged
Changes from 6 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
23f6848
Created cloudant-with-open-liberty.adoc
revijay Nov 21, 2024
56c8ec8
Updated blog file cloudant-with-open-liberty.adoc
revijay Nov 24, 2024
753eb77
Incorporated review comments
revijay Nov 26, 2024
546fb88
Updated blog to add an intro and summary section
revijay Nov 26, 2024
6a45f84
Updated introduction and added some more information in the blog
revijay Nov 27, 2024
4a50e24
Incorporated review comments
revijay Nov 27, 2024
f9125dc
Remove unnecessary URL params
mswatosh Nov 27, 2024
2194585
committed some minor changes in the code when working with IAM
revijay Nov 28, 2024
37f653d
Merge branch 'cloudant_4152' of https://github.com/OpenLiberty/blogs …
revijay Nov 28, 2024
4d00646
Update posts/2024-11-25-cloudant-with-open-liberty.adoc
revijay Dec 4, 2024
b4e8d46
Update posts/2024-11-25-cloudant-with-open-liberty.adoc
revijay Dec 4, 2024
f346a67
Update posts/2024-11-25-cloudant-with-open-liberty.adoc
revijay Dec 4, 2024
5fec7c7
Update posts/2024-11-25-cloudant-with-open-liberty.adoc
revijay Dec 4, 2024
e101667
Update posts/2024-11-25-cloudant-with-open-liberty.adoc
revijay Dec 4, 2024
d4d0009
Update posts/2024-11-25-cloudant-with-open-liberty.adoc
revijay Dec 4, 2024
78da96d
Update posts/2024-11-25-cloudant-with-open-liberty.adoc
revijay Dec 4, 2024
37cd405
Update posts/2024-11-25-cloudant-with-open-liberty.adoc
revijay Dec 4, 2024
51ba3ce
Updated based on review comments
revijay Dec 4, 2024
5ee3fdd
Update 2024-11-25-cloudant-with-open-liberty.adoc
revijay Dec 4, 2024
15816ad
Update posts/2024-11-25-cloudant-with-open-liberty.adoc
revijay Dec 6, 2024
af13019
Update posts/2024-11-25-cloudant-with-open-liberty.adoc
revijay Dec 6, 2024
2ea7a9f
Renamed post file name
revijay Dec 6, 2024
8307d37
minor edits
dmuelle Dec 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
225 changes: 225 additions & 0 deletions posts/2024-11-25-cloudant-with-open-liberty.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
---
layout: post
title: "Access Cloudant with Open Liberty using CDI"
categories: blog
author_picture: https://avatars3.githubusercontent.com/revijay
author_github: https://github.com/revijay
seo-title: Access Cloudant with Open Liberty using CDI - OpenLiberty.io
seo-description: Using Cloudant with Open Liberty previously meant enabling the cloudant-1.0 feature and configuring several elements in server.xml. With CDI and MicroProfile Config, you can easily configure access to Cloudant with a CDI producer. The cloudant-1.0 feature was implemented using Java Cloudant Client library which is no longer supported, so in this demonstration we are using the new Cloudant SDK for Java.
blog_description: "Using Cloudant with Open Liberty previously meant enabling the cloudant-1.0 feature and configuring several elements in server.xml. With CDI and MicroProfile Config, you can easily configure access to Cloudant with a CDI producer. The cloudant-1.0 feature was implemented using Java Cloudant Client library which is no longer supported, so in this demonstration we are using the new Cloudant SDK for Java."
open-graph-image: https://openliberty.io/img/twitter_card.jpg
open-graph-image-alt: Open Liberty Logo
---
= Access Cloudant client with Open Liberty using CDI
Reshmi Vijayan <https://github.com/revijay>
:imagesdir: /
:url-prefix:
:url-about: /

Cloudant, an IBM-managed NoSQL database built on top of Apache CouchDB, provides a powerful solution for document-oriented storage with high availability and scalability. Cloudant provides a robust, flexible, and highly scalable NoSQL database solution that is tailor-made for cloud-native applications. Cloudant with Open Liberty offers a seamless way to build, deploy, and scale your Java applications with efficient, scalable data storage.
revijay marked this conversation as resolved.
Show resolved Hide resolved

Using Cloudant with Open Liberty previously meant enabling the `cloudant-1.0` feature and configuring several elements in ``server.xml``. With CDI and MicroProfile Config, you can easily configure access to Cloudant with a CDI producer (for an introduction to using CDI producers, see the https://openliberty.io/guides/cdi-intro.html[Injecting Dependencies into Microservices guide]). The cloudant-1.0 feature was implemented using Java Cloudant Client library which is no longer supported, so in this demonstration we are using the new Cloudant SDK for Java.
revijay marked this conversation as resolved.
Show resolved Hide resolved

== A CDI producer for Cloudant
With a CDI producer, you can easily provide a Cloudant client to your application by which you can inject the client into various parts of the application in a type-safe and flexible way, while leveraging the benefits of dependency injection (such as lifecycle management and configuration). Also, we are using link:{url-prefix}/guides/microprofile-config-intro.html[MicroProfile Config] to make the configuration of Cloudant driver simple.
revijay marked this conversation as resolved.
Show resolved Hide resolved
This example demonstrates how to create a CDI producer to inject a Cloudant client:
[source, java]
----
@ApplicationScoped
public class CloudantProducer {

@Inject
@ConfigProperty(name = "cloudant.host", defaultValue = "localhost")
String host;

@Inject
@ConfigProperty(name = "cloudant.port", defaultValue = "5984")
String port;

@Inject
@ConfigProperty(name = "cloudant.username")
String username;

@Inject
@ConfigProperty(name = "cloudant.password")
String encodedPassword;

@Produces
public Cloudant createCloudant() {
String password = PasswordUtil.passwordDecode(encodedPassword);
BasicAuthenticator authenticator = new BasicAuthenticator.Builder()
.username(username)
.password(password)
.build();

Cloudant service = new Cloudant("cloudant", authenticator);
service.setServiceUrl("http://" + host + ":" + port);

return service;
}
}
----
One of the advantages of using a CDI producer is that it can be tailored to your needs. For improved security,the createCloudant method uses Open Liberty's password decoding. This requires the following Maven dependency:
revijay marked this conversation as resolved.
Show resolved Hide resolved
[source,xml]
----
<dependency>
<groupId>com.ibm.websphere.appserver.api</groupId>
<artifactId>com.ibm.websphere.appserver.api.passwordUtil</artifactId>
<version>1.0.95</version>
</dependency>
----
You also need to enable the feature in `server.xml`:
revijay marked this conversation as resolved.
Show resolved Hide resolved
[source, xml]
----
<feature>passwordUtilities-1.0</feature>
----
Now, by placing the following snippet in your ``microprofile-config.properties`` or `server.env` file, the values for user and password will be pulled into the CloudantProducer class:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Now, by placing the following snippet in your ``microprofile-config.properties`` or `server.env` file, the values for user and password will be pulled into the CloudantProducer class:
Now, by placing the following snippet in your ``microprofile-config.properties`` or `server.env` file, the values for user and password will be pulled into the `CloudantProducer` class:

[source, text]
----
cloudant.user=admin
cloudant.password={aes}AEEjCqvh7XAwDxrdYC6BUbqYlwqI8NAxRkWWWq7muxZu
cloudant.dbname=testdb
----

Instead of using `BasicAuthentication` with a username and password, Cloudant also supports `IAM (Identity and Access Management)` authentication, which allows users and applications to authenticate using secure API keys or IAM tokens. By using IAM authentication, we can avoid the risks associated with managing passwords and ensure that only authorized entities can interact with Cloudant databases.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Instead of using `BasicAuthentication` with a username and password, Cloudant also supports `IAM (Identity and Access Management)` authentication, which allows users and applications to authenticate using secure API keys or IAM tokens. By using IAM authentication, we can avoid the risks associated with managing passwords and ensure that only authorized entities can interact with Cloudant databases.
Instead of using `BasicAuthentication` with a username and password, Cloudant also supports Identity and Access Management (IAM ) authentication, which allows users and applications to authenticate using secure API keys or IAM tokens. By using IAM authentication, we can avoid the risks associated with managing passwords and ensure that only authorized entities can interact with Cloudant databases.

Follow the https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-getting-started-with-cloudant&_ga=2.42518757.1165320250.1604321683-1614077795.1594908456[IBM Cloudant Setup] guide to create a Cloudant instance and API key for accessing it.
mswatosh marked this conversation as resolved.
Show resolved Hide resolved

The code snippet below shows how can we create a CDI Producer to inject a Cloudant client with IAM authentication.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The code snippet below shows how can we create a CDI Producer to inject a Cloudant client with IAM authentication.
The following code snippet shows how to create a CDI Producer to inject a Cloudant client with IAM authentication.

[source, java]
----
@ApplicationScoped
public class CloudantProducer {

@Inject
@ConfigProperty(name = "cloudant.host", defaultValue = "localhost")
String host;

@Inject
@ConfigProperty(name = "cloudant.port", defaultValue = "5984")
String port;

@Inject
@ConfigProperty(name = "cloudant.apikey")
String apikey;

@Produces
public Cloudant createCloudant() {
IamAuthenticator authenticator = new IamAuthenticator.Builder()
.apikey("apikey")
.build();

Cloudant service = new Cloudant("cloudant", authenticator);
service.setServiceUrl("http://" + host + ":" + port);

return service;
}
}
----
revijay marked this conversation as resolved.
Show resolved Hide resolved

== Injecting the Cloudant client
Here is an example of using the CDI producer to inject a Cloudant client in a JAX-RS application.
[source, java]
----
@Inject
Cloudant client;

revijay marked this conversation as resolved.
Show resolved Hide resolved
@Inject
@ConfigProperty(name = "cloudant.dbname")
String dbname;

@POST
@Path("/add")
@Consumes(MediaType.APPLICATION_JSON)
public void add(CrewMember crewMember) {
Document newCrewMember = new Document();
newCrewMember.put("Name",crewMember.getName());
newCrewMember.put("Rank",crewMember.getRank());
newCrewMember.put("CrewID",crewMember.getCrewID());

PostDocumentOptions createDocumentOptions =
new PostDocumentOptions.Builder()
.db(dbname)
.document(newCrewMember)
.build();
DocumentResult createDocumentResponse = client
.postDocument(createDocumentOptions)
.execute()
.getResult();
}
----

In the above code:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In the above code:
In this example:


* `@Inject` is used to inject the Cloudant client instance provided by the CDI producer.
* The `PostDocumentOptions` is a builder class that allows you to specify various options when posting the document. You must provide the db name and the document content.
* The `postDocument` is the main method that posts the document to the specified database. It returns a DocumentResult object which contains metadata about the inserted document (like its _id and _rev).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* The `postDocument` is the main method that posts the document to the specified database. It returns a DocumentResult object which contains metadata about the inserted document (like its _id and _rev).
* The `postDocument` is the main method that posts the document to the specified database. It returns a `DocumentResult` object that contains metadata about the inserted document (like its` _id` and `_rev`).


Similarly, we can delete a document from Cloudant using its `id`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does "its" refer to here? the document? Cloudant?

revijay marked this conversation as resolved.
Show resolved Hide resolved
[source, java]
----
@DELETE
@Path("/{id}")
public String remove(@PathParam("id") String id) {
GetDocumentOptions documentInfoOptions =
new GetDocumentOptions.Builder()
.db(dbname)
.docId(id)
.build();

Document document = client
.getDocument(documentInfoOptions)
.execute()
.getResult();

DeleteDocumentOptions deleteDocumentOptions =
new DeleteDocumentOptions.Builder()
.db(dbname)
.docId(id)
.rev(document.getRev())
.build();

DocumentResult deleteDocumentResponse = client
.deleteDocument(deleteDocumentOptions)
.execute()
.getResult();
}
----
In the above example:
revijay marked this conversation as resolved.
Show resolved Hide resolved

* The `GetDocumentOptions` class is used to configure parameters for retrieving a document from a Cloudant database. It allows you to specify the database name, document ID, and optional parameters like the document revision, whether to include attachments, conflicts, or deleted information in the response. The class uses the builder pattern to set these options before making the request to Cloudant.
* The `DeleteDocumentOptions` class is used to configure parameters for deleting a document from a Cloudant database. It allows you to specify the database name, the document ID, and the revision (_rev) of the document to ensure that the correct version is deleted (to prevent race conditions). This class uses the builder pattern to set options before sending the delete request to Cloudant.
revijay marked this conversation as resolved.
Show resolved Hide resolved

== No need for a Cloudant feature
revijay marked this conversation as resolved.
Show resolved Hide resolved
Previously, using Cloudant required enabling the `cloudant-1.0` feature. Even if the Cloudant SDK for Java's API changes, simple updates to your CDI producer will allow it to continue to work. You should remove the `cloudant-1.0` feature from your `server.xml` when using the new Cloudant SDK for Java.

The Cloudant SDK for Java should be bundled in your application. To do this with Maven you can use a dependency:
revijay marked this conversation as resolved.
Show resolved Hide resolved

[source, xml]
----
<dependency>
<groupId>com.ibm.cloud</groupId>
<artifactId>cloudant</artifactId>
<version>x.x.x</version>
</dependency>
----
If you have multiple applications accessing Cloudant, instead of bundling the Cloudant SDK for Java with each application, you can configure a shared library in your `server.xml` like this:
[source, xml]
----
<library id="cloudantLib">
<file name="${shared.resource.dir}/cloudant-x.x.x.jar" />
</library>

<application contextRoot="/" location="app1.war">
<classloader sharedLibraryRef="cloudantLib"/>
</application>

<application contextRoot="/app2" location="app2.war">
<classloader sharedLibraryRef="cloudantLib"/>
</application>
----

== Summary
In this blog post, we explored how easy it is to create a CDI producer for Cloudant, and configure it with MicroProfile Config to help integrate Cloudant into an Open Liberty-based Java application, leveraging the power of Cloudant's NoSQL database with the flexibility of Open Liberty’s lightweight, cloud-native architecture.
The full sample is available on GitHub here: link:https://github.com/OpenLiberty/sample-cloudant[https://github.com/OpenLiberty/sample-cloudant].
revijay marked this conversation as resolved.
Show resolved Hide resolved

By combining the strengths of Cloudant and Open Liberty, developers can create powerful, cloud-native applications that are both flexible and scalable, with minimal infrastructure management. This integration ensures real-time data access, robust data storage, and seamless scaling—all essential for modern, data-driven applications in the cloud.