Skip to content

bmarwell/openliberty-content-negotiation-example

Repository files navigation

OpenLiberty Content Negotiation Example

Differences from Brian‘s API

Just for the fun of it, and because JSON is derived from JavaScript, I did set the config option PropertyNamingStrategy.LOWER_CASE_WITH_UNDERSCORES.

The output will have under_scores in field names instead of lowerCamelCase (as derived from Java getter methods).

As already mentioned, most classes were converted to interfaces and CDI beans.

Using the API

The calls are similar to Brian‘s API.

Help API

Curl user agent

$ curl --url "https://api.diceroll.bmarwell.de/"
Welcome to the Dice Parser!!

Roll dice by making a request:
    curl https://api.diceroll.bmarwell.de/roll?dice=2d6 -H "Accept: text/plain"

Or get the result in JSON (the default):
    curl https://api.diceroll.bmarwell.de/roll?dice=2d6 -H "Accept: application/json"

HTTPie user agent

$ curl  -H "User-Agent: HTTPie/1.0.0" --url "https://api.diceroll.bmarwell.de/"
Welcome to the Dice Parser!!

Roll dice by making a request:
    http https://api.diceroll.bmarwell.de/roll dice==2d6 "Accept: text/plain"

Or get the result in JSON:
    http https://api.diceroll.bmarwell.de/roll dice==2d6 "Accept: application/json"

Generic User Agent (or none/unknown)

$ curl  -H "User-Agent: " --url "https://api.diceroll.bmarwell.de/"
Welcome to the Dice Parser!!

Roll dice by making a request:
    GET https://api.diceroll.bmarwell.de/roll?dice=2d6
    Accept: text/plain

Or get the result in JSON:
    GET https://api.diceroll.bmarwell.de/roll?dice=2d6
    Accept: application/json

German Language

$ curl -H "accept-language: de" --url "https://api.diceroll.bmarwell.de/"
Willkommen beim Würfelparser!!

Würfeln Sie, indem Sie eine Anfrage stellen:
curl https://api.diceroll.bmarwell.de/roll?dice=2d6 -H "Accept: text/plain"

Oder rufen Sie das Ergebnis in JSON ab:
curl https://api.diceroll.bmarwell.de/roll?dice=2d6 -H "Accept: application/json"

Dice roll API

See Brian’s Docs for all available options.

Accept text/plain (or none specified):

$ curl --url "https://api.diceroll.bmarwell.de/roll?dice=2d6"
2d6 = 10
--d6 = 6
--d6 = 4

Accept application/json

$ curl -H "accept: application/json" --url "https://api.diceroll.bmarwell.de/roll?dice=2d6"

{
    "expression": {
        "number_of_dice": 2,
        "number_of_faces": 6
    },
    "results": [
        {
            "expression": {
                "number_of_dice": 1,
                "number_of_faces": 6
            },
            "results": [
            ],
            "value": 2
        },
        {
            "expression": {
                "number_of_dice": 1,
                "number_of_faces": 6
            },
            "results": [
            ],
            "value": 2
        }
    ],
    "value": 4
}

How to build

Environment

Make sure your java version is recent enough.

sdk env

Quick build with all checks

./mvnw verify

Build docker image

# needed for podman beforehand:
export DOCKER_HOST="unix://$XDG_RUNTIME_DIR/podman/podman.sock"
systemctl enable --user --now podman.socket
systemctl enable --user --now podman.service
# actual build
./mvnw package -Pdockerize

Image will be built as openlibertycontentrenegotiation/olcr-app-ol-docker:latest

Enable Open Liberty InstantOn

This feature is powered by Eclipse OpenJ9 and Linux CRIU.

Prerequisites:

  • podman

  • podman-docker

  • set-up UNIX-host as can be seen above

  • jq — as we enabled JSON logging

# remove old dangling image
docker rm olcr-checkpoint-container

# build the InstantOn-Image
podman run --name olcr-checkpoint-container --privileged --env WLP_CHECKPOINT=applications openlibertycontentrenegotiation/olcr-app-ol-docker:latest | grep -E '^{' | jq -s
# now you should have a checkpointed container (check the logs)

# to make it available, use:
podman commit olcr-checkpoint-container oclr-instanton

# this is now something you can start:
podman run \
  --rm \
  --cap-add=CHECKPOINT_RESTORE \
  --cap-add=NET_ADMIN \
  --cap-add=SYS_PTRACE \
  --security-opt seccomp=unconfined \
  --security-opt systempaths=unconfined \
  --security-opt apparmor=unconfined \
  -p 9080:9080 \
  oclr-instanton

What does this example show?

OpenLiberty features

  • Resful WebServices 3.0, CDI 3.0, JSON-B(inding) 2.0 on OpenLiberty

  • Some OpenLiberty features, like

    • TLS1.3 over http/2

    • disabling CDI implicit bean archives

    • Preferred server compression

    • Modified cookie length

    • skipping META-INF processing

    • A bit of hardening (remove server header, disabled welcome page)

    • JSON logging for the docker container.

    • the easiness of using features

As well as

Startup time

Some classes are pre-compiled using OpenJ9‘s AOT compiler. The files are then saved to a shared class cache file. This way, Java does not need to compile the files again on every startup.

$ docker run -p 9080:9080 de.bmarwell.examples.openlibertycontentrenegotiation/olcr-app-ol-docker:1.0.0-SNAPSHOT

[…]
[2021-11-04T20:00:31.258+0000] 00000034 id=         com.ibm.ws.app.manager.AppMessageHelper                      A CWWKZ0001I: Application olcr-web-restv1-1.0.0-SNAPSHOT started in 0.526 seconds.