{{announcement.body}}
{{announcement.title}}

Implementing Dynamic Resource-Based Services in Java With Ressor

DZone 's Guide to

Implementing Dynamic Resource-Based Services in Java With Ressor

In this post, we take a closer look at the open-source Ressor framework and how to implement dynamic resource-based services in Java.

· Java Zone ·
Free Resource

Introduction

Ressor is an open-resource framework for developing dynamic Java-based services and components in which business logic is based on some resource data. The resource could be anything — file on local File System, YAML configuration from GitHub repository, etc.

Consider, for example, a weather prediction service or a stock market price provider, which pulls new data over an HTTP endpoint. These kinds of services are useless if they operate with stale data, so they should detect and reload continuously.

You may also like: Dynamic, Modular Microservices With Java EE

The key idea of Ressor is to hide away all the complexity related to working with data sources, content parsing, and dynamic reloading. It provides a declarative API, with which you define services once and use for the whole application runtime.

How it Works

Ressor generates a special proxy class that inherits your service type. Under the hood, this proxy delegates all method calls to the most up-to-date instance of your service/component. To create it, it loads data from the provided source, parses it using translators, and calls the constructor/factory method of your class.

Ressor provides a declarative API, implementing the most popular sources and file formats. During service instantiation, you should define what your source, resource, and translator are. Thus, after service is created, you can subscribe to further resource changes. Versioning is also supported using different reload strategies, depending on the kind of data source. This allows to reload only the data which was actually changed, saving the network/disk bandwidth and CPU resources.

This approach aligns best with IoC/DI frameworks, such as Spring, where you register the beans only once during context startup. You can safely do it with Ressor services as well. In this case, Ressor will implicitly make sure they are always up-to-date.

Dynamic Feature Toggle Example

Defining Service

Consider you are about to implement an extremely simple Feature Toggle service for your application. It will be configured using a simple YAML file stored on the GitHub repository. Whenever the feature toggle state is changed via commit to this repository, your application should enable/disable the given feature at the runtime. Following is a data model:

Java







It's very simple — we have a feature name and its current state. Having this model, we can implement our service:

Java







Our service takes a list of feature toggles as an input and builds a state map. Then, we can check whether the feature is enabled using isEnabled method.

Now, it's time for Ressor to create a service instance and start fueling it with data from the GitHub repository:

Java







Let's describe the most important parts line by line:

#4: Declare that we expect data to be in YAML array format. Ressor will parse it using Jackson into List<FeatureToggle>.

#5: Declare that the source will be a Git repository from the remote URL.

#8: Declare the path to file inside the Git repository.

#9: Creates a proxy class instance, cloning Git repository and translating YAML content into FeatureToggleService constructor.

You can always re-use the source for multiple services.

You can instantiate your service asynchronously, but in that case, you need to provide an initial instance, which will serve until the first reload happens:

Java







Making Service Reloadable

We would like Ressor to keep featureToggle  service with only up-to-date information. Someone may disable some features by committing a change to a toggles.yaml file in the GitHub repository.

This can be achieved by simple polling using Ressor:

Java







It will be performing git fetch command every 5 seconds for the source repository on the background. If any file change is detected (for the current branch), a new instance of FeatureToggleService will be created and replaced inside the proxy.

This way, featureToggle instance can be, for example, registered once as a Spring bean during application startup. Ressor guarantees that it will eventually contain the most recent data.

Service Usage

Once Ressor creates a service instance, it can be used anywhere for the whole application lifetime:

Java

You can find the full example code here. You can try it by running yourself. There are also lots of other examples.

Importing

Releases are available via Maven Central. Sources implementations are bundled as a separate modules.

Java 11+

Java

Java 8

Java


Conclusion

Ressor idea is quite straightforward: take complete service implementation and fuel it with the translated data from the given source, implicitly reloading it when needed. Apart from Git, Ressor has various other data sources: file system, HTTP, Amazon S3, etc. There are more cases and features that were not covered in this article.

The repository is available on Github. You can find out more on the official Ressor Documentation. Also, there are several examples to try.

Further Reading

Dynamic, Modular Microservices With Java EE

Dynamic Configuration Management in Microservices Architecture With Spring Cloud

Topics:
java ,core java ,jvm ,microservices

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}