Oracle releases Helidon, an open source lightweight Java micro-service framework

Keywords: Programming Java github Docker Web Server

Recently, Oracle launched a new open source framework, Helidon, which is a collection of Java libraries for creating applications based on micro services. Like Payara Micro, Thorntail (previously WildFly Swarm), OpenLiberty, TomEE and other projects, the project has joined the MicroProfile family.

Originally named J4C (Java for Cloud), Helidon is designed for simplicity and speed. It includes two versions: Helidon SE and Helidon MP. Helidon SE provides three core API s for creating micro services: Web servers, configuration and security, which are used to build applications based on micro services without application servers. Helidon MP supports the MicroProfile 1.1 specification for building applications based on micro services.

Architecture of Helidon

The following schematic diagram shows the relationship between Helidon SE and Helidon MP.

The following figure illustrates the categories of microservice frameworks that Helidon SE and Helidon MP belong to.

Web server

Inspired by NodeJS and other Java frameworks, Helidon's Web server is an asynchronous, reactive API that runs on Netty. Web Server interfaces include support for configuration, routing, error handling, and building metrics and healthy endpoints.

Quick Start Example

Helidon provides Quick Start Example To demonstrate the difference between Helidon SE and Helidon MP.

Let's borrow the official example first, and then we'll write an example by hand later.

The entire official Helidon project can be found on GitHub.

https://github.com/oracle/helidon

Building Docker Mirror

Helidon SE example

docker build -t quickstart-se target

Helidon MP example

docker build -t quickstart-mp target

Running Docker Image

Helidon SE example

docker run --rm -p 8080:8080 quickstart-se:latest

Helidon MP example

docker run --rm -p 8080:8080 quickstart-mp:latest

test

Both examples support the same REST interface

This example is a very simple Hello World greeting service. Responses are encoded using JSON. For example:

curl -X GET http://localhost:8080/greet
{"message":"Hello World!"}

curl -X GET http://localhost:8080/greet/Joe
{"message":"Hello Joe!"}

curl -X PUT http://localhost:8080/greet/greeting/Hola
{"greeting":"Hola"}

curl -X GET http://localhost:8080/greet/Jose
{"message":"Hola Jose!"}

Write an example by hand

Environmental Science

Helidon requires Java 8 (or later) and Maven. If you want to build and deploy Docker containers, you need Docker. If you want to deploy to Kubernetes, you need kubectl and Kubernetes clusters

The following list shows the minimum version

| Java SE 8 or Open JDK 8| | Maven 3.5 | | Docker 18.02 | Run Kubernetes on the desktop using the Edge channel| | Kubectl 1.7.4 |

Maven coordinates

Add the following code snippets to the pom.xml file

<dependency>
    <groupId>io.helidon.webserver</groupId>
    <artifactId>helidon-webserver</artifactId>
    <version>0.10.1</version>
</dependency>

<dependency>
    <groupId>io.helidon.webserver</groupId>
    <artifactId>helidon-webserver-netty</artifactId>
    <version>0.10.1</version>
</dependency>

<!--  WebServer Jersey rely on-->
<dependency>
    <groupId>io.helidon.webserver</groupId>
    <artifactId>helidon-webserver-jersey</artifactId>
    <version>0.10.1</version>
</dependency>

test method

package com.souyunku.helidon.webserver.examples.jersey;

import io.helidon.webserver.ServerRequest;
import io.helidon.webserver.ServerResponse;
import io.helidon.webserver.jersey.JerseySupport;
import io.opentracing.SpanContext;

import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.stream.Collectors;

@Path("/")
public class HelloWorld {

    @Inject
    private ServerRequest request;

    @Inject
    private ServerResponse response;


    @Inject
    @Named(JerseySupport.REQUEST_SPAN_CONTEXT)
    private SpanContext spanContext;


    @GET
    @Path("hello")
    public Response hello() {
        return Response.ok("Hello World !").build();
    }


    @POST
    @Path("hello")
    public Response hello(String content) {
        return Response.accepted("Hello: " + content + "!").build();
    }

    @POST
    @Path("content")
    public Response content(String content) {
        return Response.accepted(content).build();
    }

    @GET
    @Path("injection")
    public Response webServerInjection() {
        return Response.ok("request=" + request.getClass().getName()
                + "\nresponse=" + response.getClass().getName()
                + "\nspanContext=" + spanContext.getClass().getName()).build();
    }

