DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • How to Setup the Spring Cloud Config Server With Git
  • A Systematic Approach for Java Software Upgrades
  • Dropwizard vs. Micronaut: Unpacking the Best Framework for Microservices
  • Spring Microservice Tip: Abstracting the Database Hostname With Environment Variable

Trending

  • Measuring the Impact of AI on Software Engineering Productivity
  • Java's Quiet Revolution: Thriving in the Serverless Kubernetes Era
  • Microsoft Azure Synapse Analytics: Scaling Hurdles and Limitations
  • Docker Model Runner: Streamlining AI Deployment for Developers
  1. DZone
  2. Coding
  3. Java
  4. Java EE MicroProfile With KumuluzEE

Java EE MicroProfile With KumuluzEE

In the world of Java EE microservices, all eyes are on MicroProfile. But KumuluzEE is already in the game. Let's link and configure some microservices.

By 
Piotr Mińkowski user avatar
Piotr Mińkowski
·
Aug. 01, 17 · Tutorial
Likes (6)
Comment
Save
Tweet
Share
10.6K Views

Join the DZone community and get the full member experience.

Join For Free

Enterprise Java seems to be a step back from the others when it comes to microservices architecture. Some weeks ago, I took a part in Code Europe – the programming conference in Warsaw. One of the speakers was Ivar Grimstad, who was talking about MicroProfile – an open initiative for optimizing Enterprise Java for a microservices architecture. This idea is very interesting, but at the moment, it is rather at the beginning of the road.

However, while I was reading about the microprofile initiative, I came across information about JavaEE framework developed by Slovenian company – KumuluzEE. The solution seemed to be interesting enough that I decided to take a closer look at it. Well, we can read on the website that KumuluzEE is the Java Duke’s Choice Award Winner, so there is still a hope for JavaEE and microservices

What’s KumuluzEE

Can KumuluzEE be a competitor to the Spring Cloud framework? It is certainly not as popular and advanced when it comes to solutions for microservices like Spring Cloud, but it has basic modules for service registration, discovery, distributed configuration propagation, circuit breaking, metrics, and support for Docker and Kubernetes. It uses CDI on JBoss Weld containers for dependency injection and Jersey as a REST API provider. Modules for configuration and discovery are based on Consul or etcd, though they are at the early stage of development (1.0.0-SNAPSHOT).

But let’s try it out.

Preparation

I’ll show you a sample application that consists of two independent microservices — account-service and customer-service. Both of them expose a REST API, and one of the customer-service methods invokes a method from account-service. Every microservice registers itself in Consul and is able to get configuration properties from Consul. The sample application source code is available on GitHub. Before we begin, let’s start a Consul instance using a Docker container.

docker run -d --name consul -p 8500:8500 -p 8600:8600 consul


We should also add some KumuluzEE dependencies to the Maven pom.xml.

<dependency>
    <groupId>com.kumuluz.ee</groupId>
    <artifactId>kumuluzee-core</artifactId>
</dependency>
<dependency>
    <groupId>com.kumuluz.ee</groupId>
    <artifactId>kumuluzee-servlet-jetty</artifactId>
</dependency>
<dependency>
    <groupId>com.kumuluz.ee</groupId>
    <artifactId>kumuluzee-jax-rs-jersey</artifactId>
</dependency>
<dependency>
    <groupId>com.kumuluz.ee</groupId>
    <artifactId>kumuluzee-cdi-weld</artifactId>
</dependency>


Service Registration

To enable service registration, we should add one additional dependency to our pom.xml. I chose Consul as a registration and discovery server, but you can also use etcd (kumuluzee-discovery-consul).

<dependency>
    <groupId>com.kumuluz.ee.discovery</groupId>
    <artifactId>kumuluzee-discovery-consul</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>


Inside the application configuration file, we should set discovery properties and a server URL. For me, it is 192.168.99.100.

kumuluzee:
  service-name: account-service
  env: dev
  version: 1.0.0
  discovery:
    consul:
      agent: http://192.168.99.100:8500
      hosts: http://192.168.99.100:8500
    ttl: 20
    ping-interval: 15


Here’s the account microservice's main class. As you probably guess, the annotation @RegisterService enables registration on the server.

@RegisterService("account-service")
@ApplicationPath("v1")
public class AccountApplication extends Application {
 
}


We start the application by running:

