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 cloudant-with-open-liberty.adoc #4153

Merged
merged 1 commit into from
Nov 21, 2024
Merged
Changes from all commits
Commits
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
170 changes: 170 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,170 @@
---
layout: post
title: "Access Cloudant client with Open Liberty using CDI"
Copy link
Member

Choose a reason for hiding this comment

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

"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 client with Open Liberty using CDI - OpenLiberty.io
Copy link
Member

Choose a reason for hiding this comment

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

"Access Cloudant with Open Liberty using CDI"

seo-description: Using Cloudant with Open Liberty previously meant enabling the cloudant-1.0 feature and configuring several elements in server.xml. Now, with improvements in CDI and the introduction of MicroProfile Config, you can easily configure access to Cloudant with a CDI producer. Earlier cloudant-1.0 feature was implemented using Java Cloudant Client library which is not under active development now, so in this demonstration we are using Cloudant Java SDK library.
Copy link
Member

@mswatosh mswatosh Nov 21, 2024

Choose a reason for hiding this comment

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

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 the Java Cloudant Client library which is no longer supported, so in this demonstration we are using the new Cloudant SDK for Java.

Copy link
Member

Choose a reason for hiding this comment

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

Same recommendation for blog_description

blog_description: "Using Cloudant with Open Liberty previously meant enabling the cloudant-1.0 feature and configuring several elements in server.xml. Now, with improvements in CDI and the introduction of MicroProfile Config, you can easily configure access to Cloudant with a CDI producer. Earlier cloudant-1.0 feature was implemented using Java Cloudant Client library which is not under active development now, so in this demonstration we are using Cloudant Java SDK library."
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: /

Using Cloudant with Open Liberty previously meant enabling the `cloudant-1.0` feature and configuring several elements in ``server.xml``. Now, with improvements in CDI and the introduction of 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]). Earlier cloudant-1.0 feature was implemented using Java Cloudant Client library which is not under active development now, so in this demonstration we are using Cloudant Java SDK library.
Copy link
Member

Choose a reason for hiding this comment

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

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 the Java Cloudant Client library which is no longer supported, so in this demonstration we are using the new Cloudant SDK for Java.


== 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).This example demonstrates how to create a CDI producer to inject a Cloudant client:
[source, java]
----
@ApplicationScoped
public class CloudantProducer {

@Produces
public Cloudant createCloudant() {
return new Cloudant(“cloudant”, new BasicAuthenticator.Builder().build());
Copy link
Member

@mswatosh mswatosh Nov 21, 2024

Choose a reason for hiding this comment

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

This isn't valid since BasicAuthenticator needs a user and password. I think for this blog we should just go straight to the full example vs starting with a minimal example like this. I think more people are familiar with CDI/MP Config than when the MongoDb post was written.

}
}
----

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

Choose a reason for hiding this comment

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

Add a new line under here

@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:

* `@Inject` is used to inject the Cloudant client instance provided by the CDI producer.
* The `postDocument` method demonstrates how to create and post a document in the cloudant database using the injected CloudantClient.
Copy link
Member

Choose a reason for hiding this comment

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

I would go into more detail here, postDocument isn't really what's creating the the document. Maybe describe how the PostDocumentOptions is created with the database name and the new document, and then the postDocument method is used on the injected client to put the document in the database.


== Enhancing the CDI producer
Copy link
Member

Choose a reason for hiding this comment

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

Mentioned above, but use this as the first example

One of the advantages of using a CDI producer is that it can be tailored to your needs. For improved security,the `createCloudant` method can be enhanced to include authentication with a user name and password:

[source,java]
----
@Produces
public Cloudant createCloudant() {
String password = PasswordUtil.passwordDecode(encodedPassword);
BasicAuthenticator authenticator = new BasicAuthenticator.Builder()
.username(username)
.password(password)
.build();

return new Cloudant("cloudant", authenticator);
}
----
This requires `passwordUtilities-1.0`, available as a Maven dependency:
[source,xml]
----
<dependency>
<groupId>io.openliberty.features</groupId>
<artifactId>passwordUtilities-1.0</artifactId>
<version>18.0.0.4</version>
Copy link
Member

Choose a reason for hiding this comment

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

This uses password util now instead:

com.ibm.websphere.appserver.api
com.ibm.websphere.appserver.api.passwordUtil
1.0.95

</dependency>
----

You also need to enable the feature in `server.xml`:
[source, xml]
----
<feature>passwordUtilities-1.0</feature>
----

By default, Cloudant communication occurs over HTTPS (SSL). However, if you're working with a custom Cloudant instance or self-signed certificates, you may need to configure your Open Liberty application to trust the custom certificate.
Copy link
Member

Choose a reason for hiding this comment

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

I'm not familiar with using Cloudant with SSL, is this something that will always be necessary? If it's just for cases where self-signed certificates are used it may not be worth mentioning here, since I think that would apply to any use of self-signed certificates?


You can configure SSL by modifying the server.xml to use your custom SSL certificates:
[source, xml]
----
<sslRegistry id="defaultSSLConfig">
<keyStore file="path/to/keystore.jks" password="password"/>
<trustStore file="path/to/truststore.jks" password="password"/>
</sslRegistry>

<httpEndpoint host="*" httpPort="9080" httpsPort="9443" sslConfigRef="defaultSSLConfig"/>
----

== Configure with MicroProfile Config
Now that you have a more advanced CDI producer, it would be nice to add configurability to some of the variables, like the user and password. Using link:{url-prefix}/guides/microprofile-config-intro.html[MicroProfile Config] makes configuring the Cloudant driver simple. You can add the following to your CDI producer to add configuration:
[source, java]
----
@Inject
Copy link
Member

Choose a reason for hiding this comment

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

Same as above, let's just start with this in the CDI producer

@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 password;

@Inject
@ConfigProperty(name = "cloudant.dbname")
String dbname;
----
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
----
== No need for a Cloudant feature
Previously, using Cloudant required enabling the `cloudant-1.0` feature. Even if the Cloudant Java Driver 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 newer versions of Cloudant with a CDI producer.
Copy link
Member

Choose a reason for hiding this comment

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

Previously, using Cloudant required enabling the cloudant-1.0 feature. You should remove the cloudant-1.0 feature from your server.xml when using the new Cloudant SDK for Java.


The Cloudant client should be bundled in your application. To do this with Maven you can use a dependency:
Copy link
Member

Choose a reason for hiding this comment

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

The Cloudant SDK for Java should be bundled in your application. To do this with Maven you can use a dependency:


[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 client library, 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>
----

This illustrates how easy it is to create a CDI producer for Cloudant, and configure it with MicroProfile Config that help you to 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]