From ea23d46b3b7e41e7db1b57d85b7206614fb5b08b Mon Sep 17 00:00:00 2001 From: Romain Grecourt Date: Mon, 15 Apr 2019 16:35:32 -0700 Subject: [PATCH] Quickstart update for native images (#547) * Rename ossrh-release profile to staging and change the repos to staging. - OSSRH does not have a hosted release repo available, thus a profile for ossrh-release does not make sense. * Move the nexus-staging-maven-plugin declaration with extension=true in the release profile. * rename version.plugin.sitegen property to version.plugin.helidon-build-tools, bump the value from 1.0.9 to 1.0.10 * Remove the graal example, instead make the helidon-quickstart-se "graalvm ready". * Update archetype generation logic. - Use a shell script instead of archetype:create-from-project - Make all Dockerfiles multi-stage docker builds using Maven. - Move Dockerfiles and app.yaml at the top level. * Update docs * Add the Dockerfile used to create the helidon images. - Update the docker image guide. - Use uniqueVersions=false in the manifest jar config. * Fixes to support both Graal CE and EE in Helidon quickstart se. * Add native-image.properties with a reflection-config JSON placeholder --- docs-internal/dockerbuild-local-snapshots.md | 109 +++++ .../main/docs/guides/02_quickstart-se.adoc | 14 +- .../main/docs/guides/03_quickstart-mp.adoc | 14 +- docs/src/main/docs/guides/04_dockerfile.adoc | 63 +-- .../docs/guides/06_Oracle_Kubernetes.adoc | 10 +- etc/dockerfiles/Dockerfile.jdk8-graalvm | 63 +++ etc/dockerfiles/Dockerfile.jdk8-graalvm-maven | 38 ++ etc/dockerfiles/build.sh | 69 ++++ examples/pom.xml | 1 - examples/quickstarts/archetypes/README.md | 69 +--- .../archetypes/archetype.properties | 24 -- .../archetypes/create-archetype.sh | 374 ++++++++++++++++++ .../archetypes/create-archetypes.sh | 209 ++++------ .../archetypes/deploy-archetypes.sh | 44 +-- .../quickstarts/archetypes/set-version.sh | 9 +- .../templates/archetype-metadata.xml | 63 +++ .../quickstarts/archetypes/templates/pom.xml | 103 +++++ .../quickstarts/archetypes/test-archetypes.sh | 58 +-- .../helidon-quickstart-graalvm/README.md | 74 ---- .../helidon-quickstart-graalvm/pom.xml | 271 ------------- .../src/main/docker/Dockerfile | 40 -- .../quickstart/graalvm/GreetService.java | 127 ------ .../examples/quickstart/graalvm/Main.java | 112 ------ .../quickstart/graalvm/package-info.java | 24 -- .../src/main/resources/logging.properties | 37 -- .../examples/quickstart/graalvm/MainTest.java | 112 ------ .../helidon-quickstart-mp/.dockerignore | 1 + .../helidon-quickstart-mp/.gitignore | 16 + .../helidon-quickstart-mp/Dockerfile | 44 +++ .../helidon-quickstart-mp/README.md | 12 +- .../k8s => helidon-quickstart-mp}/app.yaml | 16 +- .../helidon-quickstart-mp/build.gradle | 2 +- .../quickstarts/helidon-quickstart-mp/pom.xml | 41 +- .../helidon-quickstart-mp/settings.gradle | 2 +- .../src/main/docker/Dockerfile | 23 -- .../src/main/k8s/app.yaml | 50 --- .../helidon-quickstart-se/.dockerignore | 1 + .../helidon-quickstart-se/.gitignore | 16 + .../helidon-quickstart-se/Dockerfile | 45 +++ .../helidon-quickstart-se/Dockerfile.native | 44 +++ .../helidon-quickstart-se/README.md | 62 ++- .../k8s => helidon-quickstart-se}/app.yaml | 16 +- .../helidon-quickstart-se/build.gradle | 2 +- .../quickstarts/helidon-quickstart-se/pom.xml | 74 ++-- .../helidon-quickstart-se/settings.gradle | 4 +- .../src/main/docker/Dockerfile | 23 -- .../helidon-example-reflection-config.json | 1 + .../native-image/native-image.properties} | 11 +- examples/quickstarts/pom.xml | 9 +- .../helidon/health/checks/HealthChecks.java | 20 +- .../extension/NettySubstitutions.java | 14 + pom.xml | 38 +- 52 files changed, 1354 insertions(+), 1364 deletions(-) create mode 100644 docs-internal/dockerbuild-local-snapshots.md create mode 100644 etc/dockerfiles/Dockerfile.jdk8-graalvm create mode 100644 etc/dockerfiles/Dockerfile.jdk8-graalvm-maven create mode 100755 etc/dockerfiles/build.sh delete mode 100644 examples/quickstarts/archetypes/archetype.properties create mode 100755 examples/quickstarts/archetypes/create-archetype.sh create mode 100644 examples/quickstarts/archetypes/templates/archetype-metadata.xml create mode 100644 examples/quickstarts/archetypes/templates/pom.xml delete mode 100644 examples/quickstarts/helidon-quickstart-graalvm/README.md delete mode 100644 examples/quickstarts/helidon-quickstart-graalvm/pom.xml delete mode 100644 examples/quickstarts/helidon-quickstart-graalvm/src/main/docker/Dockerfile delete mode 100644 examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/GreetService.java delete mode 100644 examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/Main.java delete mode 100644 examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/package-info.java delete mode 100644 examples/quickstarts/helidon-quickstart-graalvm/src/main/resources/logging.properties delete mode 100644 examples/quickstarts/helidon-quickstart-graalvm/src/test/java/io/helidon/examples/quickstart/graalvm/MainTest.java create mode 100644 examples/quickstarts/helidon-quickstart-mp/.dockerignore create mode 100644 examples/quickstarts/helidon-quickstart-mp/.gitignore create mode 100644 examples/quickstarts/helidon-quickstart-mp/Dockerfile rename examples/quickstarts/{helidon-quickstart-se/src/main/k8s => helidon-quickstart-mp}/app.yaml (75%) delete mode 100644 examples/quickstarts/helidon-quickstart-mp/src/main/docker/Dockerfile delete mode 100644 examples/quickstarts/helidon-quickstart-mp/src/main/k8s/app.yaml create mode 100644 examples/quickstarts/helidon-quickstart-se/.dockerignore create mode 100644 examples/quickstarts/helidon-quickstart-se/.gitignore create mode 100644 examples/quickstarts/helidon-quickstart-se/Dockerfile create mode 100644 examples/quickstarts/helidon-quickstart-se/Dockerfile.native rename examples/quickstarts/{helidon-quickstart-graalvm/src/main/k8s => helidon-quickstart-se}/app.yaml (75%) delete mode 100644 examples/quickstarts/helidon-quickstart-se/src/main/docker/Dockerfile create mode 100644 examples/quickstarts/helidon-quickstart-se/src/main/resources/META-INF/native-image/helidon-example-reflection-config.json rename examples/quickstarts/{helidon-quickstart-graalvm/src/main/resources/application.yaml => helidon-quickstart-se/src/main/resources/META-INF/native-image/native-image.properties} (81%) diff --git a/docs-internal/dockerbuild-local-snapshots.md b/docs-internal/dockerbuild-local-snapshots.md new file mode 100644 index 000000000..c9632d409 --- /dev/null +++ b/docs-internal/dockerbuild-local-snapshots.md @@ -0,0 +1,109 @@ +# Docker build with local SNAPSHOT + +## Start Nexus + +```bash +docker volume create --name nexus-data +docker run -d -p 8081:8081 --name nexus -v nexus-data:/nexus-data sonatype/nexus3 +``` + +Nexus can take some time to start, ping the following URL to check the status: + `http://localhost:8081` + +## Configure nexus credentials + +```xml + + + + local-nexus + admin + admin123 + + + +``` + +## Deploy SNAPSHOT artifacts to Nexus + +```bash +mvn deploy -DskipTests \ + -DaltDeploymentRepository=local-nexus::default::http://localhost:8081/repository/maven-snapshots +``` + +## Update the Dockerfile + +Create a `settings.xml` as follow: + +```xml + + + /tmp/repository + + + + x-repo + + + env.X_REPO + + + + + x-repo + ${env.X_REPO} + + never + true + + + true + + + + + + x-repo + ${env.X_REPO} + + never + true + + + true + + + + + + +``` + +Update the `Dockerfile` and add the following lines: + +``` +# A build time argument that can be used to configure an extra Maven repository. +# E.g. --build-arg X_REPO=my-repo-url +ARG X_REPO +ADD settings.xml / +``` + +Then add `-s /settings.xml` to all Maven commands. + +## Build your image + +Replace `DOCKER_HOST` with a host name or IP address that can be used to reach + the nexus server from inside a container. (E.g. docker.for.mac.localhost). + +```bash +docker build \ + --build-arg X_REPO=http://DOCKER_HOST:8081/repository/maven-public \ + -t my-image-tag \ + . +``` diff --git a/docs/src/main/docs/guides/02_quickstart-se.adoc b/docs/src/main/docs/guides/02_quickstart-se.adoc index 50d8845b7..40f5e51d5 100644 --- a/docs/src/main/docs/guides/02_quickstart-se.adoc +++ b/docs/src/main/docs/guides/02_quickstart-se.adoc @@ -99,16 +99,14 @@ curl -X GET http://localhost:8080/greet/Jose == Build a Docker Image -The project also contains a Dockerfile so that you can easily -build and run a Docker image. Because the example's runtime -dependencies are already in `target/libs`, the Dockerfile is -pretty simple (see `target/Dockerfile`). To build the Docker -image, you need to have Docker installed and running on your system. +The project also contains a Dockerfile so that you can easily build and run a + Docker image. To build the Docker image, you need to have Docker installed and + running on your system. [source,bash] .Docker build ---- -docker build -t helidon-quickstart-se target +docker build -t helidon-quickstart-se . ---- [source,bash] @@ -135,7 +133,7 @@ kubectl get nodes [source,bash] .Deploy the application to Kubernetes ---- -kubectl create -f target/app.yaml +kubectl create -f app.yaml kubectl get pods # Wait for quickstart pod to be RUNNING ---- @@ -159,5 +157,5 @@ After you're done, cleanup. [source,bash] .Remove the application from Kubernetes ---- -kubectl delete -f target/app.yaml +kubectl delete -f app.yaml ---- diff --git a/docs/src/main/docs/guides/03_quickstart-mp.adoc b/docs/src/main/docs/guides/03_quickstart-mp.adoc index ce02dba3c..f5374974c 100644 --- a/docs/src/main/docs/guides/03_quickstart-mp.adoc +++ b/docs/src/main/docs/guides/03_quickstart-mp.adoc @@ -99,16 +99,14 @@ curl -X GET http://localhost:8080/greet/Jose == Build a Docker Image -The project also contains a Dockerfile so that you can easily -build and run a Docker image. Because the example's runtime -dependencies are already in `target/libs`, the Dockerfile is -pretty simple (see `target/Dockerfile`). To build the Docker -image, you need to have Docker installed and running on your system. +The project also contains a Dockerfile so that you can easily build and run a + Docker image. To build the Docker image, you need to have Docker installed and + running on your system. [source,bash] .Docker build ---- -docker build -t helidon-quickstart-mp target +docker build -t helidon-quickstart-mp . ---- [source,bash] @@ -135,7 +133,7 @@ kubectl get nodes [source,bash] .Deploy the application to Kubernetes ---- -kubectl create -f target/app.yaml +kubectl create -f app.yaml kubectl get pods # Wait for quickstart pod to be RUNNING ---- @@ -159,5 +157,5 @@ After you're done, cleanup. [source,bash] .Remove the application from Kubernetes ---- -kubectl delete -f target/app.yaml +kubectl delete -f app.yaml ---- diff --git a/docs/src/main/docs/guides/04_dockerfile.adoc b/docs/src/main/docs/guides/04_dockerfile.adoc index fec18efba..b4447d8f5 100644 --- a/docs/src/main/docs/guides/04_dockerfile.adoc +++ b/docs/src/main/docs/guides/04_dockerfile.adoc @@ -64,38 +64,47 @@ Fat Jars are jar files that contain the application and its dependencies ; they This section describes the Dockerfile provided by the <>. -The Dockerfile is located at `src/main/docker/Dockerfile` and contains the - following: +The Dockerfile is located at `./Dockerfile` and contains the following: [source,yaml] ---- -FROM openjdk:8-jre-slim #<1> +# Multistage Docker build. <1> +# 1st stage, build the app <2> +FROM maven:3.5.4-jdk-9 as build -RUN mkdir /app -COPY libs /app/libs #<2> -COPY ${project.artifactId}.jar /app #<3> +WORKDIR /helidon -CMD ["java", "-jar", "/app/${project.artifactId}.jar"] #<4> +# 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 -DskipTests # <3> + +# Do the Maven build! +# Incremental docker builds will resume here when you change sources +ADD src src +RUN mvn package -DskipTests # <4> + +RUN echo "done!" + +# 2nd stage, build the runtime image <5> +FROM openjdk:8-jre-slim # <6> +WORKDIR /helidon + +# Copy the binary built in the 1st stage +COPY --from=build /helidon/target/helidon-quickstart-se.jar ./ +COPY --from=build /helidon/target/libs ./libs # <5> + +CMD ["java", "-jar", "helidon-quickstart-se.jar"] # <7> ---- -<1> The base image is the Java 8 JRE image provided by the OpenJDK project. -<2> First, the application dependencies are copied to `/app`. -<3> Then, the application jar file is copied to `/app`. -<4> The command to start the application. - -[IMPORTANT] -.Incremental build -==== -When rebuilding an image Docker rebuilds from the first layer that is - effectively changed. Copying the application jar file after the libraries - ensures that Docker does not rebuild the prior layers. -==== - -[NOTE] -.What is ${project.artifactId}? -==== -It's a Maven property. The file above is processed during the Maven build, a new - file is created under the target directory and the property value is expanded. -==== +<1> This is a multi-stage Docker build. See more info + link:{docker-multi-stage-url}[here] +<2> The first stage that creates the build artifacts +<3> Create a layer, using just the `pom.xml`, that contains the Maven cache. +<4> When resuming here, Maven won't re-download the world. +<5> The final stage that creates the image for our application. +<6> Using a lightweight image. +<7> The command to start the application. [source,bash] .Build the project @@ -126,7 +135,7 @@ curl -X GET http://localhost:8080/greet This section describes how to build an image with a custom Java 11 JRE using `jlink`. -Replace `src/main/docker/Dockerfile` with the following: +Replace `Dockerfile` with the following: [source,yaml] ---- diff --git a/docs/src/main/docs/guides/06_Oracle_Kubernetes.adoc b/docs/src/main/docs/guides/06_Oracle_Kubernetes.adoc index e5ff05d88..d1ab2959c 100644 --- a/docs/src/main/docs/guides/06_Oracle_Kubernetes.adoc +++ b/docs/src/main/docs/guides/06_Oracle_Kubernetes.adoc @@ -116,8 +116,8 @@ kubectl create secret docker-registry \ First, change to the `helidon-quickstart-se` directory. -Then edit `src/main/k8s/app.yaml` and add the following under `spec` in the - `deployment` section: +Then edit `app.yaml` and add the following under `spec` in the `deployment` + section: [source, yaml] ---- @@ -134,14 +134,10 @@ spec: <1> The config secret name <2> The image path -NOTE: The file at `src/main/k8s/app.yaml` is configured as a Maven resource to - allow for substituting Maven properties, the Maven build generates a substituted - file at `target/app.yaml`. - [source,bash] .Deploy the application: ---- -kubectl create -f target/app.yaml -n helidon +kubectl create -f app.yaml -n helidon ---- [source,bash] diff --git a/etc/dockerfiles/Dockerfile.jdk8-graalvm b/etc/dockerfiles/Dockerfile.jdk8-graalvm new file mode 100644 index 000000000..45b7623f0 --- /dev/null +++ b/etc/dockerfiles/Dockerfile.jdk8-graalvm @@ -0,0 +1,63 @@ +# +# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM debian:stretch as build + +WORKDIR /build + +RUN set -x \ + && apt-get -y update \ + && apt-get -y install curl + +RUN curl -O -L https://github.com/oracle/graal/releases/download/vm-1.0.0-rc13/graalvm-ce-1.0.0-rc13-linux-amd64.tar.gz && \ + tar -xvzf graalvm-*.tar.gz && \ + rm graalvm-*.tar.gz && \ + mv graalvm-* graalvm + +RUN cd graalvm && \ + rm -rf \ + samples \ + man \ + jre/man \ + jre/languages \ + src.zip \ + bin/jvisualvm lib/visualvm \ + bin/js jre/bin/js \ + bin/node jre/bin/node \ + bin/npm jre/bin/npm \ + bin/polyglot jre/bin/polyglot \ + bin/lli jre/bin/lli \ + jre/lib/amd64/libjvmcicompiler.so \ + jre/lib/amd64/liblcms.so \ + jre/lib/boot/graaljs-scriptengine.jar \ + jre/lib/graalvm/graal-truffle-compiler-libgraal.jar \ + jre/lib/graalvm/graaljs-launcher.jar \ + jre/lib/graalvm/sulong-launcher.jar + +RUN echo "done!" + +FROM debian:stretch-slim as final + +RUN set -x \ + && apt-get -y update \ + && apt-get -y install gcc zlib1g-dev \ + && apt-get clean autoclean \ + && apt-get autoremove --yes \ + && rm -rf /var/lib/{apt,dpkg,cache,log}/ + +WORKDIR /graal +COPY --from=build /build/graalvm /graal/graalvm +ENV GRAALVM_HOME=/graal/graalvm diff --git a/etc/dockerfiles/Dockerfile.jdk8-graalvm-maven b/etc/dockerfiles/Dockerfile.jdk8-graalvm-maven new file mode 100644 index 000000000..8ca2b7251 --- /dev/null +++ b/etc/dockerfiles/Dockerfile.jdk8-graalvm-maven @@ -0,0 +1,38 @@ +# +# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM debian:stretch as build + +WORKDIR /build + +RUN set -x \ + && apt-get -y update \ + && apt-get -y install curl unzip + +RUN set -x && \ + curl -O https://archive.apache.org/dist/maven/maven-3/3.6.0/binaries/apache-maven-3.6.0-bin.zip && \ + unzip apache-maven-*-bin.zip && \ + rm apache-maven-*-bin.zip && \ + mv apache-maven-* maven + +RUN echo "done!" + +FROM helidon/jdk8-graalvm:1.0.0-rc13 + +COPY --from=build /build/maven /usr/share/maven +RUN ln -s /usr/share/maven/bin/mvn /bin/ + +ENV JAVA_HOME /graal/graalvm \ No newline at end of file diff --git a/etc/dockerfiles/build.sh b/etc/dockerfiles/build.sh new file mode 100755 index 000000000..899f24c31 --- /dev/null +++ b/etc/dockerfiles/build.sh @@ -0,0 +1,69 @@ +#!/bin/bash -e +# +# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +trap 'echo "ERROR: Error occurred at ${BASH_SOURCE}:${LINENO} command: ${BASH_COMMAND}"' ERR +set -eo pipefail + +usage(){ + echo "" + echo "Usage: `basename ${0}` [OPTIONS]" + echo "" + echo "Build and push Helidon docker images." + echo "" + echo "Options:" + echo " --push" + echo " --help print the usage and exit" + echo "" +} + +# parse command line arguments +for ((i=1;i<=${#*};i++)) +{ + arg="${!i}" + case "${arg}" in + "--push") + readonly PUSH="true" + ;; + "--help") + usage + exit 0 + ;; + *) + echo "" + echo "ERROR: Unknown option: ${arg}" + usage + exit 1 + ;; + esac +} + +if [ -h "${0}" ] ; then + readonly SCRIPT_PATH="$(readlink "$0")" +else + readonly SCRIPT_PATH="${0}" +fi +readonly MY_DIR=$(cd $(dirname -- "${SCRIPT_PATH}") ; pwd -P) + +readonly GRAALVM_VERSION=1.0.0-rc13 + +docker build -f ${MY_DIR}/Dockerfile.jdk8-graalvm -t helidon/jdk8-graalvm:${GRAALVM_VERSION} ${MY_DIR} +docker build -f ${MY_DIR}/Dockerfile.jdk8-graalvm-maven -t helidon/jdk8-graalvm-maven:${GRAALVM_VERSION} ${MY_DIR} + +if [ "${PUSH}" = "true" ] ; then + docker push helidon/jdk8-graalvm:${GRAALVM_VERSION} + docker push helidon/jdk8-graalvm-maven:${GRAALVM_VERSION} +fi \ No newline at end of file diff --git a/examples/pom.xml b/examples/pom.xml index 76deb5fa9..ac7c72fd7 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -69,5 +69,4 @@ - diff --git a/examples/quickstarts/archetypes/README.md b/examples/quickstarts/archetypes/README.md index 9841a16a6..f72aaa07d 100644 --- a/examples/quickstarts/archetypes/README.md +++ b/examples/quickstarts/archetypes/README.md @@ -1,45 +1,19 @@ - # Helidon Archetypes These are scripts for creating and deploying the Helidon quickstart archetypes. -To simplify ongoing maintenance of the quickstart examples and archetypes -we generate the archetypes on the fly using the create-from-project goal -of the archetype plugin. +To simplify maintenance of the quickstart examples and archetypes we generate + the archetypes on the fly using a shell script. -Unfortunately archetype:create-from-project is designed to be run by a -human against the pom.xml of the project you want to create the archetype -for. There was not an obvious way to run it from another project (pom) and -point it at the example project. - -We also want to keep the example pom's clean, which further limits our -option (don't want any archetype configuration in the example poms). +We also want to keep the example poms clean, which further limits our option + (don't want any archetype configuration in the example poms). So, we resorted to the following scripts: - -* `create-archetypes.sh helidon-version`: Iterates over the quickstart examples - and creates the archetypes. This script uses `archetypes.properties` as - input to get values for version and group id. - -* `set-version.sh [helidon-version]`: iterates over the - quickstart examples' poms and changes the helidon.version property in the - poms to be the specified version. If helidon-version is not - passed then the scripts looks for RELEASE_FULL_VERSION in the environment. - Also updates `archetype.properties` to update the archetype version. - This script is used during a release of the SDK to ensure that the - examples (generated by the archetypes) use the released version of - the SDK bom pom. - -* `deploy-archetypes.sh [helidon-version]`: calls create-archetypes.sh - to create and build the archetypes, and then deploys them. If - helidon-version is not passed then the scripts looks for RELEASE_FULL_VERSION - in the environment. This script is used during a release of the SDK - to release the archetypes. - -Remember, all of this wierd stuff is because we want to create the -archetypes on the fly. An alternative would be to recreate the -archetypes manually whenever we change the examples, and check -in the archetype source as a maven module. But that then makes -maintenance of the quickstart examples less convenient. +* `create-archetype.sh`: Creates a single archetype from an existing project +* `create-archetypes.sh`: Creates all the Helidon archetypes +* `set-version.sh`: Iterates over the quickstart examples poms and changes the + `helidon.version` property in the poms to be the specified version. +* `deploy-archetypes.sh`: calls create-archetypes.sh to create and build the + archetypes, and then deploys them. ## Making changes to quickstart examples and trying the archetypes @@ -48,26 +22,5 @@ and try them out. Once you are done messing with the examples and you want to try out the archetypes, do this: ``` -bash create-archetypes.sh +bash test-archetypes.sh ``` - -You can then try an archetype (which should now be in your local maven -repo): - -``` -# Use whatever archetypeVersion you used above -mvn archetype:generate -DinteractiveMode=false \ - -DarchetypeGroupId=io.helidon.archetypes -DarchetypeArtifactId=helidon-quickstart-se \ - -DarchetypeVersion=0.0.1-SNAPSHOT \ - -DgroupId=io.helidon.examples -DartifactId=quickstart-se -Dpackage=io.helidon.examples.quickstart.se -``` - -## If you add a new quickstart example - -If you add a new example, you'll want to add it to the examples lists in -each shell scripts. Apologies for violating DRY. - -## If you want to change the archetype group id - -Update archetype.groupId in `archetype.properties` to use the new archetype groupid. - diff --git a/examples/quickstarts/archetypes/archetype.properties b/examples/quickstarts/archetypes/archetype.properties deleted file mode 100644 index 9001de459..000000000 --- a/examples/quickstarts/archetypes/archetype.properties +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# See -# https://maven.apache.org/archetype/maven-archetype-plugin/examples/create-with-property-file.html -archetype.groupId=io.helidon.archetypes -# Expanded by create-archetypes.sh script -archetype.artifactId=${archetypeArtifactId} -archetype.version=1.0.3-SNAPSHOT -archetype.languages=java, docker -excludePatterns=**/.idea/**, *.iml, target/**, build/**, build.gradle, settings.gradle, .gradle/** diff --git a/examples/quickstarts/archetypes/create-archetype.sh b/examples/quickstarts/archetypes/create-archetype.sh new file mode 100755 index 000000000..bfc755f91 --- /dev/null +++ b/examples/quickstarts/archetypes/create-archetype.sh @@ -0,0 +1,374 @@ +#!/bin/bash -e +# +# Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +trap 'echo "ERROR: Error occurred at ${BASH_SOURCE}:${LINENO} command: ${BASH_COMMAND}"' ERR +set -eo pipefail + +usage(){ + echo "" + echo "Usage: `basename ${0}` [OPTIONS] PARAMETERS" + echo "" + echo "Create an archetype from an existing project." + echo "" + echo "Parameters:" + echo " --projectdir=PATH input project directory to create an archetype from" + echo " --groupid=XXX groupId of the input project" + echo " --artifactid=XXX artifactId of the input project" + echo " --version=XXX version of the input project" + echo " --name=XXX name of the input project" + echo " --package=XXX base Java package of the input project" + echo " --archetype-name=XXX name of the generated archetype" + echo " --archetype-description=XXX description of the generated archetype" + echo " --archetype-groupid=XXX groupId of the generated archetype" + echo "" + echo "Options:" + echo " --clean delete the generated archetype directory if it exists" + echo " --exludes=XXX regular expression for files to exclude" + echo " --maven-args arguments for the maven command to execute post generation (e.g. install)" + echo " --help print the usage and exit" + echo "" +} + +# parse command line arguments +for ((i=1;i<=${#*};i++)) +{ + arg="${!i}" + case "${arg}" in + "--projectdir="*) + readonly PROJECT_DIR="${arg#*=}" + ;; + "--groupid="*) + readonly GROUPID="${arg#*=}" + ;; + "--artifactid="*) + readonly ARTIFACTID="${arg#*=}" + ;; + "--version="*) + readonly VERSION="${arg#*=}" + ;; + "--name="*) + readonly NAME="${arg#*=}" + ;; + "--package="*) + readonly PACKAGE="${arg#*=}" + ;; + "--archetype-name="*) + readonly ARCHETYPE_NAME="${arg#*=}" + ;; + "--archetype-description="*) + readonly ARCHETYPE_DESCRIPTION="${arg#*=}" + ;; + "--archetype-groupid="*) + readonly ARCHETYPE_GROUPID="${arg#*=}" + ;; + "--excludes="*) + readonly EXCLUDES="${arg#*=}" + ;; + "--maven-args="*) + readonly MAVEN_ARGS="${arg#*=}" + ;; + "--clean") + readonly CLEAN="true" + ;; + "--help") + usage + exit 0 + ;; + *) + echo "" + echo "ERROR: Unknown option: ${arg}" + usage + exit 1 + ;; + esac +} + +echo "" +MISSING_PARAMS=false +if [ -z "${PROJECT_DIR}" ] ; then + echo "ERROR: Missing required parameter --projectdir" + MISSING_PARAMS=true +fi +if [ -z "${GROUPID}" ] ; then + echo "ERROR: Missing required parameter --groupid" + MISSING_PARAMS=true +fi +if [ -z "${ARTIFACTID}" ] ; then + echo "ERROR: Missing required parameter --artifactid" + MISSING_PARAMS=true +fi +if [ -z "${VERSION}" ] ; then + echo "ERROR: Missing required parameter --version" + MISSING_PARAMS=true +fi +if [ -z "${NAME}" ] ; then + echo "ERROR: Missing required parameter --name" + MISSING_PARAMS=true +fi +if [ -z "${PACKAGE}" ] ; then + echo "ERROR: Missing required parameter --package" + MISSING_PARAMS=true +fi +if [ -z "${ARCHETYPE_GROUPID}" ] ; then + echo "ERROR: Missing required parameter --archetype-groupid" + MISSING_PARAMS=true +fi +if [ -z "${ARCHETYPE_NAME}" ] ; then + echo "ERROR: Missing required parameter --archetype-name" + MISSING_PARAMS=true +fi +if [ -z "${ARCHETYPE_DESCRIPTION}" ] ; then + echo "ERROR: Missing required parameter --archetype-description" + MISSING_PARAMS=true +fi +if ${MISSING_PARAMS} ; then + usage + exit 1 +fi + +readonly DEFAULT_EXCLUDES="^[a-z]*\.gradle$|^\.idea$|^\.iml$" +if [ -z "${EXCLUDES}" ] ; then + readonly EXCLUDES="${DEFAULT_EXCLUDES}" +fi + +# verify project directory +if [ ! -d "${PROJECT_DIR}" ] ; then + echo "ERROR: Invalid project directory: ${PROJECT_DIR}" + exit 1 +fi + +# absolute path to project directory +PROJECT_DIR_PATH=$(cd "${PROJECT_DIR}" ; pwd -P) +PROJECT_DIRNAME=$(basename "${PROJECT_DIR_PATH}") +PROJECT_DIR_PARENT=$(cd "${PROJECT_DIR}/.." ; pwd -P) + +if [ -h "${0}" ] ; then + readonly SCRIPT_PATH="$(readlink "$0")" +else + readonly SCRIPT_PATH="${0}" +fi + +readonly MY_DIR=$(cd $(dirname -- "${SCRIPT_PATH}") ; pwd -P) +readonly ARCHETYPE_BASEDIR="${MY_DIR}" +readonly ARCHETYPE_DIRNAME="target/${ARTIFACTID}" +readonly ARCHETYPE_DIR="${ARCHETYPE_BASEDIR}/${ARCHETYPE_DIRNAME}" + +if [ -d "${ARCHETYPE_DIR}" ] ; then + if [ "${CLEAN}" = "true" ] ; then + rm -rf ${ARCHETYPE_DIR} + else + echo "ERROR: Generated archetype directory exists ${ARCHETYPE_DIR}" + exit 1 + fi +fi + +echo "INFO: Generating archetype project at ${ARCHETYPE_DIR}" +mkdir -p ${ARCHETYPE_DIR} + +echo "INFO: Generating archetype pom" +cat ${MY_DIR}/templates/pom.xml | sed \ + -e s@__GROUPID__@"${ARCHETYPE_GROUPID}"@g \ + -e s@__ARTIFACTID__@"${ARTIFACTID}"@g \ + -e s@__VERSION__@"${VERSION}"@g \ + -e s@__NAME__@"${ARCHETYPE_NAME}"@g \ + -e s@__DESCRIPTION__@"${ARCHETYPE_DESCRIPTION}"@g \ + > ${ARCHETYPE_DIR}/pom.xml + +# Process a java file into a template. +# $1 input base directory +# $2 input filename +# $3 output base directory +# $4 output directory name +processJavaFile(){ + local input_basedir=${1} + local input_filename=${2} + local output_basedir=${3} + local output_dirname=${4} + local inputfile_basename=`basename ${input_basedir}/${input_filename}` + local outputfile=${output_basedir}/${output_dirname}/${inputfile_basename} + + if [[ ${input_filename} =~ ${EXCLUDES} ]] ; then + echo "INFO: Excluding ${input_filename}" + return 0 + fi + + echo "INFO: Processing ${input_filename}" + echo "INFO: Generating template at ${output_dirname}/${inputfile_basename}" + + echo "#set( \$symbol_pound = '#' )" >> ${outputfile} + echo "#set( \$symbol_dollar = '$' )" >> ${outputfile} + echo "#set( \$symbol_escape = '\' )" >> ${outputfile} + + cat ${input_basedir}/${input_filename} | sed \ + -e s@"${PACKAGE}"@'${package}'@g \ + -e s@"${ARTIFACTID}"@'${artifactId}'@g \ + -e s@"${VERSION}"@'${version}'@g \ + >> ${outputfile} +} + +# Process a top level file into a template. +# $1 input base directory +# $2 input filename +# $3 output base directory +# $4 output directory name +processFile(){ + local input_basedir=${1} + local input_filename=${2} + local output_basedir=${3} + local output_dirname=${4} + local outputfile=${output_basedir}/${output_dirname}/${input_filename} + + if [[ ${input_filename} =~ ${EXCLUDES} ]] ; then + echo "INFO: Excluding ${input_filename}" + return 0 + fi + + echo "INFO: Processing ${input_filename}" + echo "INFO: Generating template at ${output_dirname}/${input_filename}" + + mkdir -p `dirname ${outputfile}` + + echo "#set( \$symbol_pound = '#' )" >> ${outputfile} + echo "#set( \$symbol_dollar = '$' )" >> ${outputfile} + echo "#set( \$symbol_escape = '\' )" >> ${outputfile} + + cat ${input_basedir}/${input_filename} | sed \ + -e s@"${GROUPID}"@'${groupId}'@g \ + -e s@"${ARTIFACTID}"@'${artifactId}'@g \ + -e s@"${VERSION}"@'${version}'@g \ + -e s@'#'@'${symbol_pound}'@g \ + >> ${outputfile} +} + +# Process a top level file into a template. +# $1 input base directory +# $2 input filename +# $3 output base directory +# $4 output directory name +processProjectPom(){ + local input_basedir=${1} + local input_filename=${2} + local output_basedir=${3} + local output_dirname=${4} + local outputfile=${output_basedir}/${output_dirname}/${input_filename} + + echo "INFO: Processing ${input_filename}" + echo "INFO: Generating pom.xml at ${output_dirname}/${input_filename}" + + cat ${input_basedir}/${input_filename} | sed \ + -e s@"${PACKAGE}."@'${package}.'@g \ + -e s@"${GROUPID}"@'${groupId}'@g \ + -e s@"${ARTIFACTID}"@'${artifactId}'@g \ + -e s@"${VERSION}"@'${version}'@g \ + -e s@"${NAME}"@'${project.artifactId}'@g \ + > ${outputfile} +} + +mkdir -p ${ARCHETYPE_DIR}/src/main/resources/archetype-resources + +# process main sources +if [ -d "${PROJECT_DIR_PATH}/src/main/java" ] ; then + echo "INFO: Processing Java files under src/main/java" + mkdir -p ${ARCHETYPE_DIR}/src/main/resources/archetype-resources/src/main/java + for javaFile in `find ${PROJECT_DIR_PATH}/src/main/java -type f -name "*.java" | sed s@"^${PROJECT_DIR_PATH}/"@@g` ; do + processJavaFile \ + ${PROJECT_DIR_PARENT}/${PROJECT_DIRNAME} \ + ${javaFile} \ + ${ARCHETYPE_DIR} \ + src/main/resources/archetype-resources/src/main/java + done +fi + +# process test sources +if [ -d "${PROJECT_DIR_PATH}/src/test/java" ] ; then + echo "INFO: Processing Java files under src/test/java" + mkdir -p ${ARCHETYPE_DIR}/src/main/resources/archetype-resources/src/test/java + for javaFile in `find ${PROJECT_DIR_PATH}/src/test/java -type f -name "*.java" | sed s@"^${PROJECT_DIR_PATH}/"@@g` ; do + processJavaFile \ + ${PROJECT_DIR_PARENT}/${PROJECT_DIRNAME} \ + ${javaFile} \ + ${ARCHETYPE_DIR} \ + src/main/resources/archetype-resources/src/test/java + done +fi + +# process resources +if [ -d "${PROJECT_DIR_PATH}/src/main/resources" ] ; then + echo "INFO: Processing resources under src/main/resources" + mkdir -p ${ARCHETYPE_DIR}/src/main/resources/archetype-resources/src/main/resources/ + for resourceFile in `find ${PROJECT_DIR_PATH}/src/main/resources -type f | sed s@"^${PROJECT_DIR_PATH}"@@g` ; do + processFile \ + ${PROJECT_DIR_PARENT}/${PROJECT_DIRNAME} \ + ${resourceFile} \ + ${ARCHETYPE_DIR} \ + src/main/resources/archetype-resources + done +fi + +# process test resources +if [ -d "${PROJECT_DIR_PATH}/src/test/resources" ] ; then + echo "INFO: Processing resources under src/test/resources" + mkdir -p ${ARCHETYPE_DIR}/src/main/resources/archetype-resources/src/test/resources/ + for resourceFile in `find ${PROJECT_DIR_PATH}/src/test/resources -type f | sed s@"^${PROJECT_DIR_PATH}"@@g` ; do + processFile \ + ${PROJECT_DIR_PARENT}/${PROJECT_DIRNAME} \ + ${resourceFile} \ + ${ARCHETYPE_DIR} \ + src/main/resources/archetype-resources + done +fi + +# process all other files +echo "INFO: Processing all other files under ${PROJECT_DIR}" +for file in `find ${PROJECT_DIR_PATH} -type f | sed s@"^${PROJECT_DIR_PATH}/"@@g` ; do + if [[ ${file} =~ ^target|^src/main/java|^src/test/java|src/main/resources|src/test/resources ]] ; then + continue + fi + if [ `basename ${file}` != "pom.xml" ] ; then + processFile \ + ${PROJECT_DIR_PARENT}/${PROJECT_DIRNAME} \ + ${file} \ + ${ARCHETYPE_DIR} \ + src/main/resources/archetype-resources + else + processProjectPom \ + ${PROJECT_DIR_PARENT}/${PROJECT_DIRNAME} \ + ${file} \ + ${ARCHETYPE_DIR} \ + src/main/resources/archetype-resources + fi +done + +echo "INFO: Generating archetype-metadata.xml" +mkdir -p ${ARCHETYPE_DIR}/src/main/resources/META-INF/maven +cat ${MY_DIR}/templates/archetype-metadata.xml | sed \ + -e s@__ARTIFACTID__@"${ARTIFACTID}"@g \ + > ${ARCHETYPE_DIR}/src/main/resources/META-INF/maven/archetype-metadata.xml + +# smoke test +mkdir -p ${ARCHETYPE_DIR}/src/test/resources/projects/basic +echo "package=it.pkg" >> ${ARCHETYPE_DIR}/src/test/resources/projects/basic/archetype.properties +echo "version=0.1-SNAPSHOT" >> ${ARCHETYPE_DIR}/src/test/resources/projects/basic/archetype.properties +echo "groupId=archetype.it" >> ${ARCHETYPE_DIR}/src/test/resources/projects/basic/archetype.properties +echo "artifactId=basic" >> ${ARCHETYPE_DIR}/src/test/resources/projects/basic/archetype.properties +touch ${ARCHETYPE_DIR}/src/test/resources/projects/basic/goal.txt + +echo "DONE!" +echo "" + +if [ ! -z "${MAVEN_ARGS}" ] ; then + mvn -f ${ARCHETYPE_DIR}/pom.xml ${MAVEN_ARGS} +fi \ No newline at end of file diff --git a/examples/quickstarts/archetypes/create-archetypes.sh b/examples/quickstarts/archetypes/create-archetypes.sh index 98fad741d..7ede4ae3f 100755 --- a/examples/quickstarts/archetypes/create-archetypes.sh +++ b/examples/quickstarts/archetypes/create-archetypes.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -e # # Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. # @@ -15,139 +15,92 @@ # limitations under the License. # -# -# Create archetypes from the quickstart examples. Usage: -# -# create-archetypes.sh [path-to-local-maven-repo] -# -# path-to-local-maven-repo is an optional path to a local -# maven repository to use. This is used, for example, by -# build pipelines that use a non-standard place for the -# local maven repository. -# -# This script uses the archetype.properties file located in the -# same directory as the script as input. -# -# The script does this for each quickstart example: -# -# 1 A clean build of the example -# 2 Generates the archetype for the example. The generated -# archetype project goes in target/generated-sources/archetype -# 3 Build's the generated archetype project -# +trap 'echo "ERROR: Error occurred at ${BASH_SOURCE}:${LINENO} command: ${BASH_COMMAND}"' ERR set -eo pipefail -# Path to this script -if [ -h "${0}" ] ; then - SCRIPT_PATH="$(readlink "$0")" -else - SCRIPT_PATH="${0}" -fi +usage(){ + echo "" + echo "Usage: `basename ${0}` [OPTIONS] --version=XXX" + echo "" + echo "Create archetypes from the quickstart examples." + echo "Parameter:" + echo "--version=XXX current Helidon version" + echo "" + echo "Options:" + echo " --maven-args=XXX arguments for the maven command to execute post generation (default is install)" + echo " --help print the usage and exit" + echo "" +} -# Current directory -MY_DIR=$(cd $(dirname -- "${SCRIPT_PATH}") ; pwd -P) - -EXAMPLE_DIR="${MY_DIR}/.." - -EXAMPLES=" \ - helidon-quickstart-se \ - helidon-quickstart-mp \ -" - -TEMP_PROP_FILE=$(mktemp -t archetype.properties.XXXXXX) - -EXTRA_MAVEN_OPTS= -if [ ! -z "${1}" ]; then - if [ ! -d "${1}" ]; then - echo "No such maven repo directory ${1}" +# parse command line arguments +for ((i=1;i<=${#*};i++)) +{ + arg="${!i}" + case "${arg}" in + "--version="*) + readonly HELIDON_VERSION="${arg#*=}" + ;; + "--maven-args="*) + readonly MAVEN_ARGS="${arg#*=}" + ;; + "--help") + usage + exit 0 + ;; + *) + echo "" + echo "ERROR: Unknown option: ${arg}" + usage exit 1 - fi - EXTRA_MAVEN_OPTS="-Dmaven.repo.local=${1}" - echo "Using local repository ${1}" + ;; + esac +} + +echo "" +MISSING_PARAMS=false +if [ -z "${HELIDON_VERSION}" ] ; then + echo "ERROR: Missing required parameter --version" + MISSING_PARAMS=true +fi +if ${MISSING_PARAMS} ; then + usage + exit 1 fi -# Make sure the parent and bom poms are built -mvn -B -N ${EXTRA_MAVEN_OPTS} -f ${MY_DIR}/../../../pom.xml clean install -mvn -B -N ${EXTRA_MAVEN_OPTS} -f ${MY_DIR}/../../../bom/pom.xml clean install +if [ -z "${MAVEN_ARGS}" ] ; then + readonly MAVEN_ARGS="install" +fi -for _ex in ${EXAMPLES}; do +if [ -h "${0}" ] ; then + readonly SCRIPT_PATH="$(readlink "$0")" +else + readonly SCRIPT_PATH="${0}" +fi +readonly MY_DIR=$(cd $(dirname -- "${SCRIPT_PATH}") ; pwd -P) +readonly EXAMPLE_DIR=$(cd "${MY_DIR}/.." ; pwd -P) - printf "\n========== ${_ex} ==========\n" - printf "Clean and sanity build of ${_ex}\n\n" - mvn -B ${EXTRA_MAVEN_OPTS} -f ${EXAMPLE_DIR}/${_ex}/pom.xml clean package +${MY_DIR}/create-archetype.sh \ + --clean \ + --projectdir="${EXAMPLE_DIR}/helidon-quickstart-se" \ + --groupid="io.helidon.examples" \ + --artifactid="helidon-quickstart-se" \ + --version="${HELIDON_VERSION}" \ + --package="io.helidon.examples.quickstart.se" \ + --name="Helidon Quickstart SE Example" \ + --archetype-name="Helidon Quickstart SE Archetype" \ + --archetype-description="Quickstart archetype for Helidon SE" \ + --archetype-groupid=io.helidon.archetypes \ + --maven-args="${MAVEN_ARGS}" - echo " ===== Generating archetype.properties file ${TEMP_PROP_FILE}" - cat ${MY_DIR}/archetype.properties | sed "s:\${archetypeArtifactId}:${_ex}:" \ - > "${TEMP_PROP_FILE}" - cat ${TEMP_PROP_FILE} - - echo " ===== Generating archetype for ${_ex}" - mvn -B ${EXTRA_MAVEN_OPTS} -f ${EXAMPLE_DIR}/${_ex}/pom.xml archetype:create-from-project -Darchetype.artifactId=${ex} -Darchetype.properties="${TEMP_PROP_FILE}" - - # Edit the pom to add more info - ARCHETYPE_DIR=${EXAMPLE_DIR}/${_ex}/target/generated-sources/archetype - mv ${ARCHETYPE_DIR}/pom.xml ${ARCHETYPE_DIR}/pom.xml.old - head -11 ${ARCHETYPE_DIR}/pom.xml.old > ${ARCHETYPE_DIR}/pom.xml - cat >> ${ARCHETYPE_DIR}/pom.xml << EOF - Helidon Archetype - - https://helidon.io - - - Oracle Corporation - http://www.oracle.com/ - - - - - Apache 2.0 - https://www.apache.org/licenses/LICENSE-2.0 - - - - - - Tomas Langer - tomas.langer@oracle.com - Oracle Corporation - - - Tim Quinn - tim.quinn@oracle.com - Oracle Corporation - - - Romain Grecourt - romain.grecourt@oracle.com - Oracle Corporation - - - Laird Jarrett Nelson - laird.nelson@oracle.com - Oracle Corporation - - - Santiago Pericas-Geertsen - santiago.pericasgeertsen@oracle.com - Oracle Corporation - - - - - scm:git:git@github.com:oracle/helidon.git - scm:git:git@github.com:oracle/helidon.git - HEAD - https://github.com/oracle/helidon - -EOF - tail -20 ${ARCHETYPE_DIR}/pom.xml.old >> ${ARCHETYPE_DIR}/pom.xml - rm -f ${ARCHETYPE_DIR}/pom.xml.old - - printf "\nBuilding archetype for ${_ex}\n\n" - mvn -B ${EXTRA_MAVEN_OPTS} -f ${ARCHETYPE_DIR}/pom.xml install - -done - -/bin/rm ${TEMP_PROP_FILE} - -echo "Done!" +${MY_DIR}/create-archetype.sh \ + --clean \ + --projectdir="${EXAMPLE_DIR}/helidon-quickstart-mp" \ + --groupid="io.helidon.examples" \ + --artifactid="helidon-quickstart-mp" \ + --version="${HELIDON_VERSION}" \ + --package="io.helidon.examples.quickstart.mp" \ + --name="Helidon Quickstart MP Example" \ + --archetype-name="Helidon Quickstart MP Archetype" \ + --archetype-description="Quickstart archetype for Helidon MP" \ + --archetype-groupid=io.helidon.archetypes \ + --maven-args="${MAVEN_ARGS}" \ No newline at end of file diff --git a/examples/quickstarts/archetypes/deploy-archetypes.sh b/examples/quickstarts/archetypes/deploy-archetypes.sh index d49738518..b1952b01b 100755 --- a/examples/quickstarts/archetypes/deploy-archetypes.sh +++ b/examples/quickstarts/archetypes/deploy-archetypes.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -e # # Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. # @@ -15,27 +15,26 @@ # limitations under the License. # +trap 'echo "ERROR: Error occurred at ${BASH_SOURCE}:${LINENO} command: ${BASH_COMMAND}"' ERR set -eo pipefail # Path to this script if [ -h "${0}" ] ; then - SCRIPT_PATH="$(readlink "$0")" + readonly SCRIPT_PATH="$(readlink "$0")" else - SCRIPT_PATH="${0}" + readonly SCRIPT_PATH="${0}" fi # Current directory -MY_DIR=$(cd $(dirname -- "${SCRIPT_PATH}") ; pwd -P) +readonly MY_DIR=$(cd $(dirname -- "${SCRIPT_PATH}") ; pwd -P) -EXAMPLE_DIR="${MY_DIR}/.." - -EXAMPLES=" \ - helidon-quickstart-se \ - helidon-quickstart-mp \ -" - -# Create archetypes from example projects -bash ${MY_DIR}/create-archetypes.sh +readonly MVN_VERSION=$(mvn \ + -q \ + -f ${MY_DIR}/../pom.xml \ + -Dexec.executable="echo" \ + -Dexec.args="\${project.version}" \ + --non-recursive \ + org.codehaus.mojo:exec-maven-plugin:1.3.1:exec) if [ -n "${STAGING_REPO_ID}" ] ; then readonly MAVEN_REPO_URL="https://oss.sonatype.org/service/local/staging/deployByRepositoryId/${STAGING_REPO_ID}/" @@ -43,18 +42,9 @@ else readonly MAVEN_REPO_URL="https://oss.sonatype.org/service/local/staging/deploy/maven2/" fi -# Deploy the archetypes -for _ex in ${EXAMPLES}; do +readonly MAVEN_DEPLOY_ARGS="org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy -DaltDeploymentRepository=ossrh::default::${MAVEN_REPO_URL}" +readonly MAVEN_ARGS="-B clean verify -DskipTests gpg:sign -Dgpg.passphase=${GPG_PASSPHRASE} ${MAVEN_DEPLOY_ARGS}" - echo "========== Deploying ${pom_file} ==========" - pom_file="${EXAMPLE_DIR}/${_ex}/target/generated-sources/archetype/pom.xml" - if [ -f "${pom_file}" ]; then - mvn -f "${pom_file}" \ - clean verify gpg:sign org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy -B -DskipTests \ - -Dgpg.passphase="${GPG_PASSPHRASE}" \ - -DaltDeploymentRepository=ossrh::default::${MAVEN_REPO_URL} - else - echo "${pom_file} does not exist. Skipping." - fi - -done +${MY_DIR}/create-archetypes.sh \ + --version="${MVN_VERSION}" \ + --maven-args="${MAVEN_ARGS}" diff --git a/examples/quickstarts/archetypes/set-version.sh b/examples/quickstarts/archetypes/set-version.sh index 62fa8577e..2bcdc8271 100755 --- a/examples/quickstarts/archetypes/set-version.sh +++ b/examples/quickstarts/archetypes/set-version.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -e # # Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. # @@ -24,17 +24,18 @@ # If new-helidon-version is not passed then the script will look in # FULL_VERSION # +trap 'echo "ERROR: Error occurred at ${BASH_SOURCE}:${LINENO} command: ${BASH_COMMAND}"' ERR set -eo pipefail # Path to this script if [ -h "${0}" ] ; then - SCRIPT_PATH="$(readlink "$0")" + readonly SCRIPT_PATH="$(readlink "$0")" else - SCRIPT_PATH="${0}" + readonly SCRIPT_PATH="${0}" fi # Current directory -MY_DIR=$(cd $(dirname -- "${SCRIPT_PATH}") ; pwd -P) +readonly MY_DIR=$(cd $(dirname -- "${SCRIPT_PATH}") ; pwd -P) EXAMPLE_DIR="${MY_DIR}/.." diff --git a/examples/quickstarts/archetypes/templates/archetype-metadata.xml b/examples/quickstarts/archetypes/templates/archetype-metadata.xml new file mode 100644 index 000000000..98809c1dd --- /dev/null +++ b/examples/quickstarts/archetypes/templates/archetype-metadata.xml @@ -0,0 +1,63 @@ + + + + + + src/main/java + + **/*.java + + + + src/test/java + + **/*.java + + + + src/main/resources + + **/* + + + + src/test/resources + + **/* + + + + + + **/* + + + src/main/java/** + src/test/java/** + src/main/resources/** + src/test/resources/** + pom.xml + + + + diff --git a/examples/quickstarts/archetypes/templates/pom.xml b/examples/quickstarts/archetypes/templates/pom.xml new file mode 100644 index 000000000..9314c1ec6 --- /dev/null +++ b/examples/quickstarts/archetypes/templates/pom.xml @@ -0,0 +1,103 @@ + + + + 4.0.0 + + __GROUPID__ + __ARTIFACTID__ + __VERSION__ + maven-archetype + + __NAME__ + + __DESCRIPTION__ + + https://helidon.io + + + Oracle Corporation + http://www.oracle.com/ + + + + + Apache 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + + + + + + Tomas Langer + tomas.langer@oracle.com + Oracle Corporation + + + Tim Quinn + tim.quinn@oracle.com + Oracle Corporation + + + Romain Grecourt + romain.grecourt@oracle.com + Oracle Corporation + + + Laird Jarrett Nelson + laird.nelson@oracle.com + Oracle Corporation + + + Santiago Pericas-Geertsen + santiago.pericasgeertsen@oracle.com + Oracle Corporation + + + + + scm:git:git@github.com:oracle/helidon.git + scm:git:git@github.com:oracle/helidon.git + HEAD + https://github.com/oracle/helidon + + + + UTF-8 + UTF-8 + + + + + + org.apache.maven.archetype + archetype-packaging + 3.0.1 + + + + + + + maven-archetype-plugin + 3.0.1 + + + + + diff --git a/examples/quickstarts/archetypes/test-archetypes.sh b/examples/quickstarts/archetypes/test-archetypes.sh index 42e6e07fc..daafb951f 100755 --- a/examples/quickstarts/archetypes/test-archetypes.sh +++ b/examples/quickstarts/archetypes/test-archetypes.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -e # # Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. # @@ -15,29 +15,23 @@ # limitations under the License. # +trap 'echo "ERROR: Error occurred at ${BASH_SOURCE}:${LINENO} command: ${BASH_COMMAND}"' ERR set -eo pipefail # Path to this script if [ -h "${0}" ] ; then - SCRIPT_PATH="$(readlink "$0")" + readonly SCRIPT_PATH="$(readlink "$0")" else - SCRIPT_PATH="${0}" + readonly SCRIPT_PATH="${0}" fi # Directory this script resides in -MY_DIR=$(cd $(dirname -- "${SCRIPT_PATH}") ; pwd -P) +readonly MY_DIR=$(cd $(dirname -- "${SCRIPT_PATH}") ; pwd -P) + # Current directory -CURRENT_DIR=${PWD} +readonly CURRENT_DIR=${PWD} -# cd to an innocuous directory since the archetypes will create -# a project here when we test it. See issue #64 -TARGET_DIR=${MY_DIR}/target -mkdir -p ${TARGET_DIR} -cd ${TARGET_DIR} - -${MY_DIR}/create-archetypes.sh - -MVN_VERSION=$(mvn \ +readonly MVN_VERSION=$(mvn \ -q \ -f ${MY_DIR}/../pom.xml \ -Dexec.executable="echo" \ @@ -45,34 +39,40 @@ MVN_VERSION=$(mvn \ --non-recursive \ org.codehaus.mojo:exec-maven-plugin:1.3.1:exec) -# invoke the quickstart-se archetype +${MY_DIR}/create-archetypes.sh \ + --version=${MVN_VERSION} \ + --maven-args="install" + +# cd to an innocuous directory since the archetypes will create +# a project here when we test it. See issue #64 +TARGET_DIR=${MY_DIR}/target +cd ${TARGET_DIR} + +rm -rf ${TARGET_DIR}/test-* || true + +# invoke the helidon-quickstart-se archetype mvn archetype:generate -DinteractiveMode=false \ -DarchetypeGroupId=io.helidon.archetypes \ -DarchetypeArtifactId=helidon-quickstart-se \ -DarchetypeVersion=${MVN_VERSION} \ - -DgroupId=io.helidon.examples \ - -DartifactId=quickstart-se \ - -Dpackage=io.helidon.examples.quickstart.se + -DgroupId=com.examples \ + -DartifactId=test-helidon-quickstart-se \ + -Dpackage=com.examples.test.helidon.se # build the generated project -mvn -f ${PWD}/quickstart-se/pom.xml install +mvn -f ${PWD}/test-helidon-quickstart-se/pom.xml install -# invoke the quickstart-mp archetype +# invoke the helidon-quickstart-mp archetype mvn archetype:generate -DinteractiveMode=false \ -DarchetypeGroupId=io.helidon.archetypes \ -DarchetypeArtifactId=helidon-quickstart-mp \ -DarchetypeVersion=${MVN_VERSION} \ - -DgroupId=io.helidon.examples \ - -DartifactId=quickstart-mp \ - -Dpackage=io.helidon.examples.quickstart.mp + -DgroupId=com.examples \ + -DartifactId=test-helidon-quickstart-mp \ + -Dpackage=com.examples.test.helidon.mp # build the generated project -mvn -f ${PWD}/quickstart-mp/pom.xml install - -# Paranoia. Don't want to delete /! -if [ ! -z "${TARGET_DIR}" ]; then - rm -rf ${TARGET_DIR}/ -fi +mvn -f ${PWD}/test-helidon-quickstart-mp/pom.xml install # cd back to original directory cd ${CURRENT_DIR} diff --git a/examples/quickstarts/helidon-quickstart-graalvm/README.md b/examples/quickstarts/helidon-quickstart-graalvm/README.md deleted file mode 100644 index 4d2dbf167..000000000 --- a/examples/quickstarts/helidon-quickstart-graalvm/README.md +++ /dev/null @@ -1,74 +0,0 @@ - -# Helidon Example: quickstart-graalvm - -This example implements a simple Hello World REST service. - -## Prerequisites - -1. Maven 3.5 or newer -2. Graal VM 1.0.0-rc14 or newer as JAVA_HOME, `$JAVA_HOME/bin/native-image` must exist -3. Docker 17 or newer to build and run docker images -4. Kubernetes minikube v0.24 or newer to deploy to Kubernetes (or access to a K8s 1.7.4 or newer cluster) -5. Kubectl 1.7.4 or newer to deploy to Kubernetes - -Verify prerequisites -``` -java -version -mvn --version -docker --version -minikube version -kubectl version --short -``` - -## Build and run - -### Build application JAR -``` -mvn package -``` -### Start the application using Graal VM -``` -mvn exec:exec -``` -### Build Docker Image -``` -mvn package -Pnative-image-docker -``` -### Start Docker container with the application using Graal VM -``` -docker run -d --rm --name helidon-native -p 8080:8080 helidon/example-graal:1.0.3-SNAPSHOT -``` - -## Exercise the application - -``` -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 health and metrics - -``` -curl -s -X GET http://localhost:8080/health -{"outcome":"UP",... -. . . - -# 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":... -. . . - -``` diff --git a/examples/quickstarts/helidon-quickstart-graalvm/pom.xml b/examples/quickstarts/helidon-quickstart-graalvm/pom.xml deleted file mode 100644 index 1f229306a..000000000 --- a/examples/quickstarts/helidon-quickstart-graalvm/pom.xml +++ /dev/null @@ -1,271 +0,0 @@ - - - - 4.0.0 - - io.helidon.examples - quickstart-graalvm - 1.0.3-SNAPSHOT - jar - ${project.artifactId} - - - - ${java.home}/bin/native-image - 1.0.2 - 1.0.0-rc14 - 1.4.10 - io.helidon.examples.quickstart.graalvm.Main - 8 - ${maven.compiler.source} - libs - ${project.build.directory}/${libs.classpath.prefix} - UTF-8 - UTF-8 - -Dfile.encoding=UTF-8 - - - - - - io.helidon - helidon-bom - ${helidon.version} - pom - import - - - org.graalvm.sdk - graal-sdk - ${graalvm.version} - - - com.oracle.substratevm - svm - ${graalvm.version} - - - org.junit.jupiter - junit-jupiter-api - 5.1.0 - - - org.junit.jupiter - junit-jupiter-engine - 5.1.0 - - - - - - - io.helidon.bundles - helidon-bundles-webserver - - - io.helidon.config - helidon-config-yaml - - - io.helidon.health - helidon-health - - - io.helidon.health - helidon-health-checks - - - io.helidon.metrics - helidon-metrics - - - io.helidon.integrations.graal - helidon-graal-native-image-extension - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - - - ${project.artifactId} - - - - src/main/resources - true - - - src/main/docker - ${project.build.directory} - true - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.19.1 - - - org.junit.platform - junit-platform-surefire-provider - 1.1.0 - - - - - org.codehaus.mojo - exec-maven-plugin - 1.6.0 - - java - - -classpath - - ${main.class} - - - - - org.apache.maven.plugins - maven-dependency-plugin - 3.1.1 - - - com.spotify - dockerfile-maven-plugin - ${dockerfile.plugin.version} - - - - - - - - - native-image-exec - - - ${native.image} - - - - - - org.codehaus.mojo - exec-maven-plugin - - - build-native-image - - exec - - - ${native.image} - - -H:Name=${basedir}/target/${native.name} - -H:IncludeResources=${native.resources} - - -H:+ReportExceptionStackTraces - - --no-server - -classpath - - ${main.class} - - - - - run-native-image - - exec - - - ${basedir}/target/${native.name} - - - - - - - - - - native-image-docker - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${copied.libs.dir} - false - false - true - true - runtime - test - - - - - - com.spotify - dockerfile-maven-plugin - - - default - - build - - - - - - - ${project.build.directory} - helidon/example-graal - ${project.version} - - - - - - - - - diff --git a/examples/quickstarts/helidon-quickstart-graalvm/src/main/docker/Dockerfile b/examples/quickstarts/helidon-quickstart-graalvm/src/main/docker/Dockerfile deleted file mode 100644 index b4a5a0f4a..000000000 --- a/examples/quickstarts/helidon-quickstart-graalvm/src/main/docker/Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -# -# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -FROM helidon/java-native:0.1.13 as build-native-image - -WORKDIR /helidon - -ADD *.jar target/ -ADD ${libs.classpath.prefix}/*.jar target/ - -RUN echo "$GRAALVM_HOME/bin/native-image -H:Name=helidon-native -H:IncludeResources='application.yaml|logging.properties' -H:+ReportExceptionStackTraces -classpath target/* ${main.class}" -RUN $GRAALVM_HOME/bin/native-image \ - --static \ - -H:Name=helidon-native \ - -H:IncludeResources='application.yaml|logging.properties' \ - --no-server \ - -H:+ReportExceptionStackTraces \ - -classpath "target/*" \ - ${main.class} - -# Now we should have a native image built, let us create the image -FROM scratch -WORKDIR /helidon -COPY --from=build-native-image /helidon/helidon-native helidon-native - -ENTRYPOINT ["./helidon-native"] - -EXPOSE 8080 diff --git a/examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/GreetService.java b/examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/GreetService.java deleted file mode 100644 index 58c5fd0b1..000000000 --- a/examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/GreetService.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.examples.quickstart.graalvm; - -import java.util.Collections; - -import javax.json.Json; -import javax.json.JsonBuilderFactory; -import javax.json.JsonObject; - -import io.helidon.common.http.Http; -import io.helidon.config.Config; -import io.helidon.webserver.Routing; -import io.helidon.webserver.ServerRequest; -import io.helidon.webserver.ServerResponse; -import io.helidon.webserver.Service; - -/** - * A simple service to greet you. Examples: - * - * Get default greeting message: - * curl -X GET http://localhost:8080/greet - * - * Get greeting message for Joe: - * curl -X GET http://localhost:8080/greet/Joe - * - * Change greeting - * curl -X PUT -H "Content-Type: application/json" -d '{"greeting" : "Howdy"}' http://localhost:8080/greet/greeting - * - * The message is returned as a JSON object - */ - -public class GreetService implements Service { - - /** - * The config value for the key {@code greeting}. - */ - private String greeting; - - private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap()); - - GreetService(Config config) { - this.greeting = config.get("app.greeting").asString().orElse("Ciao"); - } - - /** - * A service registers itself by updating the routine rules. - * @param rules the routing rules. - */ - @Override - public void update(Routing.Rules rules) { - rules - .get("/", this::getDefaultMessageHandler) - .get("/{name}", this::getMessageHandler) - .put("/greeting", this::updateGreetingHandler); - } - - /** - * Return a wordly greeting message. - * @param request the server request - * @param response the server response - */ - private void getDefaultMessageHandler(ServerRequest request, - ServerResponse response) { - sendResponse(response, "World"); - } - - /** - * Return a greeting message using the name that was provided. - * @param request the server request - * @param response the server response - */ - private void getMessageHandler(ServerRequest request, - ServerResponse response) { - String name = request.path().param("name"); - sendResponse(response, name); - } - - private void sendResponse(ServerResponse response, String name) { - String msg = String.format("%s %s!", greeting, name); - - JsonObject returnObject = JSON.createObjectBuilder() - .add("message", msg) - .build(); - response.send(returnObject); - } - - private void updateGreetingFromJson(JsonObject jo, ServerResponse response) { - - if (!jo.containsKey("greeting")) { - JsonObject jsonErrorObject = JSON.createObjectBuilder() - .add("error", "No greeting provided") - .build(); - response.status(Http.Status.BAD_REQUEST_400) - .send(jsonErrorObject); - return; - } - - greeting = jo.getString("greeting"); - response.status(Http.Status.NO_CONTENT_204).send(); - } - - /** - * Set the greeting to use in future messages. - * @param request the server request - * @param response the server response - */ - private void updateGreetingHandler(ServerRequest request, - ServerResponse response) { - request.content().as(JsonObject.class).thenAccept(jo -> updateGreetingFromJson(jo, response)); - } - -} diff --git a/examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/Main.java b/examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/Main.java deleted file mode 100644 index 60849d1ca..000000000 --- a/examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/Main.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.examples.quickstart.graalvm; - -import java.io.IOException; -import java.util.logging.LogManager; - -import io.helidon.config.Config; -import io.helidon.health.HealthSupport; -import io.helidon.health.checks.HealthChecks; -import io.helidon.media.jsonp.server.JsonSupport; -import io.helidon.metrics.MetricsSupport; -import io.helidon.webserver.Routing; -import io.helidon.webserver.ServerConfiguration; -import io.helidon.webserver.WebServer; - -/** - * Simple Hello World rest application. - */ -public final class Main { - - /** - * Cannot be instantiated. - */ - private Main() { } - - /** - * Application main entry point. - * @param args command line arguments. - * @throws IOException if there are problems reading logging properties - */ - public static void main(final String[] args) throws IOException { - startServer(); - } - - /** - * Start the server. - * @return the created {@link WebServer} instance - * @throws IOException if there are problems reading logging properties - */ - static WebServer startServer() throws IOException { - - // load logging configuration - LogManager.getLogManager().readConfiguration( - Main.class.getResourceAsStream("/logging.properties")); - - // By default this will pick up application.yaml from the classpath - Config config = Config.create(); - - // Get webserver config from the "server" section of application.yaml - ServerConfiguration serverConfig = - ServerConfiguration.create(config.get("server")); - - WebServer server = WebServer.create(serverConfig, createRouting(config)); - - // Try to start the server. If successful, print some info and arrange to - // print a message at shutdown. If unsuccessful, print the exception. - server.start() - .thenAccept(ws -> { - System.out.println( - "WEB server is up! http://localhost:" + ws.port() + "/greet"); - ws.whenShutdown().thenRun(() - -> System.out.println("WEB server is DOWN. Good bye!")); - }) - .exceptionally(t -> { - System.err.println("Startup failed: " + t.getMessage()); - t.printStackTrace(System.err); - return null; - }); - - // Server threads are not daemon. No need to block. Just react. - - return server; - } - - /** - * Creates new {@link Routing}. - * - * @return routing configured with JSON support, a health check, and a service - * @param config configuration of this server - */ - private static Routing createRouting(Config config) { - - MetricsSupport metrics = MetricsSupport.create(); - GreetService greetService = new GreetService(config); - HealthSupport health = HealthSupport.builder() - .add(HealthChecks.healthChecks()) // Adds a convenient set of checks - .build(); - - return Routing.builder() - .register(JsonSupport.create()) - .register(health) // Health at "/health" - .register(metrics) // Metrics at "/metrics" - .register("/greet", greetService) - .build(); - } - -} diff --git a/examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/package-info.java b/examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/package-info.java deleted file mode 100644 index 3358c0623..000000000 --- a/examples/quickstarts/helidon-quickstart-graalvm/src/main/java/io/helidon/examples/quickstart/graalvm/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Quickstart demo application - *

- * Start with {@link io.helidon.examples.quickstart.se.Main} class. - * - * @see io.helidon.examples.quickstart.se.Main - */ -package io.helidon.examples.quickstart.graalvm; diff --git a/examples/quickstarts/helidon-quickstart-graalvm/src/main/resources/logging.properties b/examples/quickstarts/helidon-quickstart-graalvm/src/main/resources/logging.properties deleted file mode 100644 index 2c3a8ed5a..000000000 --- a/examples/quickstarts/helidon-quickstart-graalvm/src/main/resources/logging.properties +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Example Logging Configuration File -# For more information see $JAVA_HOME/jre/lib/logging.properties - -# Send messages to the console -handlers=java.util.logging.ConsoleHandler - -# Global default logging level. Can be overriden by specific handlers and loggers -.level=INFO - -# Helidon Web Server has a custom log formatter that extends SimpleFormatter. -# It replaces "!thread!" with the current thread name -java.util.logging.ConsoleHandler.level=INFO -java.util.logging.ConsoleHandler.formatter=io.helidon.webserver.WebServerLogFormatter -java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS %4$s %3$s !thread!: %5$s%6$s%n - -#Component specific log levels -#io.helidon.webserver.level=INFO -#io.helidon.config.level=INFO -#io.helidon.security.level=INFO -#io.helidon.common.level=INFO -#io.netty.level=INFO diff --git a/examples/quickstarts/helidon-quickstart-graalvm/src/test/java/io/helidon/examples/quickstart/graalvm/MainTest.java b/examples/quickstarts/helidon-quickstart-graalvm/src/test/java/io/helidon/examples/quickstart/graalvm/MainTest.java deleted file mode 100644 index c8335f2d7..000000000 --- a/examples/quickstarts/helidon-quickstart-graalvm/src/test/java/io/helidon/examples/quickstart/graalvm/MainTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.helidon.examples.quickstart.graalvm; - -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Collections; -import java.util.concurrent.TimeUnit; -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonReader; -import javax.json.JsonReaderFactory; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import io.helidon.webserver.WebServer; - -public class MainTest { - - private static WebServer webServer; - private static final JsonReaderFactory JSON = Json.createReaderFactory(Collections.emptyMap()); - - @BeforeAll - public static void startTheServer() throws Exception { - webServer = Main.startServer(); - - long timeout = 2000; // 2 seconds should be enough to start the server - long now = System.currentTimeMillis(); - - while (!webServer.isRunning()) { - Thread.sleep(100); - if ((System.currentTimeMillis() - now) > timeout) { - Assertions.fail("Failed to start webserver"); - } - } - } - - @AfterAll - public static void stopServer() throws Exception { - if (webServer != null) { - webServer.shutdown() - .toCompletableFuture() - .get(10, TimeUnit.SECONDS); - } - } - - @Test - public void testHelloWorld() throws Exception { - HttpURLConnection conn; - - conn = getURLConnection("GET","/greet"); - Assertions.assertEquals(200, conn.getResponseCode(), "HTTP response1"); - JsonReader jsonReader = JSON.createReader(conn.getInputStream()); - JsonObject jsonObject = jsonReader.readObject(); - Assertions.assertEquals("Hello World!", jsonObject.getString("message"), - "default message"); - - conn = getURLConnection("GET", "/greet/Joe"); - Assertions.assertEquals(200, conn.getResponseCode(), "HTTP response2"); - jsonReader = JSON.createReader(conn.getInputStream()); - jsonObject = jsonReader.readObject(); - Assertions.assertEquals("Hello Joe!", jsonObject.getString("message"), - "hello Joe message"); - - conn = getURLConnection("PUT", "/greet/greeting"); - conn.setRequestProperty("Content-Type", "application/json"); - conn.setDoOutput(true); - OutputStream os = conn.getOutputStream(); - os.write("{\"greeting\" : \"Hola\"}".getBytes()); - os.close(); - Assertions.assertEquals(204, conn.getResponseCode(), "HTTP response3"); - - conn = getURLConnection("GET", "/greet/Jose"); - Assertions.assertEquals(200, conn.getResponseCode(), "HTTP response4"); - jsonReader = JSON.createReader(conn.getInputStream()); - jsonObject = jsonReader.readObject(); - Assertions.assertEquals("Hola Jose!", jsonObject.getString("message"), - "hola Jose message"); - - conn = getURLConnection("GET", "/health"); - Assertions.assertEquals(200, conn.getResponseCode(), "HTTP response2"); - - conn = getURLConnection("GET", "/metrics"); - Assertions.assertEquals(200, conn.getResponseCode(), "HTTP response2"); - } - - private HttpURLConnection getURLConnection(String method, String path) throws Exception { - URL url = new URL("http://localhost:" + webServer.port() + path); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod(method); - conn.setRequestProperty("Accept", "application/json"); - System.out.println("Connecting: " + method + " " + url); - return conn; - } -} diff --git a/examples/quickstarts/helidon-quickstart-mp/.dockerignore b/examples/quickstarts/helidon-quickstart-mp/.dockerignore new file mode 100644 index 000000000..c8b241f22 --- /dev/null +++ b/examples/quickstarts/helidon-quickstart-mp/.dockerignore @@ -0,0 +1 @@ +target/* \ No newline at end of file diff --git a/examples/quickstarts/helidon-quickstart-mp/.gitignore b/examples/quickstarts/helidon-quickstart-mp/.gitignore new file mode 100644 index 000000000..594f3abf6 --- /dev/null +++ b/examples/quickstarts/helidon-quickstart-mp/.gitignore @@ -0,0 +1,16 @@ +hs_err_pid* +target/ +.DS_Store +.idea/ +*.iws +*.ipr +*.iml +atlassian-ide-plugin.xml +nbactions.xml +nb-configuration.xml +.settings +.settings/ +.project +.classpath +*.swp +*~ diff --git a/examples/quickstarts/helidon-quickstart-mp/Dockerfile b/examples/quickstarts/helidon-quickstart-mp/Dockerfile new file mode 100644 index 000000000..cde7e345d --- /dev/null +++ b/examples/quickstarts/helidon-quickstart-mp/Dockerfile @@ -0,0 +1,44 @@ +# +# Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# 1st stage, build the app +FROM maven:3.5.4-jdk-9 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 -DskipTests + +# 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 openjdk:8-jre-slim +WORKDIR /helidon + +# Copy the binary built in the 1st stage +COPY --from=build /helidon/target/helidon-quickstart-mp.jar ./ +COPY --from=build /helidon/target/libs ./libs + +CMD ["java", "-jar", "helidon-quickstart-mp.jar"] + +EXPOSE 8080 diff --git a/examples/quickstarts/helidon-quickstart-mp/README.md b/examples/quickstarts/helidon-quickstart-mp/README.md index 33fc13a9e..8d0a6fe04 100644 --- a/examples/quickstarts/helidon-quickstart-mp/README.md +++ b/examples/quickstarts/helidon-quickstart-mp/README.md @@ -1,5 +1,5 @@ -# Helidon Example: quickstart-mp +# Helidon Quickstart MP Example This example implements a simple Hello World REST service using MicroProfile @@ -30,7 +30,7 @@ mvn package ## Start the application ``` -java -jar target/quickstart-mp.jar +java -jar target/helidon-quickstart-mp.jar ``` ## Exercise the application @@ -70,13 +70,13 @@ curl -H 'Accept: application/json' -X GET http://localhost:8080/metrics ## Build the Docker Image ``` -docker build -t quickstart-mp target +docker build -t helidon-quickstart-mp . ``` ## Start the application with Docker ``` -docker run --rm -p 8080:8080 quickstart-mp:latest +docker run --rm -p 8080:8080 helidon-quickstart-mp:latest ``` Exercise the application as described above @@ -86,6 +86,6 @@ Exercise the application as described above ``` kubectl cluster-info # Verify which cluster kubectl get pods # Verify connectivity to cluster -kubectl create -f target/app.yaml # Deploy application -kubectl get service quickstart-mp # Verify deployed service +kubectl create -f app.yaml # Deploy application +kubectl get service helidon-quickstart-mp # Verify deployed service ``` diff --git a/examples/quickstarts/helidon-quickstart-se/src/main/k8s/app.yaml b/examples/quickstarts/helidon-quickstart-mp/app.yaml similarity index 75% rename from examples/quickstarts/helidon-quickstart-se/src/main/k8s/app.yaml rename to examples/quickstarts/helidon-quickstart-mp/app.yaml index 29a1257ac..58099afcf 100644 --- a/examples/quickstarts/helidon-quickstart-se/src/main/k8s/app.yaml +++ b/examples/quickstarts/helidon-quickstart-mp/app.yaml @@ -1,5 +1,5 @@ # -# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,13 +17,13 @@ kind: Service apiVersion: v1 metadata: - name: ${project.artifactId} + name: helidon-quickstart-mp labels: - app: ${project.artifactId} + app: helidon-quickstart-mp spec: type: NodePort selector: - app: ${project.artifactId} + app: helidon-quickstart-mp ports: - port: 8080 targetPort: 8080 @@ -32,18 +32,18 @@ spec: kind: Deployment apiVersion: extensions/v1beta1 metadata: - name: ${project.artifactId} + name: helidon-quickstart-mp spec: replicas: 1 template: metadata: labels: - app: ${project.artifactId} + app: helidon-quickstart-mp version: v1 spec: containers: - - name: ${project.artifactId} - image: ${project.artifactId} + - name: helidon-quickstart-mp + image: helidon-quickstart-mp imagePullPolicy: IfNotPresent ports: - containerPort: 8080 diff --git a/examples/quickstarts/helidon-quickstart-mp/build.gradle b/examples/quickstarts/helidon-quickstart-mp/build.gradle index 3a0ba0c5b..2cf1b8bdb 100644 --- a/examples/quickstarts/helidon-quickstart-mp/build.gradle +++ b/examples/quickstarts/helidon-quickstart-mp/build.gradle @@ -20,7 +20,7 @@ apply plugin: 'maven' group = 'io.helidon.examples' version = '1.0-SNAPSHOT' -description = """quickstart-mp""" +description = """helidon-quickstart-mp""" sourceCompatibility = 1.8 targetCompatibility = 1.8 diff --git a/examples/quickstarts/helidon-quickstart-mp/pom.xml b/examples/quickstarts/helidon-quickstart-mp/pom.xml index b684ec4fb..c051c3fc1 100644 --- a/examples/quickstarts/helidon-quickstart-mp/pom.xml +++ b/examples/quickstarts/helidon-quickstart-mp/pom.xml @@ -22,16 +22,14 @@ 4.0.0 io.helidon.examples - quickstart-mp + helidon-quickstart-mp 1.0.3-SNAPSHOT jar - ${project.artifactId} + Helidon Quickstart MP Example 1.0.3-SNAPSHOT - - io.helidon.examples.quickstart.mp - ${package}.Main + io.helidon.examples.quickstart.mp.Main 8 ${maven.compiler.source} libs @@ -83,6 +81,7 @@ true ${libs.classpath.prefix} ${mainClass} + false @@ -113,38 +112,6 @@ - - org.apache.maven.plugins - maven-resources-plugin - - - copy-dockerfile - process-resources - - copy-resources - - - ${project.build.directory} - - - src/main/docker - true - - Dockerfile - - - - true - src/main/k8s - - app.yaml - - - - - - - diff --git a/examples/quickstarts/helidon-quickstart-mp/settings.gradle b/examples/quickstarts/helidon-quickstart-mp/settings.gradle index 3a05897da..98d78ade3 100644 --- a/examples/quickstarts/helidon-quickstart-mp/settings.gradle +++ b/examples/quickstarts/helidon-quickstart-mp/settings.gradle @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/examples/quickstarts/helidon-quickstart-mp/src/main/docker/Dockerfile b/examples/quickstarts/helidon-quickstart-mp/src/main/docker/Dockerfile deleted file mode 100644 index 34dab669e..000000000 --- a/examples/quickstarts/helidon-quickstart-mp/src/main/docker/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -FROM openjdk:8-jre-slim - -RUN mkdir /app -COPY libs /app/libs -COPY ${project.artifactId}.jar /app - -CMD ["java", "-jar", "/app/${project.artifactId}.jar"] diff --git a/examples/quickstarts/helidon-quickstart-mp/src/main/k8s/app.yaml b/examples/quickstarts/helidon-quickstart-mp/src/main/k8s/app.yaml deleted file mode 100644 index 29a1257ac..000000000 --- a/examples/quickstarts/helidon-quickstart-mp/src/main/k8s/app.yaml +++ /dev/null @@ -1,50 +0,0 @@ -# -# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -kind: Service -apiVersion: v1 -metadata: - name: ${project.artifactId} - labels: - app: ${project.artifactId} -spec: - type: NodePort - selector: - app: ${project.artifactId} - ports: - - port: 8080 - targetPort: 8080 - name: http ---- -kind: Deployment -apiVersion: extensions/v1beta1 -metadata: - name: ${project.artifactId} -spec: - replicas: 1 - template: - metadata: - labels: - app: ${project.artifactId} - version: v1 - spec: - containers: - - name: ${project.artifactId} - image: ${project.artifactId} - imagePullPolicy: IfNotPresent - ports: - - containerPort: 8080 ---- diff --git a/examples/quickstarts/helidon-quickstart-se/.dockerignore b/examples/quickstarts/helidon-quickstart-se/.dockerignore new file mode 100644 index 000000000..c8b241f22 --- /dev/null +++ b/examples/quickstarts/helidon-quickstart-se/.dockerignore @@ -0,0 +1 @@ +target/* \ No newline at end of file diff --git a/examples/quickstarts/helidon-quickstart-se/.gitignore b/examples/quickstarts/helidon-quickstart-se/.gitignore new file mode 100644 index 000000000..241e8042d --- /dev/null +++ b/examples/quickstarts/helidon-quickstart-se/.gitignore @@ -0,0 +1,16 @@ +hs_err_pid* +target/ +.DS_Store +.idea/ +*.iws +*.ipr +*.iml +atlassian-ide-plugin.xml +nbactions.xml +nb-configuration.xml +.settings +.settings/ +.project +.classpath +*.swp +*~ \ No newline at end of file diff --git a/examples/quickstarts/helidon-quickstart-se/Dockerfile b/examples/quickstarts/helidon-quickstart-se/Dockerfile new file mode 100644 index 000000000..4c98a52c5 --- /dev/null +++ b/examples/quickstarts/helidon-quickstart-se/Dockerfile @@ -0,0 +1,45 @@ +# +# Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# 1st stage, build the app +FROM maven:3.5.4-jdk-9 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 -DskipTests + +# 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 openjdk:8-jre-slim +WORKDIR /helidon + +# Copy the binary built in the 1st stage +COPY --from=build /helidon/target/helidon-quickstart-se.jar ./ +COPY --from=build /helidon/target/libs ./libs + +CMD ["java", "-jar", "helidon-quickstart-se.jar"] + +EXPOSE 8080 \ No newline at end of file diff --git a/examples/quickstarts/helidon-quickstart-se/Dockerfile.native b/examples/quickstarts/helidon-quickstart-se/Dockerfile.native new file mode 100644 index 000000000..015fb122d --- /dev/null +++ b/examples/quickstarts/helidon-quickstart-se/Dockerfile.native @@ -0,0 +1,44 @@ +# +# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# 1st stage, build the app +FROM helidon/jdk8-graalvm-maven:1.0.0-rc13 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 -Pnative-image -Dnative.image.skip -DskipTests + +# 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-quickstart-se . + +ENTRYPOINT ["./helidon-quickstart-se"] + +EXPOSE 8080 diff --git a/examples/quickstarts/helidon-quickstart-se/README.md b/examples/quickstarts/helidon-quickstart-se/README.md index 78e65c2b2..3eb0c4d09 100644 --- a/examples/quickstarts/helidon-quickstart-se/README.md +++ b/examples/quickstarts/helidon-quickstart-se/README.md @@ -1,7 +1,7 @@ -# Helidon Example: quickstart-se +# Helidon Quickstart SE Example -This example implements a simple Hello World REST service. +This project implements a simple Hello World REST service using Helidon SE. ## Prerequisites @@ -29,7 +29,7 @@ mvn package ## Start the application ``` -java -jar target/quickstart-se.jar +java -jar target/helidon-quickstart-se.jar ``` ## Exercise the application @@ -69,13 +69,13 @@ curl -H 'Accept: application/json' -X GET http://localhost:8080/metrics ## Build the Docker Image ``` -docker build -t quickstart-se target +docker build -t helidon-quickstart-se . ``` ## Start the application with Docker ``` -docker run --rm -p 8080:8080 quickstart-se:latest +docker run --rm -p 8080:8080 helidon-quickstart-se:latest ``` Exercise the application as described above @@ -85,6 +85,54 @@ Exercise the application as described above ``` kubectl cluster-info # Verify which cluster kubectl get pods # Verify connectivity to cluster -kubectl create -f target/app.yaml # Deply application -kubectl get service quickstart-se # Get service info +kubectl create -f app.yaml # Deply application +kubectl get service helidon-quickstart-se # Get service info ``` + +## Native image with GraalVM + +GraalVM allows you to compile your programs ahead-of-time into a native + executable. See https://www.graalvm.org/docs/reference-manual/aot-compilation/ + for more information. + +You can build a native executable in 2 different ways: +* With a local installation of GraalVM +* Using Docker + +### Local build + +Download Graal VM at https://github.com/oracle/graal/releases, the version + currently supported for Helidon is `1.0.0-rc13`. + +``` +# Setup the environment +export GRAALVM_HOME=/path +# build the native executable +mvn package -Pnative-image +``` + +You can also put the Graal VM `bin` directory in your PATH, or pass + `-DgraalVMHome=/path` to the Maven command. + +See https://github.com/oracle/helidon-build-tools/tree/master/helidon-maven-plugin + for more information. + +Start the application: + +``` +./target/helidon-quickstart-se +``` + +### Multi-stage Docker build + +Build the "native" Docker Image + +``` +docker build -t helidon-quickstart-se-native -f Dockerfile.native . +``` + +Start the application: + +``` +docker run --rm -p 8080:8080 helidon-quickstart-se-native:latest +``` \ No newline at end of file diff --git a/examples/quickstarts/helidon-quickstart-graalvm/src/main/k8s/app.yaml b/examples/quickstarts/helidon-quickstart-se/app.yaml similarity index 75% rename from examples/quickstarts/helidon-quickstart-graalvm/src/main/k8s/app.yaml rename to examples/quickstarts/helidon-quickstart-se/app.yaml index 56a388e2d..7b84daac6 100644 --- a/examples/quickstarts/helidon-quickstart-graalvm/src/main/k8s/app.yaml +++ b/examples/quickstarts/helidon-quickstart-se/app.yaml @@ -1,5 +1,5 @@ # -# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,13 +17,13 @@ kind: Service apiVersion: v1 metadata: - name: ${project.artifactId} + name: helidon-quickstart-se labels: - app: ${project.artifactId} + app: helidon-quickstart-se spec: type: NodePort selector: - app: ${project.artifactId} + app: helidon-quickstart-se ports: - port: 8080 targetPort: 8080 @@ -32,18 +32,18 @@ spec: kind: Deployment apiVersion: extensions/v1beta1 metadata: - name: ${project.artifactId} + name: helidon-quickstart-se spec: replicas: 1 template: metadata: labels: - app: ${project.artifactId} + app: helidon-quickstart-se version: v1 spec: containers: - - name: ${project.artifactId} - image: ${project.artifactId} + - name: helidon-quickstart-se + image: helidon-quickstart-se imagePullPolicy: IfNotPresent ports: - containerPort: 8080 diff --git a/examples/quickstarts/helidon-quickstart-se/build.gradle b/examples/quickstarts/helidon-quickstart-se/build.gradle index 8e8d6b969..72d44e81e 100644 --- a/examples/quickstarts/helidon-quickstart-se/build.gradle +++ b/examples/quickstarts/helidon-quickstart-se/build.gradle @@ -20,7 +20,7 @@ apply plugin: 'maven' group = 'io.helidon.examples' version = '1.0-SNAPSHOT' -description = """quickstart-se""" +description = """helidon-quickstart-se""" sourceCompatibility = 1.8 targetCompatibility = 1.8 diff --git a/examples/quickstarts/helidon-quickstart-se/pom.xml b/examples/quickstarts/helidon-quickstart-se/pom.xml index 2b54084b3..acc63e6f1 100644 --- a/examples/quickstarts/helidon-quickstart-se/pom.xml +++ b/examples/quickstarts/helidon-quickstart-se/pom.xml @@ -22,16 +22,15 @@ 4.0.0 io.helidon.examples - quickstart-se + helidon-quickstart-se 1.0.3-SNAPSHOT jar - ${project.artifactId} + Helidon Quickstart SE Example 1.0.3-SNAPSHOT - - io.helidon.examples.quickstart.se - ${package}.Main + 1.0.10 + io.helidon.examples.quickstart.se.Main 8 ${maven.compiler.source} libs @@ -82,10 +81,16 @@ true ${libs.classpath.prefix} ${mainClass} + false + + io.helidon.build-tools + helidon-maven-plugin + ${helidon.plugin.version} + @@ -112,38 +117,6 @@ - - org.apache.maven.plugins - maven-resources-plugin - - - copy-dockerfile - process-resources - - copy-resources - - - ${project.build.directory} - - - true - src/main/docker - - Dockerfile - - - - true - src/main/k8s - - app.yaml - - - - - - - @@ -201,4 +174,31 @@ test + + + + native-image + + + + io.helidon.build-tools + helidon-maven-plugin + + + + native-image + + + + + + + + + io.helidon.integrations.graal + helidon-graal-native-image-extension + + + + diff --git a/examples/quickstarts/helidon-quickstart-se/settings.gradle b/examples/quickstarts/helidon-quickstart-se/settings.gradle index da6555853..106adbc95 100644 --- a/examples/quickstarts/helidon-quickstart-se/settings.gradle +++ b/examples/quickstarts/helidon-quickstart-se/settings.gradle @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,5 +14,5 @@ * limitations under the License. */ -rootProject.name = 'quickstart-se' +rootProject.name = 'helidon-quickstart-se' enableFeaturePreview("IMPROVED_POM_SUPPORT") diff --git a/examples/quickstarts/helidon-quickstart-se/src/main/docker/Dockerfile b/examples/quickstarts/helidon-quickstart-se/src/main/docker/Dockerfile deleted file mode 100644 index 34dab669e..000000000 --- a/examples/quickstarts/helidon-quickstart-se/src/main/docker/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -FROM openjdk:8-jre-slim - -RUN mkdir /app -COPY libs /app/libs -COPY ${project.artifactId}.jar /app - -CMD ["java", "-jar", "/app/${project.artifactId}.jar"] diff --git a/examples/quickstarts/helidon-quickstart-se/src/main/resources/META-INF/native-image/helidon-example-reflection-config.json b/examples/quickstarts/helidon-quickstart-se/src/main/resources/META-INF/native-image/helidon-example-reflection-config.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/examples/quickstarts/helidon-quickstart-se/src/main/resources/META-INF/native-image/helidon-example-reflection-config.json @@ -0,0 +1 @@ +[] diff --git a/examples/quickstarts/helidon-quickstart-graalvm/src/main/resources/application.yaml b/examples/quickstarts/helidon-quickstart-se/src/main/resources/META-INF/native-image/native-image.properties similarity index 81% rename from examples/quickstarts/helidon-quickstart-graalvm/src/main/resources/application.yaml rename to examples/quickstarts/helidon-quickstart-se/src/main/resources/META-INF/native-image/native-image.properties index ee2ec5668..5423eda71 100644 --- a/examples/quickstarts/helidon-quickstart-graalvm/src/main/resources/application.yaml +++ b/examples/quickstarts/helidon-quickstart-se/src/main/resources/META-INF/native-image/native-image.properties @@ -14,13 +14,4 @@ # limitations under the License. # -app: - greeting: "Hello" - -server: - port: 8080 - host: 0.0.0.0 -# experimental: -# http2: -# enable: true -# max-content-length: 16384 \ No newline at end of file +Args=-H:ReflectionConfigurationResources=${.}/helidon-example-reflection-config.json diff --git a/examples/quickstarts/pom.xml b/examples/quickstarts/pom.xml index af2cfaa1c..68b742d22 100644 --- a/examples/quickstarts/pom.xml +++ b/examples/quickstarts/pom.xml @@ -15,10 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. ---> - - +--> 4.0.0 io.helidon.examples @@ -40,7 +37,5 @@ helidon-quickstart-se helidon-quickstart-mp - helidon-quickstart-graalvm - - + \ No newline at end of file diff --git a/health/health-checks/src/main/java/io/helidon/health/checks/HealthChecks.java b/health/health-checks/src/main/java/io/helidon/health/checks/HealthChecks.java index 98220a797..040b54417 100644 --- a/health/health-checks/src/main/java/io/helidon/health/checks/HealthChecks.java +++ b/health/health-checks/src/main/java/io/helidon/health/checks/HealthChecks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import org.eclipse.microprofile.health.HealthCheck; * @see #healthChecks() */ public final class HealthChecks { + private static final boolean IS_GRAAL_VM = Boolean.getBoolean("com.oracle.graalvm.isaot"); private HealthChecks() { } @@ -67,10 +68,17 @@ public final class HealthChecks { * @see io.helidon.health.HealthSupport.Builder#add(org.eclipse.microprofile.health.HealthCheck...) */ public static HealthCheck[] healthChecks() { - return new HealthCheck[] { - deadlockCheck(), - diskSpaceCheck(), - heapMemoryCheck() - }; + if (IS_GRAAL_VM) { + return new HealthCheck[] { + //diskSpaceCheck(), // - bug + heapMemoryCheck() + }; + } else { + return new HealthCheck[] { + deadlockCheck(), + diskSpaceCheck(), + heapMemoryCheck() + }; + } } } diff --git a/integrations/graal/native-image-extension/src/main/java/io/helidon/integrations/graal/nativeimage/extension/NettySubstitutions.java b/integrations/graal/native-image-extension/src/main/java/io/helidon/integrations/graal/nativeimage/extension/NettySubstitutions.java index 86a266396..d1cc95491 100644 --- a/integrations/graal/native-image-extension/src/main/java/io/helidon/integrations/graal/nativeimage/extension/NettySubstitutions.java +++ b/integrations/graal/native-image-extension/src/main/java/io/helidon/integrations/graal/nativeimage/extension/NettySubstitutions.java @@ -28,6 +28,20 @@ import io.netty.util.internal.logging.JdkLoggerFactory; // supressing checkstyle issues, as this class cannot follow usual naming rules @SuppressWarnings({"StaticVariableName", "VisibilityModifier"}) public final class NettySubstitutions { + @TargetClass(className = "io.netty.util.internal.PlatformDependent") + static final class PlatformDependentSvmExtension { + /** + * The class PlatformDependent caches the byte array base offset by reading the + * field from PlatformDependent0. The automatic recomputation of Substrate VM + * correctly recomputes the field in PlatformDependent0, but since the caching + * in PlatformDependent happens during image building, the non-recomputed value + * is cached. + */ + @Alias + @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.ArrayBaseOffset, declClass = byte[].class) + private static long BYTE_ARRAY_BASE_OFFSET; + } + @TargetClass(className = "io.netty.util.internal.PlatformDependent0") static final class PlatformDependent0SvmExtension { @Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FieldOffset, declClassName = "java.nio.Buffer", name = diff --git a/pom.xml b/pom.xml index d2cc270b0..7011db47b 100644 --- a/pom.xml +++ b/pom.xml @@ -177,6 +177,7 @@ 2.19.1 1.48 1.6 + 1.0.10 0.7.9 1.0.5 3.0.2 @@ -189,7 +190,6 @@ 2.7 3.0.0 3.7.1 - 1.0.9 3.0.1 3.1.3.1 1.0.0 @@ -429,7 +429,7 @@ io.helidon.build-tools sitegen-maven-plugin - ${version.plugin.sitegen} + ${version.plugin.helidon-build-tools} src/main/docs/sitegen.yaml src/main/docs @@ -482,6 +482,13 @@ org.sonatype.plugins nexus-staging-maven-plugin ${version.plugin.nexus-staging} + + ossrh + https://oss.sonatype.org/ + true + true + ${maven.deploy.skip} + @@ -535,18 +542,6 @@ /etc/checkstyle-suppressions.xml - - org.sonatype.plugins - nexus-staging-maven-plugin - true - - ossrh - https://oss.sonatype.org/ - true - true - ${maven.deploy.skip} - - io.helidon.build-tools sitegen-maven-plugin @@ -1425,6 +1420,11 @@ + + org.sonatype.plugins + nexus-staging-maven-plugin + true + org.apache.maven.plugins maven-enforcer-plugin @@ -1520,11 +1520,11 @@ - ossrh-releases + staging - ossrh-releases - https://oss.sonatype.org/content/repositories/releases/ + ossrh-staging + https://oss.sonatype.org/content/repositories/staging/ false @@ -1532,8 +1532,8 @@ - ossrh-releases - https://oss.sonatype.org/content/repositories/releases/ + ossrh-staging + https://oss.sonatype.org/content/repositories/staging/ false