Categories
Atbash JAX-RS MicroProfile

MicroProfile Rest Client for Java SE

Introduction

One of the cool specifications produced by the MicroProfile group is the Rest Client for MicroProfile  available from MP release 1.3.

It builds on top of the Client API of JAX-RS and allows you to use type-safe access to your endpoints without the need to programmatic interact with the Client API.

MicroProfile compliant server implementations need to implement this specification, but nothing says we cannot expand the usage into other environments (with a proper implementation) like use in Java SE (JavaFX seems must useful here) and plain Java EE.

Atbash has created an implementation of the specification so that it can be used in these environments and will use it within Octopus framework to propagate authentication and authorization information automatically in calls to JAX-RS endpoints.

The specification

A few words about the specification itself. JAX-RS 2.x contains a client API which allows you to access any ‘Rest’ endpoint in a uniform way.

Client client = ClientBuilder.newClient();
WebTarget employeeWebTarget = client.target("http://localhost:8080/demo/data").path("employees");
employeeWebTarget.request(MediaType.APPLICATION_JSON).get(new GenericType<List<Employee>>() {
});

This client API is great because we can use it to call any endpoint, not even limited to Java ones. As long as they behave in a standard way.

But things can be improved, by moving away from the programmatic way of performing these calls, into a more declarative way.

If we could define some kind of interface like this

@Path("/employees")
public interface EmployeeService {

@GET
@Produces(MediaType.APPLICATION_JSON)
List<Employee> getAll();
}

And we just could ask an implementation of this interface which performs the required steps of creating the Client, WebTarget and invoke it for us in the background. This would make it much easier for the developer and makes it much more type-safe.

Creating the implementation of that interface is what MicroProfile Rest Client is all about.

The interface defined above can then be injected in any other CDI bean (need to add the @RegisterRestClient on the interface and preferably a CDI scope like @ApplicationScoped) and by calling the method, we actually perform a call to the endpoint and retrieve the result.

@Inject
@RestClient
private EmployeeService employeeService;

public void doSomethingWithEmployees() {
....
... employeeService.getAll();
....
}

Atbash Rest Client

The specification also allows for a programmatic retrieval of the implementation, for those scenarios where no CDI is available.
However, remember that if we are running inside a CDI container, we can always retrieve some CDI bean by using

CDI.current().select();

from within any method.

The programmatic retrieval is thus an ideal candidate to use it in other environments or frameworks like JavaFX (basically every Java SE program), Spring, Kotlin, etc …

The programmatic retrieval starts from the RestClientBuilder with the newBuilder() method.

EmployeeService employeeService = RestClientBuilder.newBuilder()
    .baseUrl(new URL("https://localhost:8080/server/data"))
    .build(EmployeeService.class);

The above retrieves also an implementation for the Employee retrieval endpoint we used earlier on in this text.

For more information about the features like Exception handling, adding custom providers and more, look at the specification document.

The Atbash Rest Client is an implementation in Java 7 which can run on Java SE. It is created mainly for the Octopus Framework to propagate the user authentication (like username) and authorization information (like permissions) to JAX-RS endpoints in a transparent, automatically way.

A ClientRequestFilter is created in Octopus which creates a JWT token (compatible with MicroProfile JWT auth specification) containing username and permissions of the current user and this Filter can then be added as a provider to the MicroProfile Rest Client to have this security information available within the header of the call.

Since the current Octopus version is still based on Java SE 7, no other existing implementation could be used (MicroProfile is Java SE 8 based). The implementation is based on the DeltaSpike Proxy features and uses any Client API compatible implementation which is available at runtime.

Compliant, not certified.

Since all the MicroProfile specifications are Java 8 based, the API is also converted to Java SE 7. Except for a few small incompatibilities, the port is 100% interchangeable.

The most notable difference is creating the builder with the newBuilder() method. In the original specification, this is a static method of an interface which is not allowed in Java 7. For that purpose, an abstract class is created, AbstractRestClientBuilder which contains the method.

Other than that, class and method names should be identical, which makes the switch from Atbash Rest Client to any other implementation using Java 8 very smooth.

The Maven dependency has following coordinates (available on Maven Central):

<dependency>
   <groupId>be.atbash.mp.rest-client</groupId>
   <artifactId>atbash-rest-client-impl</artifactId>
   <version>0.5</version>
</dependency>

If you are running on Java 8, you can use the Apache CXF MicroProfile Rest client

<dependency>
   <groupId>org.apache.cxf</groupId>
   <artifactId>cxf-rt-rs-mp-client</artifactId>
   <version>3.2.4</version>
</dependency>

Which also can be used in a plain Java SE environment. Other implementations like the ones within Liberty and Payara Micro aren’t useable standalone in Java SE.

Remark

This first release of Atbash Rest Client is a pre-release, meaning that not all features of the specification are completely implemented. It is just a bare minimum for the a POC within Octopus.
For example, the handling of exceptions (because the endpoint returned a status in the range 4xx or 5xx) isn’t completely covered yet.

The missing parts will be implemented or improved in a future version.

Conclusion

With the MicroProfile Rest Client specification, it becomes easy to call some JAX-RS endpoints in a type-safe way. By using a declarative method, calling some endpoint becomes as easy as calling any other method within the JVM.

