Professional Documents
Culture Documents
Dzone Refcard309 Eclipse PDF
Dzone Refcard309 Eclipse PDF
Developing
Microservices With CONTENTS
öö MicroProfile Platform
Eclipse MicroProfile
ö ö Conclusion
In the short time MicroProfile has existed, we've already seen great
adoption within the community, which continues to grow. This year's
Jakarta EE Developer survey showed a huge increase in adoption since
last year:
1
Discover how YOU can build
Cloud Native Microservices
using Eclipse MicroProfile
DOWNLOAD
http://bit.ly/TechWPDzone19
DEVELOPING MICROSERVICES WITH ECLIPSE MICROPROFILE
MicroProfile Platform be created when needed. You can also choose to inject a configura-
What exactly is the MicroProfile release? It combines specifications tion into an Optional type, which handles the problem of having no
which the community considers necessary for developing microser- configuration value in a more elegant manner in cases where there is
vices with Enterprise Java. The diagram below lists the specifications no default value defined.
that are part of the platform, along with the versions for the most
HEALTH
recent 3.0 platform release in June 2019:
With the rise of Kubernetes and containers, it has become important
for microservices to define what it means for them to be functioning
and able to accept requests. In the Kubernetes world, this function-
ality is referred to as liveness and readiness, where liveness indicates
whether the runtime has failed and needs to be restarted, and read-
iness tells the container whether requests can start flowing into the
microservice for processing.
CONFIG
Defining checks doesn't do much for us if there isn't a way to see the
Configuring a microservice, or application, is a foundational ability
results. The MicroProfile Health specification defines three endpoints
that we, as developers, need for our code. Whether it's the simple
that provide the results of our checks, each with an overall "status" in-
ability to define specific ports and database configurations for differ-
dicating the combined "up" or "down" status from each check. There
ent environments, or we're actually configuring how a microservice
is an endpoint for each check type, /health/liveness and /health/
behaves, we need a means by which we can retrieve configuration
readiness , and there is /healt h, which combines the liveness and
values for use within a microservice.
readiness checks.
The MicroProfile Config specification offers that ability, but also
Whether we want a liveness or readiness check, both must utilize the
enables us to define different types of ConfigSource . A Config-
HealthCheck interface to create the check. We use either @Liveness or @
Source specifically handles retrieving configuration values from a
Readiness to indicate the type of check we need. A liveness check that
particular location, or type of storage. By default, an implementation
always returns "up," not a real production check, can be written as:
of MicroProfile Config must include a ConfigSource for retrieving
configuration from system properties and environment variables. @ApplicationScoped
@Produces
An implementation of MicroProfile Config also provides built-in con- @ApplicationScoped
verters for all primitive and array types, but a custom converter can @Liveness
HealthCheck livenessCheck() { • @Gauge - Samples the value of the object, such as the instance
return HealthCheckResponse.named("liveness").up(). returned from a method.
build();
• @Metered - Tracks the frequency of invocations of what is
}
annotated.
A health check can also include a set of key/value pair data that • @Timed - Timer that tracks many statistics about invocations,
can be returned in the JSON response to provide additional con- such as minimum and maximum execution, average, standard
textual information about why the check failed or any pertinent deviation, etc.
information for operations. We can see an example of that in the The annotations can be added to a class, except for @Gauge , applied
readiness check below: to all methods or to specific methods of a class. It's also possible to
{
Above is a very simple method we've annotated with @Timed and @
"status": "DOWN",
Counted . There are attributes available to customize various parts of
"checks": [
{ the metric, but, in this case, we've gone with the defaults. The only at-
"name": "liveness", tribute we change is the name of one of the metrics, otherwise we get
"status": "UP" a clash because the generated metric name uses the method name.
},
{ With MicroProfile Metrics present within a microservice, the /metrics
"name": "readiness",
endpoint returns all the current metrics that are capturing data from
"status": "DOWN",
the microservice. The returned data will either be in JSON or Open-
"data": {
"key": "value" Metrics text format, depending on any HTTP Accept header that may
} have been passed. Unless JSON is specifically requested, /metrics
} will typically return OpenMetrics text formatted metrics.
]
} We've already talked about microservice metrics that we can add
to our code, but there are also many base metrics that a runtime
There is no limit as to what you could do within a health check, but
is required to provide as well. Base metrics include memory usage,
good practice is to not execute calls or tasks that can take a long time
threads, available CPUs, etc. A full list can be found here: github.com/
to complete unless it's absolutely necessary. Having checks that take
eclipse/microprofile-metrics/blob/2.0.1/spec/src/main/asciidoc/re-
a while to complete, especially for liveness checks, can result in con-
quired-metrics.adoc
tainer environments reaching a timeout and restarting your microser-
vice because it thinks the container has crashed. In addition, it's possible for a runtime to define a set of vendor met-
rics that can provide telemetry on the runtime that can be used within
METRICS
MicroProfile Metrics offers the following annotations for capturing operations. Depending on the runtime, it may even make sense to tie
rent, or parallel, invocations. long? Each of the different types of metrics available, base, vendor, or
application, can be accessed by a direct endpoint to retrieve only that content = @Content(mediaType = "application/json",
subset of metrics. The endpoints are /metrics/base , /metrics/ven- schema = @Schema(implementation = User.
class))),
dor , and /metrics/application .
@APIResponse(responseCode = "400", description = "User
not found")
OPENTRACING
public Response getUserByName(
MicroProfile OpenTracing doesn't have much of an API, only @Traced ,
@Parameter(description = "The name that needs to
but it does a lot behind the scenes for our microservice without us be fetched. Use user1
needing to worry about it. For instance, when used with the Micro- for testing. ", required = true) @PathParam("username")
Profile REST Client, it will notice if you have an incoming span on a String
username)
request and create a child span to propagate in outbound REST Client
{...}
calls, setting the necessary HTTP headers for you. This enables a trac-
ing implementation to properly show child calls, without developers The above code generates an OpenAPI document segment that
needing to add any code for adding headers or propagating spans. looks like:
used to define a service we want to expose instead of one we want to Response postWithRequestId(MyEntity entity);
Another great feature is the ability to propagate headers from incom- • @Retry - Ability to retry an operation a number of times, with
ing to outgoing requests, which is especially useful when passing delays, to account for brief network errors.
JWTs or other security headers. All we need to do is add @Register-
• @CircuitBreaker - Prevents repeated failures by utilizing a
ClientHeaders onto the interface and then set values on the org.
fail-fast approach to allow a downstream service to recover.
eclipse.microprofile.rest.client.propagateHeaders config
• @Builkhead - Defines the maximum number of concurrent
property to indicate which headers we want propagated.
requests that can be processed by a method, and the depth of
If we need custom headers to be set on specific methods only, we can the waiting queue.
use @ClientHeaderParam to set specific values or call methods to
• @Asynchronous - Forces execution of a client request to occur
generate a value for the header. Here are a couple of examples:
on a separate thread.
@Path("/somePath")
Many of the above annotations can be combined to provide enhanced
public interface MyClient {
@POST
behavior, such as @Retry and @Fallback to retry an operation several
times before triggering a fallback response if all retries failed. The
@ClientHeaderParam(name = "X-Http-Method-Override", below example shows what it would look like, where nameService is a
value = "PUT") REST client we're using to call an external service:
Code continued on next column
@Retry(maxRetries = 2, maxDuration = 1000, delay = the JAX-RS security context, we can directly inject the token itself, or
200) specific claims within the token, into our microservice:
@Fallback(fallbackMethod = "greetingFailure")
public Greeting greeting() { @Inject
return new Greeting("Hello " + nameService.name(). @Claim("roles")
getName()); private JsonArray jsonRoles;
}
private Greeting greetingFailure() { @Inject
return new Greeting("Hello from Fallback"); @Claim(standard = Claims.rawToken)
} private String rawToken;
For @Retry , we've indicated we only want to make two attempts, with @Inject
private JsonWebToken jwt;
a delay of 200 milliseconds between each retry, but we want to fail
the execution if the total time of all retries reaches 1000 milliseconds.
REACTIVE MESSAGING
With @Fallback , we've chosen to use a method instead of a class,
Developing reactive microservices, and by extension reactive systems,
where the most important piece to note is that the return type of our
has gained a lot of traction over the last few years, which is why
fallback needs to match that of the method, in this case, Greeting .
MicroProfile Reactive Messaging will be a key piece for MicroProfile in
There are many different ways that the annotations from MicroProfile supporting the reactive world. Although it only recently had its first
Fault Tolerance can be combined to provide the specific handling you release, the specification was under discussion and development for
might require in your microservice. Unfortunately, it's not possible to a year before the release.
JWT AUTHENTICATION
vices together. The focus of the specification defines a development
Sure, we can create our microservices without any security, but that's model for producing, consuming, and processing messages. We do
not a realistic design choice for most environments. That's where that by utilizing a combination of @Incoming and @Outgoing on a
MicroProfile JWT Authentication comes into play. JWT Authentication method. If we only produce events, then use @Outgoing ; if we only
provides a way for security tokens to be passed into and between mi- consume events, then use @Incoming ; if we process events from one
croservices for securing resources with authentication and authoriza- channel to another, we use both. Below is an example of receiving
tion. Early on, it was decided it made sense to converge on using JWTs events from "orders" and adding a new event into a "queue":
due to these tokens being an industry standard, but the specification
@Incoming("orders")
also allows existing Enterprise Java security annotations to be used in @Outgoing("queue")
conjunction with JWT. public CompletionStage<String> prepare(String message)
{
For instance, all the JSR 250 security annotations, such as @Role- Order order = jsonb.fromJson(message, Order.class);
sAllowed and @PermitAll , can be used to secure JAX-RS endpoints return makeIt(order)
The connectors are easily switched by changing a Maven dependency • To learn more, visit the Eclipse MicroProfile website which
and a configuration property to indicate which connector should be includes a blog, FAQs, and other useful information.
used for a specific channel. This approach offers developers greater
• The Eclipse MicroProfile project page offers more technically
flexibility in switching between different connectors for different
oriented information on the project, its governance, specifica-
environments.
tions, and links to code repositories.
There are several ways to learn more about Eclipse MicroProfile and get
involved in driving the evolution of Enterprise Java-based microservices:
Devada, Inc.
600 Park Offices Drive
Suite 150
Research Triangle Park, NC
888.678.0399 919.678.0300
DZone communities deliver over 6 million pages each month
to more than 3.3 million software developers, architects, Copyright © 2019 Devada, Inc. All rights reserved. No part of this
and decision makers. DZone offers something for everyone, publication may be reproduced, stored in a retrieval system, or
including news, tutorials, cheat sheets, research guides, fea- transmitted, in any form or by means electronic, mechanical,
ture articles, source code, and more. "DZone is a developer’s photocopying, or otherwise, without prior written permission of
dream," says PC Magazine. the publisher.