diff --git a/.github/workflows/build-push-container-images.yml b/.github/workflows/build-push-container-images.yml index a29382630..3294b1ed9 100644 --- a/.github/workflows/build-push-container-images.yml +++ b/.github/workflows/build-push-container-images.yml @@ -33,6 +33,7 @@ jobs: - rest-fights - rest-heroes - rest-villains + - ui-super-heroes arch: - amd64 - arm64 @@ -118,6 +119,7 @@ jobs: - rest-fights - rest-heroes - rest-villains + - ui-super-heroes arch: - amd64 - arm64 @@ -187,71 +189,11 @@ jobs: with: image: "${{ env.IMAGE_BASE_NAME }}/${{ matrix.project }}:${{ env.CONTAINER_TAG }}-${{ matrix.arch }}" - build-ui-images: - if: ((github.event_name == 'workflow_dispatch') || ((github.event_name == 'workflow_run') && ((github.event.workflow_run.event == 'push') || (github.event.workflow_run.event == 'workflow_dispatch')) && (github.event.workflow_run.conclusion == 'success'))) && ((github.repository == 'quarkusio/quarkus-super-heroes') && ((github.event.workflow_run.head_branch == 'main'))) - runs-on: ubuntu-latest - strategy: - matrix: - arch: - - amd64 - - arm64 - steps: - - name: Calculate Branch (workflow_run event) - if: github.event_name == 'workflow_run' - run: | - echo "REF=${{ github.event.workflow_run.head_commit.id }}" >> $GITHUB_ENV - echo "BRANCH=${{ github.event.workflow_run.head_branch }}" >> $GITHUB_ENV - - - name: Calculate Branch (workflow_dispatch event) - if: github.event_name == 'workflow_dispatch' - run: | - echo "REF=${{ github.sha }}" >> $GITHUB_ENV - echo "BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV - - - name: Checkout from ${{ env.REF }} - uses: actions/checkout@v3 - with: - ref: ${{ env.REF }} - - - name: Set up QEMU - if: matrix.arch == 'arm64' - uses: docker/setup-qemu-action@v2 - with: - platforms: arm64 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - with: - install: true - - - name: Create container tag (main branch) - if: env.BRANCH == 'main' - run: echo "CONTAINER_TAG=${{ env.LATEST_IMAGE_TAG }}-${{ matrix.arch }}" >> $GITHUB_ENV - - - name: Create container tag (other branch) - if: env.BRANCH != 'main' - run: echo "CONTAINER_TAG=${{ env.LATEST_IMAGE_TAG }}-${{ env.BRANCH }}-${{ matrix.arch }}" >> $GITHUB_ENV - - - name: Build UI image (${{ matrix.arch }}) - uses: docker/build-push-action@v4 - with: - context: ui-super-heroes - platforms: linux/${{ matrix.arch }} - push: false - load: true - tags: ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.CONTAINER_TAG }} - - - name: Save UI image (${{ matrix.arch }}) - uses: ishworkh/docker-image-artifact-upload@v1 - with: - image: "${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.CONTAINER_TAG }}" - push-app-images: if: ((github.event_name == 'workflow_dispatch') || ((github.event_name == 'workflow_run') && ((github.event.workflow_run.event == 'push') || (github.event.workflow_run.event == 'workflow_dispatch')) && (github.event.workflow_run.conclusion == 'success'))) && ((github.repository == 'quarkusio/quarkus-super-heroes') && ((github.event.workflow_run.head_branch == 'main'))) needs: - build-jvm-images - build-native-images - - build-ui-images runs-on: ubuntu-latest strategy: matrix: @@ -265,6 +207,7 @@ jobs: - rest-fights - rest-heroes - rest-villains + - ui-super-heroes arch: - amd64 - arm64 @@ -350,77 +293,6 @@ jobs: working-directory: ${{ matrix.project }} run: "docker push -a ${{ env.IMAGE_BASE_NAME }}/${{ matrix.project }}" - push-ui-images: - if: ((github.event_name == 'workflow_dispatch') || ((github.event_name == 'workflow_run') && ((github.event.workflow_run.event == 'push') || (github.event.workflow_run.event == 'workflow_dispatch')) && (github.event.workflow_run.conclusion == 'success'))) && ((github.repository == 'quarkusio/quarkus-super-heroes') && ((github.event.workflow_run.head_branch == 'main'))) - needs: - - build-jvm-images - - build-native-images - - build-ui-images - runs-on: ubuntu-latest - strategy: - matrix: - arch: - - amd64 - - arm64 - steps: - - name: Calculate Branch (workflow_run event) - if: github.event_name == 'workflow_run' - run: | - echo "REF=${{ github.event.workflow_run.head_commit.id }}" >> $GITHUB_ENV - echo "BRANCH=${{ github.event.workflow_run.head_branch }}" >> $GITHUB_ENV - - - name: Calculate Branch (workflow_dispatch event) - if: github.event_name == 'workflow_dispatch' - run: | - echo "REF=${{ github.sha }}" >> $GITHUB_ENV - echo "BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV - - - name: Checkout from ${{ env.REF }} - uses: actions/checkout@v3 - with: - ref: ${{ env.REF }} - - - name: Setup Java - uses: actions/setup-java@v3 - with: - java-version: 17 - distribution: temurin - cache: maven - - - name: Create env vars (main branch) - if: env.BRANCH == 'main' - working-directory: ui-super-heroes - run: | - echo "CONTAINER_TAG=${{ env.LATEST_IMAGE_TAG }}-${{ matrix.arch }}" >> $GITHUB_ENV && - echo "APP_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV - - - name: Create env vars (other branch) - if: env.BRANCH != 'main' - working-directory: ui-super-heroes - run: | - echo "CONTAINER_TAG=${{ env.LATEST_IMAGE_TAG }}-${{ env.BRANCH }}-${{ matrix.arch }}" >> $GITHUB_ENV && - echo "APP_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)-${{ env.BRANCH }}" >> $GITHUB_ENV - - - name: Get Saved UI Image (${{ matrix.arch }}) - uses: ishworkh/docker-image-artifact-download@v1 - with: - image: "${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.CONTAINER_TAG }}" - - - name: Login to quay - uses: docker/login-action@v2 - with: - registry: quay.io - username: ${{ secrets.QUAY_REPO_USERNAME }} - password: ${{ secrets.QUAY_REPO_TOKEN }} - - - name: Tag UI image (${{ matrix.arch }}) - working-directory: ui-super-heroes - run: docker tag ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.CONTAINER_TAG }} ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.APP_VERSION }}-${{ matrix.arch }} - - - name: Push UI image (${{ matrix.arch }}) - working-directory: ui-super-heroes - run: "docker push -a ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes" - create-app-multiarch-manifests: if: ((github.event_name == 'workflow_dispatch') || ((github.event_name == 'workflow_run') && ((github.event.workflow_run.event == 'push') || (github.event.workflow_run.event == 'workflow_dispatch')) && (github.event.workflow_run.conclusion == 'success'))) && ((github.repository == 'quarkusio/quarkus-super-heroes') && ((github.event.workflow_run.head_branch == 'main'))) needs: push-app-images @@ -437,6 +309,7 @@ jobs: - rest-fights - rest-heroes - rest-villains + - ui-super-heroes name: Create app multiarch manifests (${{ matrix.project }}-${{ matrix.kind }}java${{ matrix.java }}) steps: - name: Calculate Branch (workflow_run event) @@ -518,73 +391,10 @@ jobs: -a ${{ env.IMAGE_BASE_NAME }}/${{ matrix.project }}:${{ env.ADDITIONAL_TAG }}-arm64 docker manifest push ${{ env.IMAGE_BASE_NAME }}/${{ matrix.project }}:${{ env.ADDITIONAL_TAG }} - create-ui-multiarch-manifests: - if: ((github.event_name == 'workflow_dispatch') || ((github.event_name == 'workflow_run') && ((github.event.workflow_run.event == 'push') || (github.event.workflow_run.event == 'workflow_dispatch')) && (github.event.workflow_run.conclusion == 'success'))) && ((github.repository == 'quarkusio/quarkus-super-heroes') && ((github.event.workflow_run.head_branch == 'main'))) - needs: push-ui-images - runs-on: ubuntu-latest - steps: - - name: Calculate Branch (workflow_run event) - if: github.event_name == 'workflow_run' - run: | - echo "REF=${{ github.event.workflow_run.head_commit.id }}" >> $GITHUB_ENV - echo "BRANCH=${{ github.event.workflow_run.head_branch }}" >> $GITHUB_ENV - - - name: Calculate Branch (workflow_dispatch event) - if: github.event_name == 'workflow_dispatch' - run: | - echo "REF=${{ github.sha }}" >> $GITHUB_ENV - echo "BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV - - - name: Checkout from ${{ env.REF }} - uses: actions/checkout@v3 - with: - ref: ${{ env.REF }} - - - name: Setup Java - uses: actions/setup-java@v3 - with: - java-version: 17 - distribution: temurin - cache: maven - - - name: Create env vars (main branch) - if: env.BRANCH == 'main' - working-directory: ui-super-heroes - run: | - echo "CONTAINER_TAG=${{ env.LATEST_IMAGE_TAG }}" >> $GITHUB_ENV && - echo "APP_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV - - - name: Create env vars (other branch) - if: env.BRANCH != 'main' - working-directory: ui-super-heroes - run: | - echo "CONTAINER_TAG=${{ env.LATEST_IMAGE_TAG }}-${{ env.BRANCH }}" >> $GITHUB_ENV && - echo "APP_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)-${{ env.BRANCH }}" >> $GITHUB_ENV - - - name: Login to quay - uses: docker/login-action@v2 - with: - registry: quay.io - username: ${{ secrets.QUAY_REPO_USERNAME }} - password: ${{ secrets.QUAY_REPO_TOKEN }} - - - name: Create and push multi-arch manifests - shell: bash - run: | - docker manifest create ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.CONTAINER_TAG }} \ - -a ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.CONTAINER_TAG }}-amd64 \ - -a ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.CONTAINER_TAG }}-arm64 - docker manifest push ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.CONTAINER_TAG }} - docker manifest create ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.APP_VERSION }} \ - -a ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.APP_VERSION }}-amd64 \ - -a ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.APP_VERSION }}-arm64 - docker manifest push ${{ env.IMAGE_BASE_NAME }}/ui-super-heroes:${{ env.APP_VERSION }} - deploy-resources-workflow-run: if: ((github.event_name == 'workflow_run') && ((github.event.workflow_run.event == 'push') || (github.event.workflow_run.event == 'workflow_dispatch')) && (github.event.workflow_run.conclusion == 'success') && (github.repository == 'quarkusio/quarkus-super-heroes')) && ((github.event.workflow_run.head_branch == 'main')) needs: - create-app-multiarch-manifests - - create-ui-multiarch-manifests uses: quarkusio/quarkus-super-heroes/.github/workflows/create-deploy-resources.yml@main secrets: inherit with: @@ -595,7 +405,6 @@ jobs: if: ((github.event_name == 'workflow_dispatch') && (github.repository == 'quarkusio/quarkus-super-heroes')) && ((github.ref_name == 'main')) needs: - create-app-multiarch-manifests - - create-ui-multiarch-manifests uses: quarkusio/quarkus-super-heroes/.github/workflows/create-deploy-resources.yml@main secrets: inherit with: diff --git a/.github/workflows/build-push-ui-images.yml b/.github/workflows/build-push-ui-images.yml index 3124b4c3e..4af169415 100644 --- a/.github/workflows/build-push-ui-images.yml +++ b/.github/workflows/build-push-ui-images.yml @@ -1,4 +1,5 @@ name: Build and push UI image +# Note: this is not used on main, but needs to be on the default branch so it can be manually triggered env: LATEST_IMAGE_TAG: "latest" diff --git a/.github/workflows/simple-build-test.yml b/.github/workflows/simple-build-test.yml index 92661e733..6a0625629 100644 --- a/.github/workflows/simple-build-test.yml +++ b/.github/workflows/simple-build-test.yml @@ -57,6 +57,7 @@ jobs: - rest-fights - rest-heroes - rest-villains + - ui-super-heroes name: "build-test-${{ matrix.project }}-${{ matrix.java }}" steps: - uses: actions/checkout@v3 @@ -88,6 +89,7 @@ jobs: - rest-fights - rest-heroes - rest-villains + - ui-super-heroes name: "native-build-test-${{ matrix.project }}" steps: - uses: actions/checkout@v3 diff --git a/README.md b/README.md index dfb8fc20a..321da2be0 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ The base JVM version for all the applications is Java 17. - [Super Hero Battle UI](ui-super-heroes) - An Angular application to pick up a random superhero, a random supervillain, and makes them fight. + - Served with [Quarkus Quinoa](https://quarkiverse.github.io/quarkiverse-docs/quarkus-quinoa/dev/index.html) - [Villain REST API](rest-villains) - A classical HTTP microservice exposing CRUD operations on Villains, stored in a PostgreSQL database. - Implemented with blocking endpoints using [RESTEasy Reactive](https://quarkus.io/guides/resteasy-reactive) and [Quarkus Hibernate ORM with Panache's active record pattern](https://quarkus.io/guides/hibernate-orm-panache). diff --git a/deploy/docker-compose/native.yml b/deploy/docker-compose/native.yml index 6be7eabcb..c285e811c 100644 --- a/deploy/docker-compose/native.yml +++ b/deploy/docker-compose/native.yml @@ -178,8 +178,8 @@ services: memory: 256M cpus: '0.5' - ui-super-heroes: - image: quay.io/quarkus-super-heroes/ui-super-heroes:latest + ui-super-heroes-native: + image: quay.io/quarkus-super-heroes/ui-super-heroes:native-latest container_name: ui-super-heroes ports: - "8080:8080" diff --git a/deploy/k8s/java17-knative.yml b/deploy/k8s/java17-knative.yml index 6ff4a2df3..56ac163c9 100644 --- a/deploy/k8s/java17-knative.yml +++ b/deploy/k8s/java17-knative.yml @@ -1032,7 +1032,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes app.kubernetes.io/name: ui-super-heroes name: ui-super-heroes @@ -1050,7 +1050,7 @@ spec: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes app.kubernetes.io/name: ui-super-heroes spec: diff --git a/deploy/k8s/java17-kubernetes.yml b/deploy/k8s/java17-kubernetes.yml index 31946db62..122343c75 100644 --- a/deploy/k8s/java17-kubernetes.yml +++ b/deploy/k8s/java17-kubernetes.yml @@ -1285,7 +1285,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes annotations: app.openshift.io/connects-to: rest-fights diff --git a/deploy/k8s/java17-minikube.yml b/deploy/k8s/java17-minikube.yml index 3af4db3cb..8c3f87f71 100644 --- a/deploy/k8s/java17-minikube.yml +++ b/deploy/k8s/java17-minikube.yml @@ -1277,7 +1277,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes annotations: app.openshift.io/connects-to: rest-fights diff --git a/deploy/k8s/java17-openshift.yml b/deploy/k8s/java17-openshift.yml index f582d026a..55f9549ce 100644 --- a/deploy/k8s/java17-openshift.yml +++ b/deploy/k8s/java17-openshift.yml @@ -1647,7 +1647,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes annotations: app.openshift.io/connects-to: rest-fights diff --git a/deploy/k8s/native-knative.yml b/deploy/k8s/native-knative.yml index e42a9d9c2..3ea6c8fe8 100644 --- a/deploy/k8s/native-knative.yml +++ b/deploy/k8s/native-knative.yml @@ -1032,7 +1032,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes app.kubernetes.io/name: ui-super-heroes name: ui-super-heroes @@ -1050,7 +1050,7 @@ spec: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes app.kubernetes.io/name: ui-super-heroes spec: diff --git a/deploy/k8s/native-kubernetes.yml b/deploy/k8s/native-kubernetes.yml index 264383f87..4ce14a529 100644 --- a/deploy/k8s/native-kubernetes.yml +++ b/deploy/k8s/native-kubernetes.yml @@ -1285,7 +1285,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes annotations: app.openshift.io/connects-to: rest-fights diff --git a/deploy/k8s/native-minikube.yml b/deploy/k8s/native-minikube.yml index fdec493e0..1f3f8fdb9 100644 --- a/deploy/k8s/native-minikube.yml +++ b/deploy/k8s/native-minikube.yml @@ -1277,7 +1277,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes annotations: app.openshift.io/connects-to: rest-fights diff --git a/deploy/k8s/native-openshift.yml b/deploy/k8s/native-openshift.yml index 9be349b52..7195a14a0 100644 --- a/deploy/k8s/native-openshift.yml +++ b/deploy/k8s/native-openshift.yml @@ -1647,7 +1647,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes annotations: app.openshift.io/connects-to: rest-fights diff --git a/docs/automation.md b/docs/automation.md index b84e5d4ca..11e072fef 100644 --- a/docs/automation.md +++ b/docs/automation.md @@ -5,11 +5,8 @@ - [Build and push container images](#build-and-push-container-images-workflow) - [Build JVM container image job](#build-jvm-container-images-job) - [Build native container image job](#build-native-container-images-job) - - [Build UI images job](#build-ui-images-job) - [Push application container images job](#push-application-container-images-job) - - [Push UI images job](#push-ui-images-job) - [Create application multi-arch manifests](#create-application-multi-arch-manifests) - - [Create UI multi-arch manifests](#create-ui-multi-arch-manifests) - [Create deploy resources](#create-deploy-resources-workflow) - [Cleanup artifacts](#cleanup-artifacts) - [Application Resource Generation](#application-resource-generation) @@ -28,22 +25,19 @@ The [Basic building and testing](../.github/workflows/simple-build-test.yml) wor It runs whenever code is pushed to the `main` branch as well as upon any pull requests. > The workflow can also be [triggered manually](https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow). -It runs `./mvnw clean verify` and `./mvnw clean verify -Pnative` on the [`event-statistics`](../event-statistics), [`rest-fights`](../rest-fights), [`rest-heroes`](../rest-heroes), and [`rest-villains`](../rest-villains) applications on Java 17. +It runs `./mvnw clean verify` and `./mvnw clean verify -Pnative` on the [`event-statistics`](../event-statistics), [`rest-fights`](../rest-fights), [`rest-heroes`](../rest-heroes), [`rest-villains`](../rest-villains), and [`ui-super-heroes`](../ui-super-heroes) applications on Java 17. ## Build and push container images workflow -The [Build and push container images](../.github/workflows/build-push-container-images.yml) workflow does pretty much what it sounds like: builds and pushes container images. For JVM images and for the `ui-super-heroes` application, it builds both `amd64` and `arm64` images. Multi-arch native images are coming soon. +The [Build and push container images](../.github/workflows/build-push-container-images.yml) workflow does pretty much what it sounds like: builds and pushes container images. For JVM images, it builds both `amd64` and `arm64` images. Multi-arch native images are coming soon. It only runs on pushes to the `main` branch after successful completion of the above [_Basic building and testing_](#basic-building-and-testing-workflow) workflow. > The workflow can also be [triggered manually](https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow). -It consists of 7 jobs: +It consists of 4 jobs: - [_Build JVM container images_](#build-jvm-container-images-job) - [_Build native container images_](#build-native-container-images-job) -- [_Build UI images_](#build-ui-images-job) - [_Push application container images_](#push-application-container-images-job) -- [_Push UI images_](#push-ui-images-job) - [Create application multi-arch manifests](#create-application-multi-arch-manifests) -- [Create UI multi-arch manifests](#create-ui-multi-arch-manifests) If any step in any of the jobs fail then the entire workflow fails. @@ -52,7 +46,7 @@ This image is a visual of what the workflow consists of: ![build-push-images-workflow](../images/build-push-container-images-workflow.png) ### Build JVM container images job -This job [Builds JVM container images](https://quarkus.io/guides/container-image#building) for the [`event-statistics`](../event-statistics), [`rest-fights`](../rest-fights), [`rest-heroes`](../rest-heroes), and [`rest-villains`](../rest-villains) applications on Java 17 (both amd64 & arm64 platforms) using the [Docker Build action](https://github.com/docker/build-push-action). +This job [Builds JVM container images](https://quarkus.io/guides/container-image#building) for the [`event-statistics`](../event-statistics), [`rest-fights`](../rest-fights), [`rest-heroes`](../rest-heroes), [`rest-villains`](../rest-villains), and [`ui-super-heroes`](../ui-super-heroes) applications on Java 17 (both amd64 & arm64 platforms) using the [Docker Build action](https://github.com/docker/build-push-action). Each container image created has 4 tags: - `{{app-version}}-quarkus-{{quarkus-version}}-java{{java-version}}-amd64` @@ -67,9 +61,9 @@ Each container image created has 4 tags: There are a total of 8 images built (4 applications x 1 JVM version x 2 platforms). ### Build native container images job -This job runs in parallel with the [_Build JVM container images_](#build-jvm-container-images-job) and [_Build UI images_](#build-ui-images-job) jobs. +This job runs in parallel with the [_Build JVM container images_](#build-jvm-container-images-job) job. -The job [Builds native executable container images](https://quarkus.io/guides/building-native-image#using-the-container-image-extensions) for the [`event-statistics`](../event-statistics), [`rest-fights`](../rest-fights), [`rest-heroes`](../rest-heroes), and [`rest-villains`](../rest-villains) applications using [Mandrel](https://github.com/graalvm/mandrel). +The job [Builds native executable container images](https://quarkus.io/guides/building-native-image#using-the-container-image-extensions) for the [`event-statistics`](../event-statistics), [`rest-fights`](../rest-fights), [`rest-heroes`](../rest-heroes), [`rest-villains`](../rest-villains), and [`ui-super-heroes`](../ui-super-heroes) applications using [Mandrel](https://github.com/graalvm/mandrel). Each container image created has 4 tags: - `{{app-version}}-quarkus-{{quarkus-version}}-native-amd64` @@ -80,41 +74,18 @@ Each container image created has 4 tags: > - Replace `{{app-version}}` with the application version (i.e. `1.0`). > - Replace `{{quarkus-version}}` with Quarkus version the application uses (i.e. `3.0.3.Final`). -There are a total of 8 images built (4 applications x 2 platforms). +There are a total of 10 images built (5 applications x 2 platforms). -### Build UI images job -This job runs in parallel with the [_Build JVM container images_](#build-jvm-container-images-job) and [_Build native container images_](#build-native-container-images-job) jobs. - -It builds the [`ui-super-heroes`](../ui-super-heroes) container image (both amd64 & arm64 platforms) with the following 4 tags: -- `{{app-version}}-amd64` -- `{{app-version}}-arm64` -- `latest-amd64` -- `latest-arm64` - -> - Replace `{{app-version}}` with the application version (i.e. `1.0`). - -There are a total of 2 images built, 1 each for amd64 & arm64 platforms. - ### Push application container images job -Runs after successful completion of the [_Build JVM container image_](#build-jvm-container-images-job), [_Build native container image_](#build-native-container-images-job), and [_Build UI images_](#build-ui-images-job) jobs and in parallel with the [_Push UI images_](#push-ui-images-job) job. +Runs after successful completion of the [_Build JVM container image_](#build-jvm-container-images-job) and [_Build native container image_](#build-native-container-images-job) jobs. All the container images created in the [_Build JVM container image_](#build-jvm-container-images-job) and [_Build native container image_](#build-native-container-images-job) jobs (24 total container images/48 tags) are pushed to https://quay.io/quarkus-super-heroes. -### Push UI images job -Runs after successful completion of the [_Build JVM container image_](#build-jvm-container-images-job), [_Build native container image_](#build-native-container-images-job), and [_Build UI images_](#build-ui-images-job) jobs and in parallel with the [_Push application container images_](#push-application-container-images-job) job. - -All the container images created in the [_Build UI images_](#build-ui-images-job) job (2 total container images/4 tags) are pushed to https://quay.io/quarkus-super-heroes. - ### Create application multi-arch manifests Runs after successful completion of the [_Push application container images_](#push-application-container-images-job) job and in parallel with the [_Create UI multi-arch manifests_](#create-ui-multi-arch-manifests) job. All the application container images for each platform (amd64 & arm64) are combined into manifest lists using the [`docker manifest`](https://docs.docker.com/engine/reference/commandline/manifest) command. For example, the `java{{java-version}}-latest-amd64` and `java{{java-version}}-latest-arm64` tags are combined into a single manifest list with the tag `java{{java-version}}-latest`. -### Create UI multi-arch manifests -Runs after successful completion of the [_Push UI images_](#push-ui-images-job) job and in parallel with the [_Create application multi-arch manifests_](#create-application-multi-arch-manifests) job. - -All the UI container images for each platform (amd64 & arm64) are combined into manifest lists using the [`docker manifest`](https://docs.docker.com/engine/reference/commandline/manifest) command. For example, the `latest-amd64` and `latest-arm64` tags are combined into a single manifest list with the tag `latest`. - ## Create deploy resources workflow The [Create deploy resources](../.github/workflows/create-deploy-resources.yml) workflow is responsible for [generating all of the application resources](#application-resource-generation), described in a later section of this document. @@ -137,7 +108,7 @@ Resources in these directories are generated by the [_Create deploy resources_ w Kubernetes resources are generated into a `deploy/k8s` directory, either in the [project root directory](../deploy/k8s) or in each individual project's directory. ### Quarkus projects -Each Quarkus project ([`event-statistics`](../event-statistics), [`rest-fights`](../rest-fights), [`rest-heroes`](../rest-heroes), [`rest-villains`](../rest-villains)) uses the [Quarkus Kubernetes extension](https://quarkus.io/guides/deploying-to-kubernetes) to generate Kubernetes and KNative manifests, the [Quarkus Minikube extension](https://quarkus.io/guides/deploying-to-kubernetes#deploying-to-minikube) to generate Minikube manifests, and the [Quarkus OpenShift extension](https://quarkus.io/guides/deploying-to-openshift) to generate OpenShift manifests. +Each Quarkus project ([`event-statistics`](../event-statistics), [`rest-fights`](../rest-fights), [`rest-heroes`](../rest-heroes), [`rest-villains`](../rest-villains), [`ui-super-heroes`](../ui-super-heroes)) uses the [Quarkus Kubernetes extension](https://quarkus.io/guides/deploying-to-kubernetes) to generate Kubernetes and KNative manifests, the [Quarkus Minikube extension](https://quarkus.io/guides/deploying-to-kubernetes#deploying-to-minikube) to generate Minikube manifests, and the [Quarkus OpenShift extension](https://quarkus.io/guides/deploying-to-openshift) to generate OpenShift manifests. These extensions generate the manifests needed for the application itself but not for any other services. [These extensions can also incorporate additional resources](https://quarkus.io/guides/deploying-to-kubernetes#using-existing-resources) by placing additional resources in each project's `src/main/kubernetes` directory. @@ -147,13 +118,6 @@ The [`generate-k8s-resources.sh` script](../scripts/generate-k8s-resources.sh) a In the [`rest-fights` project](../rest-fights), the [`generate-k8s-resources.sh` script](../scripts/generate-k8s-resources.sh) additionally copies in generated resources from the [`rest-heroes`](../rest-heroes) and [`rest-villains`](../rest-villains) projects into the `all-downstream.yml` files in the [`deploy/k8s` directory of the `rest-fights` project](../rest-fights/deploy/k8s). -### UI Project -Since the [`ui-super-heroes` project](../ui-super-heroes) isn't a Quarkus project it therefore doesn't have a way to generate the Kubernetes manifests. - -The [`generate-k8s-resources.sh` script](../scripts/generate-k8s-resources.sh) implements the same pattern for this project. The [`ui-super-heroes` project](../ui-super-heroes) has a [`src/main/kubernetes` directory](../ui-super-heroes/src/main/kubernetes) containing the Kubernetes manifests. - -The [`generate-k8s-resources.sh` script](../scripts/generate-k8s-resources.sh) merges the contents of these files into the files in the [`ui-super-heroes` project's `deploy/k8s` directory](../ui-super-heroes/deploy/k8s) as well as all the files in the [root `deploy/k8s` directory](../deploy/k8s). - ## Docker compose resource generation Docker compose resource generation follows a similar pattern as the [Kubernetes resource generation](#kubernetes-and-variants-resource-generation). @@ -175,8 +139,3 @@ This table describes the different files that can be found inside a project's `s The [`generate-docker-compose-resources.sh` script](../scripts/generate-docker-compose-resources.sh) loops through all versions of each application (Java version 17, both JVM and native - 8 total versions) and merges contents of these files from each project's `src/main/docker-compose` directory into each project's `deploy/docker-compose` directory as well as the respective files in the [root `deploy/docker-compose` directory](../deploy/docker-compose). The [`generate-docker-compose-resources.sh` script](../scripts/generate-docker-compose-resources.sh) additionally creates the [monitoring compose file (`monitoring.yml`)](../deploy/docker-compose/monitoring.yml) within the [root `deploy/docker-compose` directory](../deploy/docker-compose). - -### UI Project -Like the Quarkus projects, the [`ui-super-heroes` project](../ui-super-heroes) also has a [`src/main/docker-compose` directory](../ui-super-heroes/src/main/docker-compose). There is only a single [`app.yml` file](../ui-super-heroes/src/main/docker-compose/app.yml) containing the _Docker compose snippet_. - -The [`generate-docker-compose-resources.sh` script](../scripts/generate-docker-compose-resources.sh) merges the contents of this file into the [`ui-super-heroes` project's `deploy/docker-compose/app.yml` file](../ui-super-heroes/deploy/docker-compose/app.yml) as well as all the files in the [root `deploy/docker-compose` directory](../deploy/docker-compose). diff --git a/docs/deploying-to-azure-containerapps.md b/docs/deploying-to-azure-containerapps.md index 2befd4789..e2b3c73ac 100644 --- a/docs/deploying-to-azure-containerapps.md +++ b/docs/deploying-to-azure-containerapps.md @@ -699,7 +699,7 @@ Then, to execute the app locally, set `API_BASE_URL` with the same value of the ```shell export API_BASE_URL=https://${FIGHT_URL}/api -ui-super-heroes$ npm install && npm run build && npm start +ui-super-heroes$ java -jar target/quarkus-app/quarkus-run.jar ``` You can check the URL is correctly set with: diff --git a/images/application-architecture-azure-containerapps.png b/images/application-architecture-azure-containerapps.png index 2e3fcbf0f..daa8ba0e0 100644 Binary files a/images/application-architecture-azure-containerapps.png and b/images/application-architecture-azure-containerapps.png differ diff --git a/images/application-architecture.png b/images/application-architecture.png index c2bc2f156..15485faca 100644 Binary files a/images/application-architecture.png and b/images/application-architecture.png differ diff --git a/images/build-push-container-images-workflow.png b/images/build-push-container-images-workflow.png index 04598557c..1b5383b8d 100644 Binary files a/images/build-push-container-images-workflow.png and b/images/build-push-container-images-workflow.png differ diff --git a/images/plantuml/application-architecture-azure-containerapps.puml b/images/plantuml/application-architecture-azure-containerapps.puml index 858b11af4..5307ba63c 100644 --- a/images/plantuml/application-architecture-azure-containerapps.puml +++ b/images/plantuml/application-architecture-azure-containerapps.puml @@ -4,15 +4,17 @@ skinparam NodePadding 40 !include !include !include -!include +!include !include !include style.puml left to right direction together { - node "Super Hero UI" <> as ui { - agent "<$nodejs>" as uiQuarkus + node "Super Hero UI" as ui { + agent "<$angular>" <> as angularUi + agent "Quarkus" <> as uiQuarkus + angularUi .up> uiQuarkus } node "<$prometheus>" as prometheus { @@ -56,7 +58,7 @@ package "stats" <> { } } -uiQuarkus --> fightQuarkus : HTTP +angularUi --> fightQuarkus : HTTP fightQuarkus --> villainQuarkus : HTTP fightQuarkus --> heroQuarkus : HTTP diff --git a/images/plantuml/application-architecture.puml b/images/plantuml/application-architecture.puml index 37bee54fb..52ee91209 100644 --- a/images/plantuml/application-architecture.puml +++ b/images/plantuml/application-architecture.puml @@ -3,8 +3,8 @@ skinparam NodePadding 40 !include !include !include -!include !include +!include !include !include style.puml @@ -21,7 +21,9 @@ together { } node "Super Hero UI" as ui { - agent "<$nodejs>" as uiQuarkus + agent "<$angular>" <> as angularUi + agent "Quarkus" <> as uiQuarkus + angularUi .up> uiQuarkus } } @@ -63,7 +65,7 @@ package "stats" { } } -uiQuarkus --> fightQuarkus : HTTP +angularUi --> fightQuarkus : HTTP fightQuarkus --> villainQuarkus : HTTP fightQuarkus --> heroQuarkus : HTTP diff --git a/scripts/generate-docker-compose-resources.sh b/scripts/generate-docker-compose-resources.sh index 354ccae7c..d156bf9cb 100755 --- a/scripts/generate-docker-compose-resources.sh +++ b/scripts/generate-docker-compose-resources.sh @@ -136,11 +136,7 @@ do versionFilename="${kind}java${javaVersion}" fi - if [[ "$project" == "ui-super-heroes" ]]; then - filename="app" - else - filename=$versionFilename - fi + filename=$versionFilename create_project_output $project $filename $versionFilename done diff --git a/scripts/generate-k8s-resources.sh b/scripts/generate-k8s-resources.sh index 38ad35adb..6ffe38a8b 100755 --- a/scripts/generate-k8s-resources.sh +++ b/scripts/generate-k8s-resources.sh @@ -107,25 +107,6 @@ process_quarkus_project() { fi } -process_ui_project() { - local deployment_type=$1 - local version_tag=$2 - local project="ui-super-heroes" - local project_input_directory="$project/$INPUT_DIR" - local input_file="$project_input_directory/${deployment_type}.yml" - local project_output_file="$project/$OUTPUT_DIR/app-${deployment_type}.yml" - local all_apps_output_file="$OUTPUT_DIR/${version_tag}-${deployment_type}.yml" - - rm -rf $project_output_file - - if [[ -f "$input_file" ]]; then - create_output_file $project_output_file - echo "Copying app input ($input_file) to $project_output_file and $all_apps_output_file" - cat $input_file >> $project_output_file - cat $input_file >> $all_apps_output_file - fi -} - create_monitoring() { local monitoring_name="monitoring" @@ -172,7 +153,7 @@ do version_tag="${kind}java${javaVersion}" fi - for project in "rest-villains" "rest-heroes" "rest-fights" "event-statistics" + for project in "rest-villains" "rest-heroes" "rest-fights" "event-statistics" "ui-super-heroes" do # Generate all the k8s resources for all deployment types in one shot do_build $project $version_tag $javaVersion $kind @@ -183,12 +164,6 @@ do process_quarkus_project $project $deployment_type $version_tag $javaVersion $kind done done - - for deployment_type in ${DEPLOYMENT_TYPES[@]} - do - # Handle the UI project for each deployment type - process_ui_project $deployment_type $version_tag - done done done diff --git a/ui-super-heroes/.gitignore b/ui-super-heroes/.gitignore index bb66792a6..fe58fa7dd 100644 --- a/ui-super-heroes/.gitignore +++ b/ui-super-heroes/.gitignore @@ -92,6 +92,8 @@ out .nuxt dist +.quinoa + # Gatsby files .cache/ # Comment in the public line in if your project uses Gatsby and not Next.js diff --git a/ui-super-heroes/.mvn/wrapper/maven-wrapper.properties b/ui-super-heroes/.mvn/wrapper/maven-wrapper.properties index 70f4f50fc..d8b2495a1 100644 --- a/ui-super-heroes/.mvn/wrapper/maven-wrapper.properties +++ b/ui-super-heroes/.mvn/wrapper/maven-wrapper.properties @@ -14,5 +14,5 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.8/apache-maven-3.8.8-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.1/apache-maven-3.9.1-bin.zip wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/ui-super-heroes/Dockerfile b/ui-super-heroes/Dockerfile deleted file mode 100644 index 116b389ce..000000000 --- a/ui-super-heroes/Dockerfile +++ /dev/null @@ -1,39 +0,0 @@ -# First stage builds the application -FROM registry.access.redhat.com/ubi9/nodejs-18:1-26.1675794538 as builder - -USER 1001 - -# This is a hack, but until the UI has been completely re-written, this will have to do -ENV NODE_OPTIONS=--openssl-legacy-provider - -# Add dependencies -COPY --chown=1001:1001 package*.json $HOME/ - -# Install dependencies -RUN npm install - -# Add application sources -COPY --chown=1001:1001 . $HOME/ - -# Run build -RUN npm run build && \ - npm prune --production - -# Second stage copies the application to the minimal image -FROM registry.access.redhat.com/ubi9/nodejs-18-minimal:1-27.1675790153 - -# ENV variables -# HTTP_PORT: The http port this service listens on -# NODE_OPTIONS=--openssl-legacy-provider is a hack, but until the UI has been completely re-written, this will have to do -ENV HTTP_PORT=8080 \ - NODE_ENV=production \ - NODE_OPTIONS=--openssl-legacy-provider - -# Copy the application source and build artifacts from the builder image to this one -COPY --chown=1001:1001 --from=builder $HOME $HOME - -# Expose the http port -EXPOSE $HTTP_PORT - -# Run script uses standard ways to run the application -CMD npm start diff --git a/ui-super-heroes/README.md b/ui-super-heroes/README.md index ecee2a02e..60c36080b 100644 --- a/ui-super-heroes/README.md +++ b/ui-super-heroes/README.md @@ -10,7 +10,7 @@ - [Routing](#routing) ## Introduction -This is the main user interface for the application. The application is an Angular application served via Node.js. +This is the main user interface for the application. The application is an Angular application served via [Quinoa](https://quarkus.io/extensions/io.quarkiverse.quinoa/quarkus-quinoa). ![ui-super-heroes](images/ui-super-heroes.png) @@ -23,26 +23,32 @@ Environment variables can be injected into the build using the [ngx-env](https:/ Variables must start with the `NG_APP` prefix, e.g `NG_APP_MY_URL=http://localhost:1234`. -Production builds are served using a Node.js server. This server serves the compiled Angular application and an `env.js` file. This `env.js` file is generated at startup, and adds a `window.NG_CONFIG` property that the Angular application can read from. +Production builds are served using a Quarkus server. This server serves the compiled Angular application and an `env.js` file. This `env.js` file is generated at startup, and adds a `window.NG_CONFIG` property that the Angular application can read from. Currently, the `env.js` will expose just the `API_BASE_URL` that's set at runtime. This will control the base URL to connect to the [fights](../rest-fights) service. The default if unset is http://localhost:8082. +You can control the base URL using normal Quarkus configuration, such as setting `api.base.url` in `application.properties` or an `API_BASE_URL` environment variable. -You also need to make sure the angular CLI is installed (`npm install @angular/cli@12.2.8`). ```bash -npm run build +quarkus package +``` + +It is also possible to build a native binary, using + +```bash +./mvnw -B clean package -DskipTests -Pnative ``` ## Local Development Use the following command: ```shell -npm run dev +quarkus dev ``` -This starts the Angular hot reloading server at http://localhost:4200, and the Node.js server to supply the `env.js` file. The Angular server on port 4200 will proxy the request for `env.js` to the Node.js server on port 8080. +This starts both Quarkus and the Angular hot reloading server at http://localhost:4200. The Quarkus server to supplies the `env.js` file to the Javascript front-end. -The Node.js server port can be changed by setting the `HTTP_PORT` variable. The `ng.proxy.config.json` file will need to be updated with the new Node.js server port number if you deviate from 8080. +The Quarkus server port can be changed in the usual way, with `application.properties`. ## Running the Application 1. First you need to start up all of the downstream services ([Heroes Service](../rest-heroes), [Villains Service](../rest-villains), and [Fights Service](../rest-fights)). @@ -50,7 +56,7 @@ The Node.js server port can be changed by setting the `HTTP_PORT` variable. The 2. Follow the steps above section, *Building the Application*. 3. Set the `API_BASE_URL` environment variable with the appropriate [Fights Service](../rest-fights) hostname and port. > By default, the [`rest-fights`](../rest-fights) service runs on port `8082`, so setting `API_BASE_URL=http://localhost:8082` will do. -4. Start the service using the command `npm start`. +4. Start the service using the command `quarkus dev`. - You can also set the environment variable `CALCULATE_API_BASE_URL=true` to have it compute the base URL. Only use this option if the UI url is in the form of `ui-super-heroes.somewhere.com`. In this instance, setting `CALCULATE_API_BASE_URL=true` will replace `ui-super-heroes` in the URL with `rest-fights`. There is also a container image available that you can use instead: @@ -67,7 +73,13 @@ The application can be started outside of docker compose simply with `docker run If you want to use docker compose, from the `quarkus-super-heroes/ui-super-heroes` directory run: ```bash -docker-compose -f deploy/docker-compose/app.yml up +docker-compose -f deploy/docker-compose/java17.yml up +``` + +or + +```bash +docker-compose -f deploy/docker-compose/native.yml up ``` If you want to stand up the entire system, [follow these instructions](../README.md#running-locally-via-docker-compose). diff --git a/ui-super-heroes/deploy/docker-compose/app.yml b/ui-super-heroes/deploy/docker-compose/java17.yml similarity index 100% rename from ui-super-heroes/deploy/docker-compose/app.yml rename to ui-super-heroes/deploy/docker-compose/java17.yml diff --git a/ui-super-heroes/deploy/docker-compose/native.yml b/ui-super-heroes/deploy/docker-compose/native.yml new file mode 100644 index 000000000..727b85e99 --- /dev/null +++ b/ui-super-heroes/deploy/docker-compose/native.yml @@ -0,0 +1,11 @@ +version: "3" +services: + + ui-super-heroes-native: + image: quay.io/quarkus-super-heroes/ui-super-heroes:native-latest + container_name: ui-super-heroes + ports: + - "8080:8080" + restart: on-failure + environment: + API_BASE_URL: http://localhost:8082 diff --git a/ui-super-heroes/deploy/k8s/app-knative.yml b/ui-super-heroes/deploy/k8s/app-knative.yml index a269f6045..9d7f39274 100644 --- a/ui-super-heroes/deploy/k8s/app-knative.yml +++ b/ui-super-heroes/deploy/k8s/app-knative.yml @@ -12,7 +12,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes app.kubernetes.io/name: ui-super-heroes name: ui-super-heroes @@ -30,7 +30,7 @@ spec: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes app.kubernetes.io/name: ui-super-heroes spec: diff --git a/ui-super-heroes/deploy/k8s/app-kubernetes.yml b/ui-super-heroes/deploy/k8s/app-kubernetes.yml index b383b0ec8..678c1540e 100644 --- a/ui-super-heroes/deploy/k8s/app-kubernetes.yml +++ b/ui-super-heroes/deploy/k8s/app-kubernetes.yml @@ -6,7 +6,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes annotations: app.openshift.io/connects-to: rest-fights diff --git a/ui-super-heroes/deploy/k8s/app-minikube.yml b/ui-super-heroes/deploy/k8s/app-minikube.yml index dc842adc8..6f8fbda38 100644 --- a/ui-super-heroes/deploy/k8s/app-minikube.yml +++ b/ui-super-heroes/deploy/k8s/app-minikube.yml @@ -6,7 +6,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes annotations: app.openshift.io/connects-to: rest-fights diff --git a/ui-super-heroes/deploy/k8s/app-openshift.yml b/ui-super-heroes/deploy/k8s/app-openshift.yml index e00d588c0..cb1712a16 100644 --- a/ui-super-heroes/deploy/k8s/app-openshift.yml +++ b/ui-super-heroes/deploy/k8s/app-openshift.yml @@ -6,7 +6,7 @@ metadata: app: ui-super-heroes application: super-heroes system: quarkus-super-heroes - app.openshift.io/runtime: nodejs + app.openshift.io/runtime: quarkus app.kubernetes.io/part-of: super-heroes annotations: app.openshift.io/connects-to: rest-fights diff --git a/ui-super-heroes/images/ui-super-heroes.png b/ui-super-heroes/images/ui-super-heroes.png index c6a4b48d8..873e9907d 100644 Binary files a/ui-super-heroes/images/ui-super-heroes.png and b/ui-super-heroes/images/ui-super-heroes.png differ diff --git a/ui-super-heroes/ng.proxy.config.json b/ui-super-heroes/ng.proxy.config.json deleted file mode 100644 index 3c4e95706..000000000 --- a/ui-super-heroes/ng.proxy.config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "/env.js": { - "target": "http://localhost:8080/", - "secure": false - } -} diff --git a/ui-super-heroes/package.sh b/ui-super-heroes/package.sh deleted file mode 100755 index dcb3eeb3b..000000000 --- a/ui-super-heroes/package.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -# tag::adocShell[] -./node_modules/.bin/ng build --configuration production --base-href "." -# end::adocShell[] - diff --git a/ui-super-heroes/pom.xml b/ui-super-heroes/pom.xml index 4b4c39d7b..eb3f12edb 100644 --- a/ui-super-heroes/pom.xml +++ b/ui-super-heroes/pom.xml @@ -6,4 +6,164 @@ ui-super-heroes 1.0 Quarkus Sample :: Super-Heroes :: User Interface + + 3.11.0 + 17 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 3.1.1.Final + 2.0.4 + 3.1.2 + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + + + io.quarkiverse.quinoa + quarkus-quinoa + ${quinoa.version} + + + io.quarkus + quarkus-arc + + + io.quarkus + quarkus-resteasy-reactive + + + io.quarkus + quarkus-resteasy-reactive-jackson + + + io.quarkus + quarkus-container-image-docker + + + io.quarkus + quarkus-openshift + + + io.quarkus + quarkus-kubernetes + + + io.quarkus + quarkus-minikube + + + io.quarkus + quarkus-micrometer-registry-prometheus + + + io.quarkus + quarkus-smallrye-health + + + io.quarkus + quarkus-opentelemetry + + + io.quarkus + quarkus-jacoco + test + + + io.rest-assured + rest-assured + test + + + io.quarkiverse.quinoa + quarkus-quinoa-testing + ${quinoa.version} + test + + + io.quarkus + quarkus-junit5 + test + + + + + + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + true + + + + build + generate-code + generate-code-tests + + + + + + maven-compiler-plugin + ${compiler-plugin.version} + + + -parameters + + + + + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + ${maven.home} + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + + + + + + native + + + native + + + + native + + + diff --git a/ui-super-heroes/serving/config.js b/ui-super-heroes/serving/config.js deleted file mode 100644 index 386e9d099..000000000 --- a/ui-super-heroes/serving/config.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict' - -const { get } = require('env-var') -const { join } = require('path') - -module.exports = { - HTTP_PORT: get('HTTP_PORT').default(8080).asPortNumber(), - - API_BASE_URL: get('API_BASE_URL').asUrlString(), - - CALCULATE_API_BASE_URL: get('CALCULATE_API_BASE_URL').default("false").asBool(), - - // Location of Angular build and other files. Defaults to the dist/ - // in the root of the project - STATIC_DIR: get('STATIC_DIR').default(join(__dirname, '../dist/super-heroes')).asString() -} diff --git a/ui-super-heroes/serving/server.js b/ui-super-heroes/serving/server.js deleted file mode 100644 index 8b33abbe5..000000000 --- a/ui-super-heroes/serving/server.js +++ /dev/null @@ -1,56 +0,0 @@ -'use strict' - -const express = require('express') -const log = require('barelog'); -const promBundle = require("express-prom-bundle"); -const { join } = require('path'); -const { HTTP_PORT, API_BASE_URL, CALCULATE_API_BASE_URL, STATIC_DIR } = require('./config') - -const app = express(); - -// Add the options to the prometheus middleware most option are for http_request_duration_seconds histogram metric -const metricsMiddleware = promBundle({ - includeMethod: true, - includePath: true, - includeStatusCode: true, - includeUp: true, - customLabels: { - app: 'ui-super-heroes', - application: 'super-heroes', - system: 'quarkus-super-heroes' - }, - promClient: { - collectDefaultMetrics: { - } - } -}); - -// add the prometheus middleware to all routes -app.use(metricsMiddleware) - -// Serve requests for the /env.js environment configuration -app.get('/env.js', (req, res) => { - res.setHeader('Content-Type', 'application/javascript'); - - let ngConfig = {}; - - if (typeof API_BASE_URL !== 'undefined') { - ngConfig['API_BASE_URL'] = API_BASE_URL; - } - - if (typeof CALCULATE_API_BASE_URL !== 'undefined') { - ngConfig['CALCULATE_API_BASE_URL'] = CALCULATE_API_BASE_URL - } - - res.send('window.NG_CONFIG=' + JSON.stringify(ngConfig)); -}) - -// Serve files from the configured static directory -app.use(express.static(STATIC_DIR)) - -// Return the index.html for / -app.get('/', (req, res) => res.sendFile(join(STATIC_DIR, 'index.html'))) - -app.listen(HTTP_PORT, '0.0.0.0', () => { - log(`express server listening on ${HTTP_PORT}`) -}) diff --git a/ui-super-heroes/src/main/docker-compose/app.yml b/ui-super-heroes/src/main/docker-compose/java17.yml similarity index 61% rename from ui-super-heroes/src/main/docker-compose/app.yml rename to ui-super-heroes/src/main/docker-compose/java17.yml index 6e3e4b67c..0b0370423 100644 --- a/ui-super-heroes/src/main/docker-compose/app.yml +++ b/ui-super-heroes/src/main/docker-compose/java17.yml @@ -1,6 +1,6 @@ - ui-super-heroes: - image: quay.io/quarkus-super-heroes/ui-super-heroes:latest + ui-super-heroes-java17: + image: quay.io/quarkus-super-heroes/ui-super-heroes:java17-latest container_name: ui-super-heroes ports: - "8080:8080" diff --git a/ui-super-heroes/src/main/docker-compose/native.yml b/ui-super-heroes/src/main/docker-compose/native.yml new file mode 100644 index 000000000..22bed5e7d --- /dev/null +++ b/ui-super-heroes/src/main/docker-compose/native.yml @@ -0,0 +1,9 @@ + + ui-super-heroes-native: + image: quay.io/quarkus-super-heroes/ui-super-heroes:native-latest + container_name: ui-super-heroes + ports: + - "8080:8080" + restart: on-failure + environment: + API_BASE_URL: http://localhost:8082 diff --git a/ui-super-heroes/src/main/docker/Dockerfile.jvm b/ui-super-heroes/src/main/docker/Dockerfile.jvm new file mode 100644 index 000000000..74120e6d5 --- /dev/null +++ b/ui-super-heroes/src/main/docker/Dockerfile.jvm @@ -0,0 +1,93 @@ +@@ -0,0 +1,93 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./mvnw package +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/ui-super-heroes-jvm17 . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/ui-super-heroes-jvm17 +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005 +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/ui-super-heroes-jvm17 +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi9/openjdk-17:1.14 + +ENV LANGUAGE='en_US:en' + + +# We make four distinct layers so if there are application changes the library layers can be re-used +COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/ +COPY --chown=185 target/quarkus-app/*.jar /deployments/ +COPY --chown=185 target/quarkus-app/app/ /deployments/app/ +COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/ + +EXPOSE 8080 +USER 185 +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" diff --git a/ui-super-heroes/src/main/docker/Dockerfile.legacy-jar b/ui-super-heroes/src/main/docker/Dockerfile.legacy-jar new file mode 100644 index 000000000..ac84097c6 --- /dev/null +++ b/ui-super-heroes/src/main/docker/Dockerfile.legacy-jar @@ -0,0 +1,90 @@ +@@ -0,0 +1,89 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode +# +# Before building the container image run: +# +# ./mvnw package -Dquarkus.package.type=legacy-jar +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/ui-super-heroes-legacy-jar . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/ui-super-heroes-legacy-jar +# +# If you want to include the debug port into your docker image +# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005 +# +# Then run the container using : +# +# docker run -i --rm -p 8080:8080 quarkus/ui-super-heroes-legacy-jar +# +# This image uses the `run-java.sh` script to run the application. +# This scripts computes the command line to execute your Java application, and +# includes memory/GC tuning. +# You can configure the behavior using the following environment properties: +# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") +# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options +# in JAVA_OPTS (example: "-Dsome.property=foo") +# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is +# used to calculate a default maximal heap memory based on a containers restriction. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio +# of the container available memory as set here. The default is `50` which means 50% +# of the available memory is used as an upper boundary. You can skip this mechanism by +# setting this value to `0` in which case no `-Xmx` option is added. +# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This +# is used to calculate a default initial heap memory based on the maximum heap memory. +# If used in a container without any memory constraints for the container then this +# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio +# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx` +# is used as the initial heap size. You can skip this mechanism by setting this value +# to `0` in which case no `-Xms` option is added (example: "25") +# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS. +# This is used to calculate the maximum value of the initial heap memory. If used in +# a container without any memory constraints for the container then this option has +# no effect. If there is a memory constraint then `-Xms` is limited to the value set +# here. The default is 4096MB which means the calculated value of `-Xms` never will +# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096") +# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output +# when things are happening. This option, if set to true, will set +# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true"). +# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example: +# true"). +# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787"). +# - CONTAINER_CORE_LIMIT: A calculated core limit as described in +# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2") +# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024"). +# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion. +# (example: "20") +# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking. +# (example: "40") +# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection. +# (example: "4") +# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus +# previous GC times. (example: "90") +# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20") +# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100") +# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should +# contain the necessary JRE command-line options to specify the required GC, which +# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC). +# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080") +# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080") +# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be +# accessed directly. (example: "foo.example.com,bar.example.com") +# +### +FROM registry.access.redhat.com/ubi9/openjdk-17:1.14 + +ENV LANGUAGE='en_US:en' + + +COPY target/lib/* /deployments/lib/ +COPY target/*-runner.jar /deployments/quarkus-run.jar + +EXPOSE 8080 +USER 185 +ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" +ENV JAVA_APP_JAR="/deployments/quarkus-run.jar" diff --git a/ui-super-heroes/src/main/docker/Dockerfile.native b/ui-super-heroes/src/main/docker/Dockerfile.native new file mode 100644 index 000000000..043536c29 --- /dev/null +++ b/ui-super-heroes/src/main/docker/Dockerfile.native @@ -0,0 +1,27 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# +# Before building the container image run: +# +# ./mvnw package -Pnative +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native -t quarkus/ui-super-heroes . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/ui-super-heroes +# +### +FROM quay.io/quarkus/quarkus-micro-image:2.0 +WORKDIR /work/ +RUN chown 1001 /work \ + && chmod "g+rwX" /work \ + && chown 1001:root /work +COPY --chown=1001:root target/*-runner /work/application + +EXPOSE 8080 +USER 1001 + +CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/ui-super-heroes/src/main/docker/Dockerfile.native-micro b/ui-super-heroes/src/main/docker/Dockerfile.native-micro new file mode 100644 index 000000000..bff8743b5 --- /dev/null +++ b/ui-super-heroes/src/main/docker/Dockerfile.native-micro @@ -0,0 +1,27 @@ +@@ -0,0 +1,30 @@ +#### +# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. +# It uses a micro base image, tuned for Quarkus native executables. +# It reduces the size of the resulting container image. +# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. +# +# Before building the container image run: +# +# ./mvnw package -Pnative +# +# Then, build the image with: +# +# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/ui-super-heroes . +# +# Then run the container using: +# +# docker run -i --rm -p 8080:8080 quarkus/ui-super-heroes +# +### +FROM quay.io/quarkus/quarkus-distroless-image:2.0 +COPY target/*-runner /application + +EXPOSE 8080 +USER nonroot + +CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] diff --git a/ui-super-heroes/src/main/java/io/quarkus/sample/superheroes/ui/Config.java b/ui-super-heroes/src/main/java/io/quarkus/sample/superheroes/ui/Config.java new file mode 100644 index 000000000..a8b61e009 --- /dev/null +++ b/ui-super-heroes/src/main/java/io/quarkus/sample/superheroes/ui/Config.java @@ -0,0 +1,16 @@ +package io.quarkus.sample.superheroes.ui; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +import io.quarkus.runtime.annotations.RegisterForReflection; + +/* +Why do we need to register this for reflection? Normally this would be automatic if +we return it from a REST endpoint, but because we're handling our own +object mapping, we need to do our own registering. + */ +@JsonNaming(PropertyNamingStrategies.UpperSnakeCaseStrategy.class) +@RegisterForReflection +public record Config(String apiBaseUrl, boolean calculateApiBaseUrl) { +} diff --git a/ui-super-heroes/src/main/java/io/quarkus/sample/superheroes/ui/EnvResource.java b/ui-super-heroes/src/main/java/io/quarkus/sample/superheroes/ui/EnvResource.java new file mode 100644 index 000000000..48894a59e --- /dev/null +++ b/ui-super-heroes/src/main/java/io/quarkus/sample/superheroes/ui/EnvResource.java @@ -0,0 +1,41 @@ +package io.quarkus.sample.superheroes.ui; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.microprofile.config.inject.ConfigProperty; + +import jakarta.inject.Inject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; + +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; + +/** + * JAX-RS API endpoints to serve configuration to a front-end. + */ +@Path("/") +public class EnvResource { + + @ConfigProperty(name = "api.base.url", defaultValue = "http://localhost:8082") + String url; + + @ConfigProperty(name = "calculate.api.base.url", defaultValue = "false") + boolean calculateApiBaseUrl; + + @Inject + ObjectMapper objectMapper; + + @GET + @Produces(APPLICATION_JSON) + @Path("/env.js") + public String getConfig() throws JsonProcessingException { + Config config = new Config(url, + calculateApiBaseUrl); + // We could just return the Config object, but that would be json, and we want a + // javascript snippet we can include with + * and get something sensible back + */ + @Test + public void javascriptEndpoint() { + get("/env.js") + .then() + .statusCode(OK.getStatusCode()) + .body(is("window.NG_CONFIG={\"API_BASE_URL\":\"http://localhost:8082\",\"CALCULATE_API_BASE_URL\":false}")); + // This content is javascript, not json. Doing a simple equality check like this + // is brittle, but we can update it to something more flexible if we start to see issues + } + +} diff --git a/ui-super-heroes/src/test/java/io/quarkus/sample/superheroes/ui/WebUIIT.java b/ui-super-heroes/src/test/java/io/quarkus/sample/superheroes/ui/WebUIIT.java new file mode 100644 index 000000000..0c075ec41 --- /dev/null +++ b/ui-super-heroes/src/test/java/io/quarkus/sample/superheroes/ui/WebUIIT.java @@ -0,0 +1,11 @@ +package io.quarkus.sample.superheroes.ui; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +/** + * Tests the resource layer ({@link EnvResource}). + */ +@QuarkusIntegrationTest +public class WebUIIT extends WebUITests { + +} diff --git a/ui-super-heroes/src/test/java/io/quarkus/sample/superheroes/ui/WebUITests.java b/ui-super-heroes/src/test/java/io/quarkus/sample/superheroes/ui/WebUITests.java new file mode 100644 index 000000000..d92a4b05f --- /dev/null +++ b/ui-super-heroes/src/test/java/io/quarkus/sample/superheroes/ui/WebUITests.java @@ -0,0 +1,42 @@ +package io.quarkus.sample.superheroes.ui; + +import io.quarkiverse.quinoa.testing.QuinoaTestProfiles; + +import io.quarkus.sample.superheroes.ui.EnvResource; +import io.quarkus.test.junit.QuarkusTest; + +import io.quarkus.test.junit.TestProfile; + +import io.restassured.http.ContentType; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import java.util.regex.Pattern; + +import static io.restassured.RestAssured.get; +import static io.restassured.http.ContentType.HTML; +import static jakarta.ws.rs.core.Response.Status.OK; +import static org.hamcrest.Matchers.*; + +/** + * Tests the served javascript application. + * By default, the Web UI is not build/served in @QuarkusTest. The goal is to be able to test your api without having to wait for the Web UI build. + * The `Enable` test profile enables the Web UI (build and serve). + */ +@QuarkusTest +@TestProfile(QuinoaTestProfiles.Enable.class) +public class WebUITests { + + @Test + public void webApplicationEndpoint() { + get("/") + .then() + .statusCode(OK.getStatusCode()) + .contentType(HTML) + .body(matchesPattern(Pattern.compile(".*.*", Pattern.DOTALL))); + // We don't want to do full HTML parsing here, because that should + // be in the javascript tests. Instead, just confirm that we + // are successfully serving the HTML content on / + } +}