And since micro-services need to be called at some point from non-micro-service code, Java SE executable implementation is very important. It makes it possible to call it from plain Java EE, Java SE, any other framework or a JVM based language.

Have fun.

Categories
Atbash Overview

Atbash repositories overview

Now that I’m working a bit more than 6 months on the Atbash repositories, it is time to give you some overview of them.

For the moment, almost all of them are geared towards Java EE 7 and Java 7.

The idea is to create a MicroProfile compatible experience on Java EE 7. As much as possible of course. Since MicroProfile is based on Java 8, it is not always easy (or possible) to have an identical experience.

But the idea is to give the developers the possibility to have a “smooth” migration from Java EE 7 to MicroProfile by having all or the most important specifications, available on those servers.

Utility repository

Github

This contains some code used in multiple other Atbash repositories. It is not directly related to the goal but can have some usages in any project.

utils-se

– BASE64 encoder and decoder
– Utility class related to searching classes and resources on different class loaders (Current Thread, class loader of utility class or System class loader) and instantiating classes with advanced argument matching.
– Reading library or framework version from manifest file
– Check to see if an application is running within a CDI container
– Utilities related to verification and handling proxies (like determining original class)

– Reflection utilities useable in unit testing (so that we can read and set private properties without the need for setters and getters which would only be needed for testing)

utils-cdi

– Programmatic retrieval of CDI Beans, also for an optional bean (bean defined by Producer method which may or may not be present)
– Retrieval of a bean defined by Producer method involving generic types (issue due to type erasure)

– Fake bean manager useable within unit tests to supply some Mock Cdi bean instances when using programmatic CDI bean retrieval.

utils-jsf

– Creating a method expression based on the expression value
– Retrieving property values from JSF components (taking into account expressions and static values)
– Custom component finding which starts at the parent itself but then extends to the parent until found or view root is reached.

Atbash JSON (Java SE)

GitHub

Alternative JSON-B implementation (not following the specs!) to convert Java instances to JSON and vice versa. The code is adapted from the JSON smart framework (no longer maintained) for the use cases within Atbash (see Atbash JWT support) and extended to have customizations.

JWT Support (Java SE + CDI)

GitHub

The code in this repository is to support JWT (JSON Web Token, signed but also encrypted) as they appear in protocols like OAuth2 and OpenId Connect.

To support this encoding and decoding, there is also a unified handling of cryptographic keys. It is capable of reading them from a PEM file, a Java Keystore, a JWK and a JWKSet. Various encrypted formats for the Private Key are supported.

But the idea goes a bit further than just support OpenId Connect JWTs. Instead of exchanging data as JSON, why not exchange them as JWT. That way, we are not only transferring information but also make some guarantees like sender verification and end to end protection as we can detect changes through the signing.

Atbash Config (Java SE + CDI)

GitHub

The Atbash config is a Java 7 port of the MicroProfile Config specification and the Apache Geronimo implementation.

But there are also some extensions created like
– Support for custom named configuration files.
– Support for Stages so that based on a system property, values can be overridden in environments like Test environment.
– Support for custom formatted date values
– Logging of configuration values at startup of the application.
– Support for YAML format.

There is also a Config provider for testing available where the configuration values are stored in a HashMap.

Atbash Config server (MicroProfile Product)

GitHub

Allows defining the configuration values for MicroProfile application in a central place. These applications can retrieve the values using a JAX-RS endpoint.

There is also a client implementation available which, when added to the application, retrieves the values automatically, based on the configured endpoint of the config server.

Jerry (JSF)

GitHub

Jerry defines a JSF Renderer interceptor which allows you to perform various tasks on any JSF component.

It is the basis for a more advanced validation mechanism for JSF and the declarative security features of Octopus for JSF components.

Valerie (JSF, Bean Validation)

GitHub

Using the interceptor mechanism of Jerry, Valerie places the validation constraints of the Java properties (like not null, length etc) automatically on the JSF components it uses.
This way it allows to have the visual aspects of these constraints on the JSF component HTML representation and JSF validation without the need to put these constraints as JSF attribute values.

Octopus (Java SE, Java FX, CDI, JSF, JAX-RS)

GitHub

Octopus is a large framework consisting of small artifacts that bring you every aspect of authentication and authorization for Java EE and MicroProfile applications.

  • Permission-based framework
  • Secures URL, JSF components, and CDI and EJB method calls
  • Support for Java SE, JavaFX, JAX-RS and JSF
  • Integrates with OAuth2, OpenId Connect, LDAP, database, JWT, KeyCloak, CAS, …
  • Custom OpenId Connect solution within a microservices environment
  • Compatible with (and using) Microprofile (Config, Rest Client, MP-JWT, …), Java EE Security API, …
  • Very flexible, can be easily integrated within your application
  • Tightly integrated with CDI
  • Type-safe definition of permissions
  • Declarative declaration of JSF security (with tags, not using rendered attribute)
  • A custom voter can be created for more complex security requirements

Dependencies overview

The following Neo4J graph gives you an overview of the dependencies between these repositories and the relation with other libraries. Octopus is left out of the image because it would complicate it too much.

Have fun