Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helidon SE #43

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
.idea/
helidon/target/
helidon-se/target/
helidon-se/.classpath
helidon-se/.factorypath
helidon-se/.project
*.prefs
1 change: 1 addition & 0 deletions helidon-se/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/*
6 changes: 6 additions & 0 deletions helidon-se/.helidon
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#Helidon Project Configuration
#Thu Oct 12 14:27:24 MDT 2023
schema.version=1.1.0
helidon.version=3.2.2
project.flavor=mp
project.archetype=quickstart
39 changes: 39 additions & 0 deletions helidon-se/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

# 1st stage, build the app
FROM container-registry.oracle.com/java/openjdk:21 as build

# Install maven
WORKDIR /usr/share
RUN set -x && \
curl -O https://archive.apache.org/dist/maven/maven-3/3.8.4/binaries/apache-maven-3.8.4-bin.tar.gz && \
tar -xvf apache-maven-*-bin.tar.gz && \
rm apache-maven-*-bin.tar.gz && \
mv apache-maven-* maven && \
ln -s /usr/share/maven/bin/mvn /bin/

WORKDIR /helidon

# Create a first layer to cache the "Maven World" in the local repository.
# Incremental docker builds will always resume after that, unless you update
# the pom
ADD pom.xml pom.xml
RUN mvn package -Dmaven.test.skip -Declipselink.weave.skip

# Do the Maven build!
# Incremental docker builds will resume here when you change sources
ADD src src
RUN mvn package -DskipTests

RUN echo "done!"

# 2nd stage, build the runtime image
FROM container-registry.oracle.com/java/openjdk:21
WORKDIR /helidon

# Copy the binary built in the 1st stage
COPY --from=build /helidon/target/helidon-se.jar ./
COPY --from=build /helidon/target/libs ./libs

CMD ["java", "-jar", "helidon-se.jar"]

EXPOSE 8080
25 changes: 25 additions & 0 deletions helidon-se/Dockerfile.jlink
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

# 1st stage, build the app
FROM maven:3.8.4-openjdk-17-slim as build

WORKDIR /helidon

# Create a first layer to cache the "Maven World" in the local repository.
# Incremental docker builds will always resume after that, unless you update
# the pom
ADD pom.xml .
RUN mvn package -Dmaven.test.skip -Declipselink.weave.skip

# Do the Maven build to create the custom Java Runtime Image
# Incremental docker builds will resume here when you change sources
ADD src src
RUN mvn package -Pjlink-image -DskipTests
RUN echo "done!"

# 2nd stage, build the final image with the JRI built in the 1st stage

FROM debian:stretch-slim
WORKDIR /helidon
COPY --from=build /helidon/target/helidon-se-jri ./
ENTRYPOINT ["/bin/bash", "/helidon/bin/start"]
EXPOSE 8080
39 changes: 39 additions & 0 deletions helidon-se/Dockerfile.native
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

# 1st stage, build the app
FROM ghcr.io/graalvm/graalvm-community:21.0.0-ol9 as build

WORKDIR /usr/share

# Install maven
RUN set -x && \
curl -O https://archive.apache.org/dist/maven/maven-3/3.8.4/binaries/apache-maven-3.8.4-bin.tar.gz && \
tar -xvf apache-maven-*-bin.tar.gz && \
rm apache-maven-*-bin.tar.gz && \
mv apache-maven-* maven && \
ln -s /usr/share/maven/bin/mvn /bin/

WORKDIR /helidon

# Create a first layer to cache the "Maven World" in the local repository.
# Incremental docker builds will always resume after that, unless you update
# the pom
ADD pom.xml .
RUN mvn package -Pnative-image -Dnative.image.skip -Dmaven.test.skip -Declipselink.weave.skip

# Do the Maven build!
# Incremental docker builds will resume here when you change sources
ADD src src
RUN mvn package -Pnative-image -Dnative.image.buildStatic -DskipTests

RUN echo "done!"

# 2nd stage, build the runtime image
FROM scratch
WORKDIR /helidon

# Copy the binary built in the 1st stage
COPY --from=build /helidon/target/helidon-se .

ENTRYPOINT ["./helidon-se"]

EXPOSE 8080
133 changes: 133 additions & 0 deletions helidon-se/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# helidon

Minimal Helidon MP project suitable to start from scratch.

## Build and run


With JDK17+
```bash
mvn package
java -jar target/helidon.jar
```

## Exercise the application
```
curl -X GET http://localhost:8080/simple-greet
{"message":"Hello World!"}
```

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

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

curl -X PUT -H "Content-Type: application/json" -d '{"greeting" : "Hola"}' http://localhost:8080/greet/greeting

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



## Try metrics

```
# Prometheus Format
curl -s -X GET http://localhost:8080/metrics
# TYPE base:gc_g1_young_generation_count gauge
. . .

# JSON Format
curl -H 'Accept: application/json' -X GET http://localhost:8080/metrics
{"base":...
. . .
```



## Try health

```
curl -s -X GET http://localhost:8080/health
{"outcome":"UP",...

```



## Building a Native Image

Make sure you have GraalVM locally installed:

```
$GRAALVM_HOME/bin/native-image --version
```

Build the native image using the native image profile:

```
mvn package -Pnative-image
```

This uses the helidon-maven-plugin to perform the native compilation using your installed copy of GraalVM. It might take a while to complete.
Once it completes start the application using the native executable (no JVM!):

```
./target/helidon
```

Yep, it starts fast. You can exercise the application’s endpoints as before.


## Building the Docker Image

```
docker build -t helidon .
```

## Running the Docker Image

```
docker run --rm -p 8080:8080 helidon:latest
```

Exercise the application as described above.


## Building a Custom Runtime Image

Build the custom runtime image using the jlink image profile:

```
mvn package -Pjlink-image
```

This uses the helidon-maven-plugin to perform the custom image generation.
After the build completes it will report some statistics about the build including the reduction in image size.

The target/helidon-jri directory is a self contained custom image of your application. It contains your application,
its runtime dependencies and the JDK modules it depends on. You can start your application using the provide start script:

```
./target/helidon-jri/bin/start
```

Class Data Sharing (CDS) Archive
Also included in the custom image is a Class Data Sharing (CDS) archive that improves your application’s startup
performance and in-memory footprint. You can learn more about Class Data Sharing in the JDK documentation.

The CDS archive increases your image size to get these performance optimizations. It can be of significant size (tens of MB).
The size of the CDS archive is reported at the end of the build output.

If you’d rather have a smaller image size (with a slightly increased startup time) you can skip the creation of the CDS
archive by executing your build like this:

```
mvn package -Pjlink-image -Djlink.image.addClassDataSharingArchive=false
```

For more information on available configuration options see the helidon-maven-plugin documentation.

42 changes: 42 additions & 0 deletions helidon-se/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.helidon.applications</groupId>
<artifactId>helidon-se</artifactId>
<version>4.0.0</version>
<relativePath/>
</parent>
<groupId>com.okta.rest</groupId>
<artifactId>helidon-se</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<mainClass>com.okta.rest.HelloApplication</mainClass>
</properties>

<dependencies>
<dependency>
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver-security</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver-context</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.security.providers</groupId>
<artifactId>helidon-security-providers-jwt</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.http.media</groupId>
<artifactId>helidon-http-media-jsonp</artifactId>
</dependency>
</dependencies>
</project>
53 changes: 53 additions & 0 deletions helidon-se/src/main/java/com/okta/rest/HelloApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.okta.rest;

import java.net.URI;

import com.okta.rest.controller.HelloResource;

import io.helidon.common.configurable.Resource;
import io.helidon.config.Config;
import io.helidon.security.Security;
import io.helidon.security.providers.jwt.JwtProvider;
import io.helidon.webserver.WebServer;
import io.helidon.webserver.context.ContextFeature;
import io.helidon.webserver.http.HttpRouting;
import io.helidon.webserver.security.SecurityFeature;

public class HelloApplication {

public static void main(String[] args) {

var config = Config.global();
var oauth =
JwtProvider.builder()
.issuer(config.get("se.jwt.verify.issuer").asString().get())
.verifyJwk(
Resource.create(
config
.get("se.jwt.verify.publickey.location")
.asString()
.map(URI::create)
.orElseThrow()))
.build();

Security security = Security.builder().addProvider(oauth).build();
var securityFeature =
SecurityFeature.create(
sfb ->
sfb.security(security)
.addPath(p -> p.path("/hello").handler(h -> h.authenticate(true))));

WebServer.builder()
.config(config.get("server"))
.routing(HelloApplication::routing)
.addFeature(ContextFeature.create())
.addFeature(securityFeature)
.build()
.start();
}

/** Updates HTTP Routing. */
static void routing(HttpRouting.Builder routing) {
routing.addFeature(new HelloResource());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.okta.rest.controller;

import static io.helidon.http.Status.OK_200;

import io.helidon.common.media.type.MediaTypes;
import io.helidon.security.SecurityContext;
import io.helidon.webserver.http.HttpFeature;
import io.helidon.webserver.http.HttpRouting;
import io.helidon.webserver.http.ServerRequest;
import io.helidon.webserver.http.ServerResponse;

public class HelloResource implements HttpFeature {

@Override
public void setup(HttpRouting.Builder routing) {
routing.get("/hello", this::hello);
}

public void hello(ServerRequest req, ServerResponse res) {

SecurityContext context = req.context().get(SecurityContext.class).orElseThrow();
res.status(OK_200);
res.headers().contentType(MediaTypes.TEXT_PLAIN);
res.send("Hello, " + context.userName() + "!");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Args=--initialize-at-build-time=com.okta.rest \
--enable-url-protocols=https \
--report-unsupported-elements-at-runtime
6 changes: 6 additions & 0 deletions helidon-se/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Microprofile server properties
server.port=8080
server.host=0.0.0.0

se.jwt.verify.issuer=https://dev-ota46tsay8d5jodg.us.auth0.com/
se.jwt.verify.publickey.location=${se.jwt.verify.issuer}.well-known/jwks.json
Loading