    @GET
    @Path("headers")
    public Response headers(@Context HttpHeaders headers, @QueryParam("header") String header) {
        return Response.ok("headers=" + headers.getRequestHeader(header).stream().collect(Collectors.joining(",")))
                .build();
    }

    @GET
    @Path("query")
    public Response query(@QueryParam("a") String a, @QueryParam("b") String b) {
        return Response.accepted("a='" + a + "';b='" + b + "'").build();
    }

    @GET
    @Path("path/{num}")
    public Response path(@PathParam("num") String num) {
        return Response.accepted("num=" + num).build();
    }

    @GET
    @Path("requestUri")
    public String getRequestUri(@Context UriInfo uriInfo) {
        return uriInfo.getRequestUri().getPath();
    }
}

Startup service

package com.souyunku.helidon.webserver.examples.jersey;

import io.helidon.webserver.Routing;
import io.helidon.webserver.ServerConfiguration;
import io.helidon.webserver.WebServer;
import io.helidon.webserver.jersey.JerseySupport;
import org.glassfish.jersey.server.ResourceConfig;

import java.io.IOException;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.util.logging.LogManager;

/**
 * WebServer Jersey
 */
public final class WebServerJerseyMain {

    private WebServerJerseyMain() {
    }

    /**
     * Run the Jersey Web Server example.
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, InterruptedException, ExecutionException, TimeoutException {
        // Configure logging to avoid standard JVM default settings
        LogManager.getLogManager().readConfiguration(WebServerJerseyMain.class.getResourceAsStream("/logging.properties"));

        // The easiest way to start is at port 8080
        startServer(ServerConfiguration.builder()
                .port(8080)
                .build());

    }

    static CompletionStage<WebServer> startServer(ServerConfiguration serverConfiguration) {

        WebServer webServer = WebServer.create(
                serverConfiguration,
                Routing.builder()
                        //Register the Jersey application in the / Jersey context root directory
                        .register("/jersey",
                                JerseySupport.create(new ResourceConfig(HelloWorld.class)))
                        .build());

        return webServer.start()
                .whenComplete((server, t) -> {
                    System.out.println("Jersey WebServer started.");
                    System.out.println("Try the hello world resource at: http://localhost:" + server.port() + "/jersey/hello");
                });
        // http://localhost:8080/jersey/hello
    }
}

Response:

Jersey WebServer started.
Try the hello world resource at: http://localhost:8080/jersey/hello

test

Browser access

http://localhost:8080/jersey/hello

Response:

Hello World !

Access with parameters

http://localhost:8080/jersey/query?a=www.souyunku.com&b=www.ymq.io

Response:

a='www.souyunku.com';b='www.ymq.io'

More will not be demonstrated.

Call chain monitoring Zipkin

Web Server includes Zipkin's support for OpenTracing. When enabled, Web Server sends its trace events to Zipkin.

Maven coordinates

Web Server Zipkin Support Dependency

<dependency>
    <groupId>io.helidon.webserver</groupId>
    <artifactId>helidon-webserver-zipkin</artifactId>
</dependency>

Configuration tracking support

To enable Zipkin integration, configure ServerConfiguration.Builder on Tracer.

zipkin is an open source distributed tracking system, which is open source by Twitter. It is dedicated to collecting service timing data to solve the delay problem in the micro-service architecture, including data collection, storage, search and display. Its theoretical model comes from Google Dapper's paper.

Configure OpenTracing Tracer

ServerConfiguration.builder()
                   .tracer(new ZipkinTracerBuilder.forService("my-application") 
                                 .zipkin("http://10.0.0.18:9411")  
                                 .build())
                   .build()

Official documents:

https://helidon.io/docs/latest

Helidon's GitHub project address:

https://github.com/oracle/helidon

This article tests the code

GitHub: https://github.com/souyunku/DemoProjects/tree/master/helidon-examples

Previous brilliant articles

Contact

  • Author: Peng Lei
  • Source: http://www.ymq.io/2018/10/15/Helidon
  • Copyright belongs to the author. Please indicate the source for reprinting.
  • Wechat: Focus on public numbers, search for cloud databases, focus on research and knowledge sharing of development technologies

Posted by titaniumtommy on Sat, 02 Feb 2019 12:03:16 -0800