Jakarta NoSQL Driver for Keep

Oct 9, 2022, 3:41 PM

Tags: jakartaee java
  1. Jakarta NoSQL Driver for the AppDev Pack, Part 1
  2. Jakarta NoSQL Driver for the AppDev Pack, Part 2
  3. Jakarta NoSQL Driver for Keep

In what has surreptitiously turned into something of a series, I followed up my recent tinkering with Jakarta NoSQL, the AppDev Pack, and Keycloak with doing something similar with Keep.

Keep, like the AppDev Pack's Proton task, provides a remote API for Domino data. It differs from the ADP in a couple notable ways:

  1. It uses REST endpoints instead of gRPC. The pros and cons of comparing the two are well beyond the scope of this post, but you can say that a REST API is easier to work with using any old HTTP client, while gRPC has higher performance when thrashed. For the purposes of a JNoSQL driver, this is entirely an implementation detail.
  2. Keep imposes rules about data access on top of what you'd normally do with Domino. While Proton and DAS give you direct document access, Keep requires configuring individual forms and views, as well as defining specific types and access levels for fields. It's a focused REST API builder of its own, suitable for providing access to Domino data to clients directly.

The Client

The AppDev Pack ships with a Java client library presumably generated from the HCL-internal spec. Since Keep is REST-based, there's less need for a specific generated client, but it can still be tremendously useful. Keep includes (and is indeed based around) an OpenAPI spec file. The neat thing with those files is that, since they're so common, there are plenty of tools to work with them. One I've used a few times now is OpenAPI Generator, which will take such a spec file and emit bindings for a bunch of languages.

I've used the Java generator before and have gotten familiar with it. Because Java lacked a good standard HTTP client until Java 9 and still doesn't have a core-API standard type-safe client or JSON library, this generator provides options for a good number of common choices. Since this driver is targeting a Jakarta EE environment and it's fair to assume MicroProfile will be around, I went with that: JSON access is done via JSON-B and REST access is done via the ever-delightful MicroProfile Rest Client. This pair ended up producing much-cleaner client code than the previous generation I had done, which used the Apache HttpClient library directly and Jackson for JSON. I think that, post-generation, I had to go in and change some javax imports to jakarta, but otherwise it worked smoothly.

The generator emitted interfaces marked with @RegisterProvider (making them accessible via CDI) and then using JAX-RS annotations to define method signatures. For example (trimmed and reformatted):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
@RegisterProvider(ApiExceptionMapper.class)
@Path("")
public interface DataApi  {
	/* snip */

    /**
     * Send a DQL query and get JSON documents back
     *
     */
    @POST
    @Path("/query")
    @Consumes({ "application/json" })
    @Produces({ "application/json" })
    public List<Map<String, Object>> query(
		@QueryParam("dataSource") @NotNull String dataSource,
		@QueryParam("action") @NotNull String action,
		@Valid QueryRequest queryRequest,
		@QueryParam("richTextAs") RichTextRepresentation richTextAs,
		@QueryParam("count") Integer count,
		@QueryParam("start") Integer start
	) throws ApiException, ProcessingException;
}

It's possible that I had to change an earlier DominoDocument type to Map<String, Object> to account for the ever-varying content of Domino documents.

In any event, each of the operations from Keep's OpenAPI spec got a method like this, grouped into interfaces like DataApi, CodeApi, etc., also based on values in the spec.

Authentication

Lucky for me, a lot of the stuff I did to set up Keycloak authentication with the AppDev Pack carried over here. Keep, for the most part, uses JWT authentication, with tokens often coming from its /auth endpoint. It can also work with external JWT providers like Keycloak. To do that, you can configure Keep with your provider's public key, after which Keep will trust tokens issued by it.

For my setup, I configured Keycloak to emit Keep-friendly tokens, adding in a Domino-format DN and Keep-friendly scopes like $DATA. Once I did that, Keep started trusting tokens I acquired from Keycloak, which I passed to it from my Liberty login the same way I had with my ADP testing.

Implementation and Conclusion

After this point, the implementation itself is actually the least interesting. I copied the code for the Proton driver and mostly swapped out method calls and object types. Since the documents in both cases are treated as JSON data, most of my utility code was already just fine.

Keep does provide view access, which is something that Proton doesn't, so I may implement that. Though I was originally hostile to the idea of adding views to the driver, it's an unfortunate necessity in Domino work, especially when building on top of existing applications.

As it is, the driver isn't in a proper state for release, but I expect that I'll have cause to return to it and implement the missing pieces - views, attachments, and so forth. It's also just a good exercise in the mean time for working more heavily with things like the MP Rest Client, and it's good to see how well it holds up.

Commenter Photo

Heiko Voigt - Oct 9, 2022, 4:10 PM

That's my conclusion as well - KEEP offers similar calls plus some more APIs - that's why I don't get why HCL is holding back from the AppDevPack. Most code segments can be easily transferred and the ideas are similar. This is good news on the one hand - we shall see what the future holds for us.

New Comment