java -cp target/classes;target/dependency/* com.kumuluz.ee.EeApplication

Remember to override the default port by setting the environment property: PORT. I started two instances of account and one of the customer microservice.

kumuluzee-1

Service Discovery

The customer microservice exposes the API, but it also invokes the API method from account-service, so it has to discover and connect to this service. The Maven dependencies and configuration settings are the same as for account-service. The only difference is the resource class. Here’s the CustomerResource fragment, where we are invoking endpoint GET /customer/{id}.

@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("customers")
@RequestScoped
public class CustomerResource {
 
    private List<Customer> customers;
 
    @Inject
    @DiscoverService(value = "account-service", version = "1.0.x", environment = "dev")
    private WebTarget target;
 
    ...
 
    @GET
    @Path("{id}")
    @Log(value = LogParams.METRICS, methodCall = true)
    public Customer findById(@PathParam("id") Integer id) {
        Customer customer = customers.stream().filter(it -> it.getId().intValue() == id.intValue()).findFirst().get();
        WebTarget t = target.path("v1/accounts/customer/" + customer.getId());
        List<Account> accounts = t.request().buildGet().invoke(List.class);
        customer.setAccounts(accounts);
        return customer;
    }
}


There is one pretty cool thing about discovery with KumuluzEE. As you can see in the @DiscoverService, we can specify a version and environment for account-service instance. The version and environment for the microservice is read automatically from the config.yml during registration in discovery server. So, we can maintain many versions of a single microservice and freely invoke them from other microservices. Requests are automatically load balanced between all microservice match conditions from the annotation @ServiceDiscovery.

We can also monitor metrics, such as response time, by declaring @Log(value = LogParams.METRICS, methodCall = true) on the API method. Here’s a log fragment for account-service:

2017-07-28 13:57:01,114 TRACE ENTRY[ METHOD ] Entering method. {class=pl.piomin.services.kumuluz.account.resource.AccountResource, method=findByCustomer, parameters=[1]}
2017-07-28 13:57:01,118 TRACE EXIT[ METHOD ] Exiting method. {class=pl.piomin.services.kumuluz.account.resource.AccountResource, method=findByCustomer, parameters=[1], response-time=3, result=[pl.piomin.services.kumuluz.account.model.Account@1eb26fe3, pl.piomin.services.kumuluz.account.model.Account@2dda41c5]}


Distributed Configuration

To enable KumuluzEE Config, include the Consul implementation by adding the following dependency to your pom.xml.

<dependency>
    <groupId>com.kumuluz.ee.config</groupId>
    <artifactId>kumuluzee-config-consul</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>


I do not use a Consul agent running on the localhost, so I need to override some properties in config.yml. I also defined one configuration property, blacklist:

kumuluzee:
  config:
    start-retry-delay-ms: 500
    max-retry-delay-ms: 900000
    consul:
      agent: http://192.168.99.100:8500
 
rest-config:
  blacklist:


Here’s the class that loads the configuration properties and enables dynamic updates on any change in the configuration source by declaring @ConfigValue(watch = true) on a property.

@ApplicationScoped
@ConfigBundle("rest-config")
public class AccountConfiguration {
 
    @ConfigValue(watch = true)
    private String blacklist;
 
    public String getBlacklist() {
        return blacklist;
    }
 
    public void setBlacklist(String blacklist) {
        this.blacklist = blacklist;
    }
 
}


We use the configuration property blacklist in the resource class for filtering all accounts by blacklisted ids.

@GET
@Log(value = LogParams.METRICS, methodCall = true)
public List<Account> findAll() {
    final String blacklist = ConfigurationUtil.getInstance().get("rest-config.blacklist").orElse("nope");
    final String[] ids = blacklist.split(",");
    final List<Integer> blacklistIds = Arrays.asList(ids).stream().map(it -> new Integer(it)).collect(Collectors.toList());
    return accounts.stream().filter(it -> !blacklistIds.contains(it.getId())).collect(Collectors.toList());
}


The configuration property should be defined in the Consul UI Dashboard under the KEY/VALUE tab. KumuluzEE enforces a certain format of key names. In this case it has to be:

environments/dev/services/account-service/1.0.0/config/rest-config/blacklist

You can update a property value and test changes by invoking http://localhost:2222/v1/accounts.

kumuluzee-2

Final Words

Creating microservices with KumuluzEE is pretty easy. I showed you the main capabilities of this framework. KumulezEE has also modules for circuit breakers with Hystrix, streaming with Apache Kafka, and security with OAuth2/OpenID. I will keep a close eye on this library, and I hope it will continue to be developed.

microservice Java (programming language) Java EE Property (programming)

Published at DZone with permission of Piotr Mińkowski, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How to Setup the Spring Cloud Config Server With Git
  • A Systematic Approach for Java Software Upgrades
  • Dropwizard vs. Micronaut: Unpacking the Best Framework for Microservices
  • Spring Microservice Tip: Abstracting the Database Hostname With Environment Variable

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!