├── .github ├── dependabot.yml └── workflows │ ├── build.yml │ ├── preview-teardown.yml │ ├── preview.yml │ └── zips.yml ├── .gitignore ├── LICENSE ├── README.md └── quarkus-workshop-super-heroes ├── .dockerignore ├── .editorconfig ├── .mvn └── wrapper │ └── maven-wrapper.properties ├── README.adoc ├── assembly-complete.xml ├── assembly-core.xml ├── assembly.xml ├── dist ├── quarkus-super-heroes-workshop-complete.zip ├── quarkus-super-heroes-workshop-core.zip └── quarkus-super-heroes-workshop.zip ├── docs ├── .gitignore ├── pom.xml └── src │ ├── docs │ └── asciidoc │ │ ├── assets │ │ ├── css │ │ │ ├── bootstrap.css │ │ │ ├── font-awesome.min.css │ │ │ ├── github.css │ │ │ └── hol.css │ │ ├── js │ │ │ ├── bootstrap.js │ │ │ ├── highlight.pack.js │ │ │ └── jquery-3.1.1.js │ │ └── webfonts │ │ │ ├── fa-brands-400.eot │ │ │ ├── fa-brands-400.svg │ │ │ ├── fa-brands-400.ttf │ │ │ ├── fa-brands-400.woff │ │ │ ├── fa-brands-400.woff2 │ │ │ ├── fa-regular-400.eot │ │ │ ├── fa-regular-400.svg │ │ │ ├── fa-regular-400.ttf │ │ │ ├── fa-regular-400.woff │ │ │ ├── fa-regular-400.woff2 │ │ │ ├── fa-solid-900.eot │ │ │ ├── fa-solid-900.svg │ │ │ ├── fa-solid-900.ttf │ │ │ ├── fa-solid-900.woff │ │ │ ├── fa-solid-900.woff2 │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ ├── common-solution.adoc │ │ ├── core-appendix │ │ ├── appendix-installing-curl.adoc │ │ ├── appendix-installing-maven.adoc │ │ ├── appendix-preparing-warming-caches.adoc │ │ ├── appendix-preparing-warming-docker.adoc │ │ ├── appendix-preparing-warming-maven.adoc │ │ └── appendix.adoc │ │ ├── core-conclusion │ │ ├── conclusion-references.adoc │ │ └── conclusion.adoc │ │ ├── core-introduction │ │ ├── introduction-email.adoc │ │ ├── introduction-installing-ai.adoc │ │ ├── introduction-installing-azure-cli.adoc │ │ ├── introduction-installing-docker.adoc │ │ ├── introduction-installing-git.adoc │ │ ├── introduction-installing-graalvm.adoc │ │ ├── introduction-installing-jdk.adoc │ │ ├── introduction-installing-jq.adoc │ │ ├── introduction-installing-quarkus-cli.adoc │ │ ├── introduction-installing-rancher.adoc │ │ ├── introduction-installing-wsl.adoc │ │ ├── introduction-installing.adoc │ │ ├── introduction-preparing-checking-ports.adoc │ │ ├── introduction-preparing.adoc │ │ ├── introduction-presentation.adoc │ │ ├── introduction.adoc │ │ └── style.puml │ │ ├── core-microservices │ │ ├── microservices-fight.adoc │ │ ├── microservices.adoc │ │ └── style.puml │ │ ├── core-quarkus │ │ ├── quarkus-augmentation.adoc │ │ ├── quarkus-definition.adoc │ │ ├── quarkus-lifecycle.adoc │ │ ├── quarkus-profile.adoc │ │ └── quarkus.adoc │ │ ├── core-reactive │ │ ├── reactive.adoc │ │ └── style.puml │ │ ├── core-rest-client │ │ ├── rest-client-fallbacks.adoc │ │ ├── rest-client-timeout.adoc │ │ ├── rest-client.adoc │ │ ├── rest-clients.adoc │ │ └── style.puml │ │ ├── core-rest │ │ ├── rest-bootstrapping.adoc │ │ ├── rest-configuration.adoc │ │ ├── rest-openapi.adoc │ │ ├── rest-orm.adoc │ │ ├── rest.adoc │ │ └── style.puml │ │ ├── core-ui │ │ ├── ui-cors.adoc │ │ └── ui.adoc │ │ ├── default-options.adoc │ │ ├── docinfo-footer.html │ │ ├── docinfo.html │ │ ├── images │ │ ├── azure-aca-compute.png │ │ ├── azure-aca-concepts.png │ │ ├── azure-aca-intro.png │ │ ├── azure-aca-qrcode.png │ │ ├── azure-portal-2.png │ │ ├── azure-portal-3.png │ │ ├── azure-portal-4.png │ │ ├── blank-ui.png │ │ ├── cors.png │ │ ├── fault-tolerance-fallback.png │ │ ├── fault-tolerance-pending.png │ │ ├── fault-tolerance-prometheus-1.png │ │ ├── fault-tolerance-prometheus-2.png │ │ ├── fault-tolerance-prometheus-3.png │ │ ├── observability-health-ui.png │ │ ├── openai-fund.png │ │ ├── openai-key.png │ │ ├── openai-org.png │ │ ├── quarkus-augmentation.png │ │ ├── quarkus-build-time-principle.png │ │ ├── quarkus-extensions.png │ │ ├── quarkus-logo.png │ │ ├── quarkus-native-compilation.png │ │ ├── react-ui-ai.png │ │ ├── react-ui-stats.png │ │ ├── react-ui.png │ │ ├── rest-openapi-swaggerui.png │ │ └── semantic-kernel.png │ │ ├── index.html │ │ ├── optional-ai │ │ ├── ai.adoc │ │ └── style.puml │ │ ├── optional-azure-container-apps │ │ ├── azure-aca-administrating.adoc │ │ ├── azure-aca-running-app.adoc │ │ ├── azure-aca.adoc │ │ ├── azure-cleaning-up.adoc │ │ ├── azure-local-running-app.adoc │ │ └── azure-setting-up.adoc │ │ ├── optional-container │ │ └── container.adoc │ │ ├── optional-contract-testing │ │ ├── contract-testing-happy-path-consumer-tests.adoc │ │ ├── contract-testing-provider-tests.adoc │ │ ├── contract-testing-states.adoc │ │ └── contract-testing.adoc │ │ ├── optional-kubernetes │ │ ├── kubernetes-open-shift.adoc │ │ └── kubernetes.adoc │ │ ├── optional-load │ │ └── load.adoc │ │ ├── optional-messaging │ │ ├── messaging-conclusion.adoc │ │ ├── messaging-receiving-from-kafka.adoc │ │ ├── messaging-sending-to-kafka.adoc │ │ ├── messaging-websocket.adoc │ │ ├── messaging.adoc │ │ └── style.puml │ │ ├── optional-native │ │ └── native.adoc │ │ ├── optional-observability │ │ ├── observability-healthcheck.adoc │ │ ├── observability-metrics.adoc │ │ ├── observability-prometheus.adoc │ │ └── observability.adoc │ │ ├── optional-quarkus-extension │ │ ├── quarkus-extension.adoc │ │ └── style.puml │ │ ├── plantuml │ │ ├── 0-introduction-physical-architecture-ai.puml │ │ ├── 0-introduction-physical-architecture.puml │ │ ├── 1-rest-physical-architecture.puml │ │ ├── 3-reactive-physical-architecture.puml │ │ ├── 4-microservices-fights-sequence.puml │ │ ├── 4-microservices-physical-architecture.puml │ │ ├── 5-rest-client-physical-architecture.puml │ │ ├── 5a-ai-physical-architecture.puml │ │ ├── 5b-ai-narration-microservice.puml │ │ ├── 6-messaging-physical-architecture.puml │ │ ├── 6-quarkus-http-architecture.puml │ │ ├── 7-observability-physical-architecture.puml │ │ ├── 8-extension-architecture.puml │ │ └── style.puml │ │ ├── redirect.html │ │ ├── spine.adoc │ │ └── style.puml │ └── resource-generation │ ├── generate-attribute-combinations.sh │ └── qrcode.java ├── mvnw ├── mvnw.cmd ├── pom.xml └── super-heroes ├── event-statistics ├── .dockerignore ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── .gitignore │ │ ├── MavenWrapperDownloader.java │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ └── main │ ├── docker │ ├── Dockerfile.build-native │ ├── Dockerfile.jvm │ ├── Dockerfile.legacy-jar │ ├── Dockerfile.native │ └── Dockerfile.native-micro │ ├── java │ └── io │ │ └── quarkus │ │ └── workshop │ │ └── superheroes │ │ └── statistics │ │ ├── Fight.java │ │ ├── FightDeserializer.java │ │ ├── Ranking.java │ │ ├── Score.java │ │ ├── SuperStats.java │ │ ├── TeamStats.java │ │ ├── TeamStatsWebSocket.java │ │ └── TopWinnerWebSocket.java │ └── resources │ ├── META-INF │ └── resources │ │ └── index.html │ ├── application.properties │ └── banner.txt ├── extension-version ├── deployment │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── io │ │ └── quarkus │ │ └── workshop │ │ └── superheroes │ │ └── version │ │ └── deployment │ │ └── ExtensionVersionProcessor.java ├── pom.xml └── runtime │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── io │ │ └── quarkus │ │ └── workshop │ │ └── superheroes │ │ └── version │ │ └── runtime │ │ ├── VersionConfig.java │ │ └── VersionRecorder.java │ └── resources │ └── META-INF │ └── quarkus-extension.yaml ├── infrastructure ├── README.adoc ├── ai-azure-openai-create.sh ├── ai-azure-openai-delete.sh ├── azure-build-push-registry.sh ├── azure-deploy-aca.sh ├── azure-setup-aca-env.sh ├── azure-setup-azure-env.sh ├── azure-setup-env-var.sh ├── db-init │ ├── initialize-databases.sql │ ├── initialize-tables-fights.sql │ ├── initialize-tables-heroes.sql │ └── initialize-tables-villains.sql ├── docker-compose-app-local.yaml ├── docker-compose-app-remote.yaml ├── docker-compose-linux.yaml ├── docker-compose.yaml ├── monitoring │ ├── prometheus-linux.yml │ └── prometheus.yml ├── prometheus-linux.yaml └── prometheus.yaml ├── kubernetes ├── config-fight.yaml ├── config-hero.yaml ├── config-villain.yaml ├── database-fight.yaml ├── database-hero.yaml ├── database-villain.yaml ├── deployment-fight.yaml ├── deployment-hero.yaml ├── deployment-villain.yaml ├── kafka-cluster-descriptor.yaml └── kafka-topic-fight-descriptor.yaml ├── load-super-heroes ├── .dockerignore ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── .gitignore │ │ ├── MavenWrapperDownloader.java │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ └── main │ ├── docker │ ├── Dockerfile.jvm │ └── Dockerfile.legacy-jar │ ├── java │ └── io │ │ └── quarkus │ │ └── workshop │ │ └── superheroes │ │ └── load │ │ ├── CLIMain.java │ │ ├── client │ │ ├── Fight.java │ │ ├── FightsProxy.java │ │ ├── Hero.java │ │ ├── HeroProxy.java │ │ ├── RequestLogger.java │ │ ├── Villain.java │ │ └── VillainProxy.java │ │ ├── package-info.java │ │ └── scenarios │ │ ├── FightScenario.java │ │ ├── HeroScenario.java │ │ ├── Scenario.java │ │ └── VillainScenario.java │ └── resources │ └── application.properties ├── rest-fights ├── .dockerignore ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── .gitignore │ │ ├── MavenWrapperDownloader.java │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── docker │ │ ├── Dockerfile.build-native │ │ ├── Dockerfile.jvm │ │ ├── Dockerfile.legacy-jar │ │ ├── Dockerfile.native │ │ └── Dockerfile.native-micro │ ├── java │ │ └── io │ │ │ └── quarkus │ │ │ └── workshop │ │ │ └── superheroes │ │ │ └── fight │ │ │ ├── Fight.java │ │ │ ├── FightResource.java │ │ │ ├── FightService.java │ │ │ ├── Fighters.java │ │ │ ├── client │ │ │ ├── Hero.java │ │ │ ├── HeroProxy.java │ │ │ ├── NarrationProxy.java │ │ │ ├── Villain.java │ │ │ └── VillainProxy.java │ │ │ └── health │ │ │ └── PingFightResourceHealthCheck.java │ └── resources │ │ ├── META-INF │ │ └── resources │ │ │ └── index.html │ │ ├── application.properties │ │ ├── banner.txt │ │ └── import.sql │ └── test │ └── java │ └── io │ └── quarkus │ └── workshop │ └── superheroes │ └── fight │ ├── FightResourceConsumerTest.java │ ├── FightResourceTest.java │ └── client │ ├── DefaultTestHero.java │ ├── DefaultTestVillain.java │ ├── MockNarrationProxy.java │ └── MockVillainProxy.java ├── rest-heroes ├── .dockerignore ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── .gitignore │ │ ├── MavenWrapperDownloader.java │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── docker │ │ ├── Dockerfile.build-native │ │ ├── Dockerfile.jvm │ │ ├── Dockerfile.legacy-jar │ │ ├── Dockerfile.native │ │ └── Dockerfile.native-micro │ ├── java │ │ └── io │ │ │ └── quarkus │ │ │ └── workshop │ │ │ └── superheroes │ │ │ └── hero │ │ │ ├── Hero.java │ │ │ ├── HeroResource.java │ │ │ └── health │ │ │ └── PingHeroResourceHealthCheck.java │ └── resources │ │ ├── META-INF │ │ └── resources │ │ │ └── index.html │ │ ├── application.properties │ │ ├── banner.txt │ │ └── import.sql │ └── test │ ├── java │ └── io │ │ └── quarkus │ │ └── workshop │ │ └── superheroes │ │ └── hero │ │ ├── HeroContractVerificationTest.java │ │ ├── HeroResourceIT.java │ │ └── HeroResourceTest.java │ └── resources │ └── pacts │ └── rest-fights-rest-heroes.json ├── rest-narration ├── .dockerignore ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── .gitignore │ │ ├── MavenWrapperDownloader.java │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── docker │ │ ├── Dockerfile.jvm │ │ ├── Dockerfile.legacy-jar │ │ ├── Dockerfile.native │ │ └── Dockerfile.native-micro │ ├── java │ │ └── io │ │ │ └── quarkus │ │ │ └── workshop │ │ │ └── superheroes │ │ │ └── narration │ │ │ ├── Fight.java │ │ │ ├── NarrationResource.java │ │ │ ├── NarrationService.java │ │ │ └── SemanticKernelNarrationService.java │ └── resources │ │ ├── META-INF │ │ └── resources │ │ │ └── index.html │ │ ├── NarrationSkill │ │ └── NarrateFight │ │ │ ├── config.json │ │ │ └── skprompt.txt │ │ ├── application.properties │ │ └── banner.txt │ └── test │ └── java │ └── io │ └── quarkus │ └── workshop │ └── superheroes │ └── narration │ └── NarrationResourceTest.java ├── rest-villains ├── .dockerignore ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── .gitignore │ │ ├── MavenWrapperDownloader.java │ │ └── maven-wrapper.properties ├── jd-gui.cfg ├── mvnw ├── mvnw.cmd ├── openapi-custom.yml ├── openapi.yml ├── pom.xml └── src │ ├── main │ ├── docker │ │ ├── Dockerfile.build-native │ │ ├── Dockerfile.jvm │ │ ├── Dockerfile.legacy-jar │ │ ├── Dockerfile.native │ │ └── Dockerfile.native-micro │ ├── java │ │ └── io │ │ │ └── quarkus │ │ │ └── workshop │ │ │ └── superheroes │ │ │ └── villain │ │ │ ├── Villain.java │ │ │ ├── VillainApplication.java │ │ │ ├── VillainApplicationLifeCycle.java │ │ │ ├── VillainResource.java │ │ │ ├── VillainService.java │ │ │ └── health │ │ │ └── PingVillainResourceHealthCheck.java │ └── resources │ │ ├── META-INF │ │ └── resources │ │ │ └── index.html │ │ ├── application.properties │ │ └── import.sql │ └── test │ └── java │ └── io │ └── quarkus │ └── workshop │ └── superheroes │ └── villain │ ├── VillainResourceIT.java │ └── VillainResourceTest.java └── ui-super-heroes ├── .browserslistrc ├── .dockerignore ├── .gitignore ├── .mvn └── wrapper │ ├── .gitignore │ ├── MavenWrapperDownloader.java │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── docker │ ├── Dockerfile.jvm │ ├── Dockerfile.legacy-jar │ ├── Dockerfile.native │ └── Dockerfile.native-micro ├── java │ └── io │ │ └── quarkus │ │ └── workshop │ │ └── superheroes │ │ └── ui │ │ ├── Config.java │ │ └── EnvResource.java ├── resources │ └── application.properties └── webui │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── favicon.ico │ └── index.html │ └── src │ ├── app │ ├── App.js │ ├── App.test.js │ ├── fight-list │ │ ├── FightList.js │ │ └── FightList.test.js │ ├── fight │ │ ├── Fight.js │ │ └── Fight.test.js │ └── shared │ │ ├── .gitignore │ │ ├── api │ │ ├── fight-service.js │ │ └── fight-service.test.js │ │ └── git_push.sh │ ├── assets │ └── .gitkeep │ ├── index.js │ └── styles.css └── test └── java └── io └── quarkus └── workshop └── superheroes └── ui ├── EnvResourceTests.java └── WebUITests.java /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: maven 4 | directory: /quarkus-workshop-super-heroes 5 | open-pull-requests-limit: 40 6 | schedule: 7 | interval: daily 8 | labels: 9 | - "version-upgrade" 10 | pull-request-branch-name: 11 | separator: "_" 12 | - package-ecosystem: "github-actions" 13 | directory: "/" 14 | schedule: 15 | interval: daily 16 | labels: 17 | - infra 18 | pull-request-branch-name: 19 | separator: "_" 20 | -------------------------------------------------------------------------------- /.github/workflows/preview-teardown.yml: -------------------------------------------------------------------------------- 1 | name: Surge.sh Preview Teardown 2 | 3 | on: 4 | pull_request_target: 5 | types: [ closed ] 6 | 7 | jobs: 8 | preview-teardown: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Teardown surge preview 12 | id: deploy 13 | run: npx surge teardown https://quarkiverse-quarkus-workshops-pr-${{ github.event.number }}-preview.surge.sh --token ${{ secrets.SURGE_TOKEN }} || echo "NOT_TORNDOWN=true" >> "$GITHUB_ENV" 14 | - name: Update PR status comment 15 | uses: actions-cool/maintain-one-comment@v3.0.0 16 | if: env.NOT_TORNDOWN != 'true' 17 | with: 18 | token: ${{ secrets.GITHUB_TOKEN }} 19 | body: | 20 | 🙈 The PR is closed and the preview is expired. 21 | 22 | body-include: '' 23 | number: ${{ github.event.number }} 24 | -------------------------------------------------------------------------------- /.github/workflows/preview.yml: -------------------------------------------------------------------------------- 1 | name: Surge PR Preview 2 | 3 | on: 4 | workflow_run: 5 | workflows: [ "Build" ] 6 | types: 7 | - completed 8 | 9 | jobs: 10 | preview: 11 | runs-on: ubuntu-20.04 12 | if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' 13 | steps: 14 | - name: Download PR Artifact 15 | uses: dawidd6/action-download-artifact@v6 16 | with: 17 | run_id: ${{ github.event.workflow_run.id }} 18 | name: site 19 | - name: Store PR id as variable 20 | id: pr 21 | run: | 22 | echo "id=$(> $GITHUB_OUTPUT 23 | rm -f pr-id.txt 24 | - name: Publishing to surge for preview 25 | id: deploy 26 | run: npx surge ./ --domain https://quarkiverse-quarkus-workshops-pr-${{ steps.pr.outputs.id }}-preview.surge.sh --token ${{ secrets.SURGE_TOKEN }} 27 | - name: Update PR status comment on success 28 | uses: actions-cool/maintain-one-comment@v3.0.0 29 | with: 30 | token: ${{ secrets.GITHUB_TOKEN }} 31 | body: | 32 | 🚀 PR Preview ${{ github.sha }} has been successfully built and deployed to https://quarkiverse-quarkus-workshops-pr-${{ steps.pr.outputs.id }}-preview.surge.sh 33 | 34 | body-include: '' 35 | number: ${{ steps.pr.outputs.id }} 36 | - name: Update PR status comment on failure 37 | if: ${{ failure() }} 38 | uses: actions-cool/maintain-one-comment@v3.0.0 39 | with: 40 | token: ${{ secrets.GITHUB_TOKEN }} 41 | body: | 42 | 😭 Deploy PR Preview failed. 43 | 44 | body-include: '' 45 | number: ${{ steps.pr.outputs.id }} 46 | -------------------------------------------------------------------------------- /.github/workflows/zips.yml: -------------------------------------------------------------------------------- 1 | name: Generate zips 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths-ignore: 8 | - 'quarkus-workshop-super-heroes/docs/**' 9 | - 'quarkus-workshop-super-heroes/dist/**' 10 | jobs: 11 | build_java17: 12 | runs-on: ubuntu-latest 13 | concurrency: zip-generation 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: Install JDK 17 17 | uses: actions/setup-java@v4 18 | with: 19 | distribution: temurin 20 | java-version: 17 21 | - name: Microservices build with Maven 22 | run: mvn -B install --file quarkus-workshop-super-heroes/pom.xml 23 | - name: Native build with Maven 24 | run: mvn -B install --file quarkus-workshop-super-heroes/pom.xml -Pnative -Dquarkus.native.container-build=true -DskipITs -pl '!:rest-narration,!:extension-version' 25 | publication: 26 | needs: [ build_java17 ] 27 | runs-on: ubuntu-latest 28 | concurrency: zip-generation 29 | steps: 30 | - uses: actions/checkout@v4 31 | - name: Install JDK 17 32 | uses: actions/setup-java@v4 33 | with: 34 | distribution: temurin 35 | java-version: 17 36 | - name: Generate zips 37 | run: | 38 | cd quarkus-workshop-super-heroes/ 39 | mvn package -N 40 | - name: Commit zips 41 | run: | 42 | git config --global user.name 'Github Actions' 43 | git config --global user.email 'ci-action@users.noreply.github.com' 44 | git commit -am "Automated zip generation" 45 | git push 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | .DS_Store 3 | *.dylib 4 | ### JetBrains template 5 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 6 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 7 | 8 | # User-specific stuff: 9 | **/.idea/ 10 | 11 | ## File-based project format: 12 | **/*.iws 13 | **/*.iml 14 | 15 | ## Plugin-specific files: 16 | 17 | # IntelliJ 18 | out/ 19 | 20 | # mpeltonen/sbt-idea plugin 21 | .idea_modules/ 22 | 23 | # Package Files # 24 | *.tar.gz 25 | *.rar 26 | **/target 27 | *dummy* 28 | ObjectStore 29 | maven-wrapper.jar 30 | node_modules/ 31 | node/ 32 | 33 | .project 34 | .classpath 35 | .settings 36 | .factorypath 37 | 38 | 39 | # Semantic Kernel 40 | conf.properties -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hosts Quarkus related workshops 2 | 3 | * quarkus-workshop-super-heroes: workshop where you build several microservices interoperating through HTTP and Kafka. 4 | Instructions are available [here](https://quarkus.io/quarkus-workshops/super-heroes/). 5 | 6 | ## Configuring a workshop 7 | 8 | The [entry page of the workshop](https://quarkus.io/quarkus-workshops/super-heroes/) accepts query parameters. 9 | 10 | For 11 | example, https://quarkus.io/quarkus-workshops/super-heroes/index.html?native=false&ai=false&kubernetes=false&contract-testing=false&observability=false&extension=false&messaging=false&hideDefined=true 12 | will 13 | present a minimal workshop with no optional components, but allow people to select an operating system. 14 | The `hideDefined=true` locks and hides options which have been set in the url. 15 | 16 | As another example, https://quarkus.io/quarkus-workshops/super-heroes/index.html?os=mac would preconfigure the operating 17 | system to MacOS, 18 | and show all options. 19 | 20 | ## Continuous Build 21 | 22 | Each push and pull requests is checked using GitHub Actions. -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/.dockerignore: -------------------------------------------------------------------------------- 1 | **/target 2 | target 3 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | # We recommend you to keep these unchanged 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | # Change these settings to your own preference 16 | indent_style = space 17 | indent_size = 4 18 | 19 | [*.{ts, tsx, js, jsx, json, css, scss, yml, yaml}] 20 | indent_size = 2 21 | 22 | [*.md] 23 | trim_trailing_whitespace = false 24 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 19 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/dist/quarkus-super-heroes-workshop-complete.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/dist/quarkus-super-heroes-workshop-complete.zip -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/dist/quarkus-super-heroes-workshop-core.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/dist/quarkus-super-heroes-workshop-core.zip -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/dist/quarkus-super-heroes-workshop.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/dist/quarkus-super-heroes-workshop.zip -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/.gitignore: -------------------------------------------------------------------------------- 1 | # generated as part of the build 2 | src/docs/asciidoc/images/qrcode.png 3 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/css/github.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | github.com style (c) Vasily Polovnyov 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | color: #333; 12 | background: #f8f8f8; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-quote { 17 | color: #998; 18 | font-style: italic; 19 | } 20 | 21 | .hljs-keyword, 22 | .hljs-selector-tag, 23 | .hljs-subst { 24 | color: #333; 25 | font-weight: bold; 26 | } 27 | 28 | .hljs-number, 29 | .hljs-literal, 30 | .hljs-variable, 31 | .hljs-template-variable, 32 | .hljs-tag .hljs-attr { 33 | color: #008080; 34 | } 35 | 36 | .hljs-string, 37 | .hljs-doctag { 38 | color: #d14; 39 | } 40 | 41 | .hljs-title, 42 | .hljs-section, 43 | .hljs-selector-id { 44 | color: #900; 45 | font-weight: bold; 46 | } 47 | 48 | .hljs-subst { 49 | font-weight: normal; 50 | } 51 | 52 | .hljs-type, 53 | .hljs-class .hljs-title { 54 | color: #458; 55 | font-weight: bold; 56 | } 57 | 58 | .hljs-tag, 59 | .hljs-name, 60 | .hljs-attribute { 61 | color: #000080; 62 | font-weight: normal; 63 | } 64 | 65 | .hljs-regexp, 66 | .hljs-link { 67 | color: #009926; 68 | } 69 | 70 | .hljs-symbol, 71 | .hljs-bullet { 72 | color: #990073; 73 | } 74 | 75 | .hljs-built_in, 76 | .hljs-builtin-name { 77 | color: #0086b3; 78 | } 79 | 80 | .hljs-meta { 81 | color: #999; 82 | font-weight: bold; 83 | } 84 | 85 | .hljs-deletion { 86 | background: #fdd; 87 | } 88 | 89 | .hljs-addition { 90 | background: #dfd; 91 | } 92 | 93 | .hljs-emphasis { 94 | font-style: italic; 95 | } 96 | 97 | .hljs-strong { 98 | font-weight: bold; 99 | } 100 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/assets/webfonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/common-solution.adoc: -------------------------------------------------------------------------------- 1 | ifdef::give-solution[] 2 | [WARNING] 3 | ==== 4 | If you have any problem with the code, don't understand or feel you are running, remember to ask for some help. 5 | Also, you can get the code of this entire workshop from {github-url}. 6 | You can also download the completed code from {github-raw}/dist/quarkus-super-heroes-workshop-complete.zip. 7 | ==== 8 | endif::give-solution[] 9 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-appendix/appendix-preparing-warming-caches.adoc: -------------------------------------------------------------------------------- 1 | [[appendix-preparing-warming-caches]] 2 | = Warming the caches 3 | 4 | This workshop needs internet access to download all sorts of Maven artifacts, Docker images, and even pictures. 5 | Some of these artifacts are large, and because we have to share internet connexions at the workshop, it is better to download them before the workshop. 6 | 7 | If you're getting ready for a workshop, you might find it helpful to pre-download some Docker images. 8 | This can save strain on shared bandwidth. If, however, you're already attending a workshop, don't 9 | worry about warming anything up. 10 | 11 | include::appendix-preparing-warming-maven.adoc[leveloffset=+1] 12 | 13 | include::appendix-preparing-warming-docker.adoc[leveloffset=+1] 14 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-appendix/appendix-preparing-warming-maven.adoc: -------------------------------------------------------------------------------- 1 | = Warming up Maven 2 | 3 | == Download the workshop scaffolding 4 | 5 | [example, role="cta"] 6 | -- 7 | 8 | First, download the zip file {github-raw}/dist/quarkus-super-heroes-workshop.zip, and unzip it wherever you want. 9 | This zip file contains _some_ of the code of the workshop, and you will need to complete it. 10 | -- 11 | 12 | == Download the Maven dependencies 13 | 14 | [example, role="cta"] 15 | -- 16 | 17 | Now that you have the initial structure in place, navigate to the root directory and run: 18 | 19 | 20 | [source,shell] 21 | ---- 22 | ./mvnw clean install 23 | ---- 24 | -- 25 | 26 | By running this command, it downloads all the required dependencies. 27 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-appendix/appendix.adoc: -------------------------------------------------------------------------------- 1 | [appendix] 2 | = Installing extra software 3 | 4 | include::appendix-installing-maven.adoc[leveloffset=+1] 5 | 6 | include::appendix-installing-curl.adoc[leveloffset=+1] 7 | 8 | include::appendix-preparing-warming-caches.adoc[leveloffset=+1] 9 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-conclusion/conclusion-references.adoc: -------------------------------------------------------------------------------- 1 | [[conclusion-references]] 2 | = References 3 | 4 | * https://quarkus.io/quarkus-workshops/super-heroes 5 | * https://github.com/cescoffier/quarkus-todo-app 6 | * https://github.com/agoncal/baking-microservice-pie 7 | * https://forge.jboss.org/document/hands-on-lab 8 | * https://bit.ly/forge-hol 9 | * https://quarkus.io 10 | * https://code.quarkus.io 11 | * https://quarkus.io/guides/all-config 12 | * https://azure.microsoft.com/services/container-apps[Azure Container Apps Overview] 13 | * https://docs.microsoft.com/azure/container-apps[Azure Container Apps Documentation] 14 | * https://github.com/ozangunalp/managed-kafka-quarkus/tree/main/azure-event-hub[Managed Kafka Quarkus] 15 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-introduction/introduction-email.adoc: -------------------------------------------------------------------------------- 1 | [[introduction-email]] 2 | = Getting Ready for the Quarkus Workshop 3 | 4 | Hi all, 5 | 6 | The workshop is approaching, and soon we will all be spending a bit of time coding some microservices with Quarkus! 7 | Aren't you excited about it? 8 | 9 | But before we start coding, *we want you to install a few tools* so the workshop goes smoothly. 10 | As you will see, the microservice architecture that we will be developing is exceptionally rich in terms of technologies: 11 | We need a few tools installed, repositories to be filled, and Docker images to be downloaded. 12 | So please, find attached a PDF document introducing the workshop and explaining how to install the needed tools. 13 | If you have any problem following this guide, ping us by email to help you. 14 | 15 | See you soon. 16 | 17 | The authors 18 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-introduction/introduction-installing-azure-cli.adoc: -------------------------------------------------------------------------------- 1 | [[azure-intro-installing-azure-cli]] 2 | = Azure CLI 3 | 4 | The Azure command-line interface (https://docs.microsoft.com/cli/azure[Azure CLI)] is a set of commands used to create and manage Azure resources. 5 | The Azure CLI is available across Azure services and is designed to get you working quickly with Azure, with an emphasis on automation. 6 | For this workshop you need to have Azure CLI installed locally on your machine. 7 | 8 | == Installing Azure CLI 9 | 10 | The https://docs.microsoft.com/cli/azure/install-azure-cli[Azure CLI is available to install] in Windows, macOS and Linux environments. 11 | It can also be run in a Docker container and Azure Cloud Shell. 12 | On Mac OS X, the easiest way to install Azure CLI is by executing the following command: 13 | 14 | [source,shell] 15 | ---- 16 | brew install azure-cli 17 | ---- 18 | 19 | == Checking for Azure CLI Installation 20 | 21 | Once the installation is complete, you can execute a few commands to be sure the Azure CLI is correctly installed: 22 | 23 | [source,shell] 24 | ---- 25 | az version 26 | az --version 27 | ---- 28 | 29 | == Some Azure CLI Commands 30 | 31 | Azure CLI is a command-line utility where you can use several parameters and options to create, query, or delete Azure resources. 32 | To get some help on the commands, you can type: 33 | 34 | [source,shell] 35 | ---- 36 | az help 37 | az --help 38 | az vm --help 39 | az vm disk --help 40 | az vm disk attach --help 41 | ---- 42 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-introduction/introduction-installing-git.adoc: -------------------------------------------------------------------------------- 1 | [[introduction-installing-git]] 2 | 3 | = Git 4 | 5 | Git{wj}footnote:[Git https://git-scm.com] is a free and open source distributed version control system designed for tracking changes in computer files and coordinating work on those files among multiple people. 6 | It is primarily used for source code management in software development, but it can be used to keep track of changes in any set of files. 7 | Git was created by Linus Torvalds in 2005 for the development of the Linux kernel, with other kernel developers contributing to its initial development. 8 | 9 | ifdef::use-mac[] 10 | == Installing Git 11 | 12 | On Mac, if you have installed Homebrew, then installing Git is just a matter of a single command. 13 | Open your terminal and install Git with the following command: 14 | 15 | [source,shell] 16 | ---- 17 | $ brew install git 18 | ---- 19 | endif::use-mac[] 20 | 21 | == Checking for Git Installation 22 | 23 | Once installed, check for Git by running `git --version` in the terminal. 24 | It should display the git version: 25 | 26 | [source,term] 27 | ---- 28 | $ git --version 29 | ---- 30 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-introduction/introduction-installing-jq.adoc: -------------------------------------------------------------------------------- 1 | [[appendix-installing-jq]] 2 | 3 | = jq 4 | 5 | Very often, when using cURL to invoke a RESTful web service, we get some JSON payload. 6 | cURL does not format this JSON so that you will get a flat String such as: 7 | 8 | [source,shell] 9 | ---- 10 | curl http://localhost:8083/api/heroes 11 | [{"id":"1","name":"Chewbacca","level":"14"},{"id":"2","name":"Wonder Woman","level":"15"},{"id":"3","name":"Anakin Skywalker","level":"8"}] 12 | ---- 13 | 14 | But what we want is to format the JSON payload, so it is easier to read. 15 | For that, there is a neat utility tool called `jq` that we could use. 16 | `jq` is a tool for processing JSON inputs, applying the given filter to its JSON text inputs, and producing the filter's results as JSON on standard output.footnote:[jq https://stedolan.github.io/jq] 17 | 18 | == Installing jq 19 | 20 | ifdef::use-mac[You can install it on Mac OSX with a simple `brew install jq`.] 21 | 22 | == Checking for jq Installation 23 | 24 | Once installed, it's just a matter of piping the cURL output to jq like this: 25 | 26 | [source,shell] 27 | ---- 28 | curl http://localhost:8083/api/heroes | jq 29 | 30 | [ 31 | { 32 | "id": "1", 33 | "name": "Chewbacca", 34 | "lastName": "14" 35 | }, 36 | { 37 | "id": "2", 38 | "name": "Wonder Woman", 39 | "lastName": "15" 40 | }, 41 | { 42 | "id": "3", 43 | "name": "Anakin Skywalker", 44 | "lastName": "8" 45 | } 46 | ] 47 | ---- 48 | 49 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-introduction/introduction-installing-wsl.adoc: -------------------------------------------------------------------------------- 1 | [[azure-intro-installing-wsl]] 2 | = WSL 3 | 4 | https://docs.microsoft.com/windows/wsl[Windows Subsystem for Linux] (WSL) lets developers run a GNU/Linux environment -- including most command-line tools, utilities, and applications -- directly on Windows, unmodified, without the overhead of a traditional virtual machine or dual-boot setup. 5 | 6 | [WARNING] 7 | ==== 8 | If you are using Windows, it is recommended to install WSL as all the commands use bash. 9 | ==== 10 | 11 | == Installing WSL 12 | 13 | You can install everything you need to run Windows Subsystem for Linux (WSL) by entering this command in an administrator PowerShell or Windows Command Prompt and then restarting your machine: 14 | 15 | [source,shell] 16 | ---- 17 | wsl --install 18 | ---- 19 | 20 | This command will enable the required optional components, download the latest Linux kernel, set WSL 2 as your default, and install a Linux distribution for you (Ubuntu by default). 21 | 22 | The first time you launch a newly installed Linux distribution, a console window will open and you'll be asked to wait for files to de-compress and be stored on your machine. 23 | All future launches should take less than a second. 24 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-introduction/introduction-installing.adoc: -------------------------------------------------------------------------------- 1 | [[introduction-installing]] 2 | = Installing Software 3 | 4 | include::introduction-installing-jdk.adoc[leveloffset=+1] 5 | 6 | include::introduction-installing-docker.adoc[leveloffset=+1] 7 | 8 | include::introduction-installing-jq.adoc[leveloffset=+1] 9 | 10 | ifdef::use-native[] 11 | include::introduction-installing-graalvm.adoc[leveloffset=+1] 12 | endif::use-native[] 13 | 14 | ifdef::use-local-kubernetes[] 15 | include::introduction-installing-rancher.adoc[leveloffset=+1] 16 | endif::use-local-kubernetes[] 17 | 18 | ifdef::use-ai[] 19 | include::introduction-installing-ai.adoc[leveloffset=+1] 20 | endif::use-ai[] 21 | 22 | ifdef::use-windows[] 23 | include::introduction-installing-wsl.adoc[leveloffset=+1] 24 | endif::use-windows[] 25 | 26 | ifdef::use-azure[] 27 | include::introduction-installing-azure-cli.adoc[leveloffset=+1] 28 | endif::use-azure[] 29 | 30 | == Recap 31 | 32 | Before going further, make sure the following commands work on your machine. 33 | 34 | [source,shell] 35 | ---- 36 | java -version 37 | ifdef::use-native[] 38 | $GRAALVM_HOME/bin/native-image --version 39 | endif::use-native[] 40 | curl --version 41 | docker version 42 | docker compose version 43 | ifdef::use-local-kubernetes[] 44 | kubectl version # If you used Rancher Desktop and plan to use Kubernetes 45 | endif::use-local-kubernetes[] 46 | ifdef::use-azure[] 47 | az --version 48 | endif::use-azure[] 49 | ---- 50 | 51 | We have not mentioned cURL up to now, because most modern operating systems ship with it pre-installed. 52 | If your system is missing cURL, the appendix includes xref:appendix-installing-curl[instructions for installing cURL]. 53 | 54 | ifdef::use-ai[] 55 | And also make sure to have your OpenAI or Azure credentials ready if you want to develop the "Narration" microservice. 56 | endif::use-ai[] 57 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-introduction/introduction-preparing-checking-ports.adoc: -------------------------------------------------------------------------------- 1 | [[introduction-preparing-checking-ports]] 2 | = Checking Ports 3 | 4 | During this workshop, we will use several ports. 5 | 6 | [example, role="cta"] 7 | -- 8 | Use `lsof` to make sure the following ports are free, so you don't run into any conflicts. 9 | 10 | [source,shell] 11 | ---- 12 | lsof -i tcp:8080 # UI 13 | lsof -i tcp:8082 # Fight REST API 14 | lsof -i tcp:8083 # Hero REST API 15 | lsof -i tcp:8084 # Villain REST API 16 | ifdef::use-messaging[] 17 | lsof -i tcp:8085 # Statistics REST API 18 | endif::use-messaging[] 19 | ifdef::use-ai[] 20 | lsof -i tcp:8086 # Narration REST API 21 | endif::use-ai[] 22 | lsof -i tcp:5432 # Postgres 23 | ifdef::use_observability[] 24 | lsof -i tcp:9090 # Prometheus 25 | endif::use_observability[] 26 | ifdef::use-messaging[] 27 | lsof -i tcp:2181 # Zookeeper 28 | lsof -i tcp:9092 # Kafka 29 | endif::use-messaging[] 30 | ---- 31 | -- 32 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-introduction/style.puml: -------------------------------------------------------------------------------- 1 | skinparam dpi 300 2 | skinparam useBetaStyle true 3 | skinparam handwritten true 4 | allow_mixing 5 | 6 | skinparam node { 7 | ArrowColor aqua 8 | 9 | borderColor #566573 10 | backgroundColor #F9E79F 11 | fontName Calibri 12 | fontSize 17 13 | fontColor #566573 14 | } 15 | 16 | skinparam database { 17 | borderColor #566573 18 | backgroundColor #D5F5E3 19 | } 20 | 21 | skinparam agent { 22 | backgroundColor<> #D2B4DE 23 | backgroundColor<> #FAE5D3 24 | } 25 | 26 | skinparam arrow { 27 | fontName Calibri 28 | color #FF6655 29 | fontColor #777777 30 | thickness 2 31 | fontSize 11 32 | } 33 | 34 | skinparam class { 35 | backgroundColor #FAE5D3 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-microservices/microservices.adoc: -------------------------------------------------------------------------------- 1 | [[microservices]] 2 | = From Microservice to Microservices 3 | 4 | ''' 5 | 6 | So far we've built two microservices: the villains and heroes microservices. 7 | In the following sections you will develop an extra microservice: a _fight_ microservice where heroes and villains fight. 8 | We will also add a React front-end, so we can fight graphically. 9 | But as you can notice in the diagram below, these microservices still not communicate with each other. 10 | You will have to wait the next chapter for that ;o) 11 | 12 | [plantuml,align=center] 13 | ---- 14 | include::{plantDir}/4-microservices-physical-architecture.puml[] 15 | ---- 16 | 17 | Each microservice is developed in its own directory. 18 | 19 | [plantuml] 20 | ---- 21 | @startsalt 22 | { 23 | { 24 | T 25 | super-heroes 26 | + infrastructure 27 | + rest-fights 28 | ++ src 29 | +++ main 30 | +++ test 31 | + rest-heroes 32 | ++ src 33 | +++ main 34 | +++ test 35 | + rest-villains 36 | ++ src 37 | +++ main 38 | +++ test 39 | + ui-super-heroes 40 | ++ src 41 | +++ app 42 | +++ main 43 | } 44 | } 45 | @endsalt 46 | ---- 47 | 48 | In the following sections, you will: 49 | 50 | * Create a new Quarkus application 51 | * Implement REST API using JAX-RS 52 | * Access your database using Hibernate ORM with Panache 53 | * Use transactions 54 | 55 | IMPORTANT: This service is exposed on the port 8082. 56 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-microservices/style.puml: -------------------------------------------------------------------------------- 1 | skinparam dpi 300 2 | skinparam useBetaStyle true 3 | skinparam handwritten true 4 | allow_mixing 5 | 6 | skinparam node { 7 | ArrowColor aqua 8 | 9 | borderColor #566573 10 | backgroundColor #F9E79F 11 | fontName Calibri 12 | fontSize 17 13 | fontColor #566573 14 | } 15 | 16 | skinparam database { 17 | borderColor #566573 18 | backgroundColor #D5F5E3 19 | } 20 | 21 | skinparam agent { 22 | backgroundColor<> #D2B4DE 23 | backgroundColor<> #FAE5D3 24 | } 25 | 26 | skinparam arrow { 27 | fontName Calibri 28 | color #FF6655 29 | fontColor #777777 30 | thickness 2 31 | fontSize 11 32 | } 33 | 34 | skinparam class { 35 | backgroundColor #FAE5D3 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-quarkus/quarkus-augmentation.adoc: -------------------------------------------------------------------------------- 1 | [[quarkus-augmentation]] 2 | = Quarkus Augmentation 3 | 4 | Let's demystify all this. 5 | 6 | So far, you have developed the super-villains microservice. 7 | This microservice is relatively simple. 8 | It still has database access, ORM support, transaction, JSON serialization, and deserialization. 9 | 10 | [example, role="cta"] 11 | -- 12 | Let's now package this application using: 13 | 14 | [source,shell] 15 | ---- 16 | ./mvnw package 17 | ---- 18 | -- 19 | 20 | In the log, you can see actions happening during what Quarkus calls the _augmentation_ phase. 21 | 22 | [source,shell,subs="attributes+"] 23 | ---- 24 | [INFO] --- quarkus-maven-plugin:{quarkus-version}:build (default) @ rest-villains --- 25 | [INFO] [org.jboss.threads] JBoss Threads version 3.4.2.Final 26 | [INFO] [org.hibernate.Version] HHH000412: Hibernate ORM core version 5.5.7.Final 27 | [INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 1932ms 28 | ---- 29 | 30 | In this log, you can observe the _build_ principle. 31 | Typically, about Hibernate, it saves from having to: 32 | 33 | 1. embed an XML parser at runtime, 34 | 2. Do the actual parsing, 35 | 3. Configure Hibernate based on the content of the file. 36 | 37 | With Quarkus, at runtime, almost everything is already configured. 38 | Only runtime configuration properties are applied at startup (such as database URLs). 39 | 40 | Also, during this augmentation, Java classes are generated or extended. 41 | Remember the `Villain` Panache entity. 42 | The class is extended during the _augmentation_. 43 | If you run `javap --class-path target/quarkus-app/quarkus/transformed-bytecode.jar io.quarkus.workshop.superheroes.villain.Villain`, you can see methods prefixed with `$$` added to the class. 44 | 45 | Each _extension_ can combine build time and run time. 46 | The following figure presents some of the extensions you already used, but there are a lot more. 47 | We are going to learn more about extensions later in this workshop and even build one. 48 | What's important to understand for now is that the magic is packaged into extension, and every time you add a `quarkus-` dependency to your `pom.xml` file, you enable an extension. 49 | 50 | image::quarkus-extensions.png[role=half-size] 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-quarkus/quarkus.adoc: -------------------------------------------------------------------------------- 1 | [[quarkus]] 2 | = Quarkus 3 | 4 | ''' 5 | 6 | In the previous chapter, you had a quick peek at Quarkus and how you can build HTTP / REST-based applications with it. 7 | But that was just the beginning; Quarkus can do a lot more, which is the purpose of this chapter. 8 | In this chapter, you are going to see: 9 | 10 | * What's Quarkus? and how does it change the Java landscape 11 | * What are the main Quarkus idea, and how it helps in the _cloud native world_ 12 | * The Quarkus build process, in other words, the _secret sauce number 1_ 13 | * The Quarkus reactive nature, in other words, the _secret sauce number 2_ 14 | * Some Quarkus features such as the application lifecycle support 15 | ifdef::use-native[] 16 | * How you can use Quarkus to generate native executable 17 | endif::use-native[] 18 | 19 | include::quarkus-definition.adoc[leveloffset=+1] 20 | 21 | Quarkus does not stop there. 22 | As you have seen in the previous chapter, it proposes a stellar developer experience. 23 | It also unifies reactive and imperative to let you decide how you want to handle I/O. It allows implementing both REST and event-driven applications using a consistent model. 24 | To do this, Quarkus is based on a reactive core allowing high concurrency and reducing memory consumption. 25 | 26 | // TODO IMAGE 27 | 28 | Quarkus detects if your method can be called on the I/O thread and follows the reactive execution model; or if your method must be called on a worker thread and follows the imperative execution model. 29 | 30 | // TODO IMAGE 31 | 32 | Ok, but enough talking, time to see this in action. 33 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-reactive/style.puml: -------------------------------------------------------------------------------- 1 | skinparam dpi 300 2 | skinparam useBetaStyle true 3 | skinparam handwritten true 4 | allow_mixing 5 | 6 | skinparam node { 7 | ArrowColor aqua 8 | 9 | borderColor #566573 10 | backgroundColor #F9E79F 11 | fontName Calibri 12 | fontSize 17 13 | fontColor #566573 14 | } 15 | 16 | skinparam database { 17 | borderColor #566573 18 | backgroundColor #D5F5E3 19 | } 20 | 21 | skinparam agent { 22 | backgroundColor<> #D2B4DE 23 | backgroundColor<> #FAE5D3 24 | } 25 | 26 | skinparam arrow { 27 | fontName Calibri 28 | color #FF6655 29 | fontColor #777777 30 | thickness 2 31 | fontSize 11 32 | } 33 | 34 | skinparam class { 35 | backgroundColor #FAE5D3 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-rest-client/rest-client.adoc: -------------------------------------------------------------------------------- 1 | [[rest-client]] 2 | = HTTP communication & Fault Tolerance 3 | 4 | ''' 5 | 6 | So far we've built one Fight microservice which need to invoke the Hero and Villain microservices. 7 | In the following sections you will develop this invocation thanks to the MicroProfile REST Client. 8 | We will also deal with fault tolerance thanks to timeouts and circuit breaker. 9 | 10 | [plantuml,align=center] 11 | ---- 12 | include::{plantDir}/5-rest-client-physical-architecture.puml[] 13 | ---- 14 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-rest-client/style.puml: -------------------------------------------------------------------------------- 1 | skinparam dpi 300 2 | skinparam useBetaStyle true 3 | skinparam handwritten true 4 | allow_mixing 5 | 6 | skinparam node { 7 | ArrowColor aqua 8 | 9 | borderColor #566573 10 | backgroundColor #F9E79F 11 | fontName Calibri 12 | fontSize 17 13 | fontColor #566573 14 | } 15 | 16 | skinparam database { 17 | borderColor #566573 18 | backgroundColor #D5F5E3 19 | } 20 | 21 | skinparam agent { 22 | backgroundColor<> #D2B4DE 23 | backgroundColor<> #FAE5D3 24 | } 25 | 26 | skinparam arrow { 27 | fontName Calibri 28 | color #FF6655 29 | fontColor #777777 30 | thickness 2 31 | fontSize 11 32 | } 33 | 34 | skinparam class { 35 | backgroundColor #FAE5D3 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-rest/rest.adoc: -------------------------------------------------------------------------------- 1 | [[rest]] 2 | = Creating a _classical_ REST/HTTP Microservice 3 | 4 | ''' 5 | 6 | At the heart of the Super-Hero application comes Villains! 7 | You can't have superheroes without super-villains. 8 | 9 | We need to expose a REST API allowing CRUD operations on villains. 10 | This microservice is, let's say, a _classical_ REST microservice. 11 | It uses HTTP to expose a REST API and internally store data into a database. 12 | It's using the _imperative_ development model. 13 | 14 | The _fight_ microservice will use this service. 15 | 16 | [plantuml,align=center,width=300] 17 | ---- 18 | include::{plantDir}/1-rest-physical-architecture.puml[] 19 | ---- 20 | 21 | In the following sections, you learn: 22 | 23 | * How to create a new Quarkus application 24 | * How to implement REST API using JAX-RS and the Quarkus REST extension footnote:[Quarkus REST supports the reactive and imperative development models.] 25 | * How to compose your application using beans 26 | * How to access your database using Hibernate ORM with Panache 27 | * How to use transactions 28 | * How to enable OpenAPI and Swagger-UI 29 | 30 | IMPORTANT: This service is exposed on the port 8084. 31 | 32 | But first, let's describe our service. 33 | The Super-Villains microservice manages villains with their names, powers, and so on. 34 | The REST API allows adding, removing, listing, and picking a random villain from the stored set. 35 | Nothing outstanding but a good first step to discover Quarkus. 36 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/core-rest/style.puml: -------------------------------------------------------------------------------- 1 | skinparam dpi 300 2 | skinparam useBetaStyle true 3 | skinparam handwritten true 4 | allow_mixing 5 | 6 | skinparam node { 7 | ArrowColor aqua 8 | 9 | borderColor #566573 10 | backgroundColor #F9E79F 11 | fontName Calibri 12 | fontSize 17 13 | fontColor #566573 14 | } 15 | 16 | skinparam database { 17 | borderColor #566573 18 | backgroundColor #D5F5E3 19 | } 20 | 21 | skinparam agent { 22 | backgroundColor<> #D2B4DE 23 | backgroundColor<> #FAE5D3 24 | } 25 | 26 | skinparam arrow { 27 | fontName Calibri 28 | color #FF6655 29 | fontColor #777777 30 | thickness 2 31 | fontSize 11 32 | } 33 | 34 | skinparam class { 35 | backgroundColor #FAE5D3 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/default-options.adoc: -------------------------------------------------------------------------------- 1 | // Make sure the defaults here are kept in sync with 2 | // both generate-attribute-combinations.sh and index.html! 3 | :os: all 4 | :use-ai: 5 | :use-azure: 6 | :use-cli: 7 | :use-container: 8 | :use-contract-testing: 9 | :use-extension: 10 | :use-kubernetes: 11 | :use-messaging: 12 | :use-native: 13 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/docinfo-footer.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-aca-compute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-aca-compute.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-aca-concepts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-aca-concepts.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-aca-intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-aca-intro.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-aca-qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-aca-qrcode.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-portal-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-portal-2.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-portal-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-portal-3.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-portal-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/azure-portal-4.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/blank-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/blank-ui.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/cors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/cors.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/fault-tolerance-fallback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/fault-tolerance-fallback.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/fault-tolerance-pending.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/fault-tolerance-pending.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/fault-tolerance-prometheus-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/fault-tolerance-prometheus-1.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/fault-tolerance-prometheus-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/fault-tolerance-prometheus-2.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/fault-tolerance-prometheus-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/fault-tolerance-prometheus-3.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/observability-health-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/observability-health-ui.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/openai-fund.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/openai-fund.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/openai-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/openai-key.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/openai-org.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/openai-org.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/quarkus-augmentation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/quarkus-augmentation.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/quarkus-build-time-principle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/quarkus-build-time-principle.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/quarkus-extensions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/quarkus-extensions.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/quarkus-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/quarkus-logo.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/quarkus-native-compilation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/quarkus-native-compilation.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/react-ui-ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/react-ui-ai.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/react-ui-stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/react-ui-stats.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/react-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/react-ui.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/rest-openapi-swaggerui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/rest-openapi-swaggerui.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/semantic-kernel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/docs/src/docs/asciidoc/images/semantic-kernel.png -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/optional-ai/style.puml: -------------------------------------------------------------------------------- 1 | skinparam dpi 300 2 | skinparam useBetaStyle true 3 | skinparam handwritten true 4 | allow_mixing 5 | 6 | skinparam node { 7 | ArrowColor aqua 8 | 9 | borderColor #566573 10 | backgroundColor #F9E79F 11 | fontName Calibri 12 | fontSize 17 13 | fontColor #566573 14 | } 15 | 16 | skinparam database { 17 | borderColor #566573 18 | backgroundColor #D5F5E3 19 | } 20 | 21 | skinparam agent { 22 | backgroundColor<> #D2B4DE 23 | backgroundColor<> #FAE5D3 24 | } 25 | 26 | skinparam arrow { 27 | fontName Calibri 28 | color #FF6655 29 | fontColor #777777 30 | thickness 2 31 | fontSize 11 32 | } 33 | 34 | skinparam class { 35 | backgroundColor #FAE5D3 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/optional-azure-container-apps/azure-aca-administrating.adoc: -------------------------------------------------------------------------------- 1 | [[azure-aca-monitoring]] 2 | = Monitoring the Application on Azure Container Apps 3 | 4 | == Restarting a Microservice 5 | 6 | If you need to restart a microservice, you need to actually restart the active revision. 7 | For that, first get the active revision: 8 | 9 | ```shell 10 | az containerapp revision list \ 11 | --resource-group "$RESOURCE_GROUP" \ 12 | --name "$FIGHTS_APP" \ 13 | --output table 14 | ``` 15 | 16 | Then, restart it: 17 | 18 | ```shell 19 | az containerapp revision restart \ 20 | --resource-group "$RESOURCE_GROUP" \ 21 | --app "$FIGHTS_APP" \ 22 | --name rest-fights-app--mh396rg 23 | ``` 24 | 25 | == Redeploying a new version of a microservice 26 | 27 | If you need to push a new version of a Docker image, make sure it has a different tag. 28 | Then, update the container with this new tagged image: 29 | 30 | ```shell 31 | az containerapp update \ 32 | --resource-group "$RESOURCE_GROUP" \ 33 | --image quay.io/quarkus-super-heroes/rest-fights:azure2 \ 34 | --name "$FIGHTS_APP" 35 | ``` 36 | 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/optional-azure-container-apps/azure-cleaning-up.adoc: -------------------------------------------------------------------------------- 1 | = Cleaning Up Azure Resources 2 | 3 | Do NOT forget to remove the Azure resources once you are done running the workshop. 4 | 5 | [source,shell] 6 | ---- 7 | az group delete \ 8 | --name "$RESOURCE_GROUP" 9 | ---- 10 | 11 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/optional-kubernetes/kubernetes-open-shift.adoc: -------------------------------------------------------------------------------- 1 | [[cloud-open-shift]] 2 | = Deploying to Open Shift 3 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/optional-load/load.adoc: -------------------------------------------------------------------------------- 1 | [[load]] 2 | = Loading the Microservices 3 | 4 | 5 | Now that we have the three main microservices exposing health checks and metrics, time to have a decent user interface to monitor how the system behaves. 6 | The purpose of this workshop is to add some load to our application. 7 | You will download the load application, install it and run it. 8 | 9 | == Give me some load! 10 | 11 | In the `super-heroes/load-super-heroes` directory, there is a command line Quarkus application . 12 | This application simulates users interacting with the system so it generates some load. 13 | 14 | == Looking at Some Code 15 | 16 | The `CLIMain` class is just a Picocli extension command line application that executes the `FightScenario`, `HeroScenario` and `VillainScenario`, 17 | on the same thread but randomly executing 3 different random calls to the 3 REST APIs. 18 | For example, if you look at the `HeroScenario`, you will see that it's just a suit of HTTP calls on the Hero API: 19 | 20 | [source,indent=0] 21 | ---- 22 | include::{projectdir}/load-super-heroes/src/main/java/io/quarkus/workshop/superheroes/load/scenarios/HeroScenario.java[tag=adocScenario] 23 | ---- 24 | 25 | == Running the Load Application 26 | 27 | [example, role="cta"] 28 | -- 29 | You are all set! 30 | Time to compile and start the load application using: 31 | 32 | [source,shell] 33 | ---- 34 | ./mvnw package 35 | java -jar ./target/quarkus-app/quarkus-run.jar -s 36 | ---- 37 | -- 38 | 39 | You will see the following logs. To stop the load, write something and press Enter key. 40 | 41 | [source,shell] 42 | ---- 43 | INFO: GET - http://localhost:8082/api/fights/1 - 200 44 | INFO: DELETE - http://localhost:8084/api/villains/440 - 204 45 | INFO: GET - http://localhost:8083/api/heroes - 200 46 | INFO: GET - http://localhost:8084/api/villains/hello - 200 47 | INFO: GET - http://localhost:8082/api/fights - 200 48 | INFO: GET - http://localhost:8083/api/heroes/581 - 200 49 | INFO: GET - http://localhost:8084/api/villains/126 - 200 50 | INFO: GET - http://localhost:8082/api/fights/hello - 200 51 | INFO: DELETE - http://localhost:8083/api/heroes/491 - 204 52 | ---- 53 | 54 | [NOTE] 55 | ==== 56 | Stop the load application before going further. 57 | ==== 58 | 59 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/optional-messaging/messaging-conclusion.adoc: -------------------------------------------------------------------------------- 1 | [[messaging-conclusion]] 2 | = Unifying Imperative and Reactive Programming 3 | 4 | So, as seen in this chapter, Quarkus is not limited to HTTP microservices, but fits perfectly in an event-driven architecture. 5 | The secret behind this is to use a single reactive engine for both imperative and reactive code: 6 | 7 | [plantuml,align=center] 8 | ---- 9 | include::{plantDir}/6-quarkus-http-architecture.puml[] 10 | ---- 11 | 12 | This unique architecture allows mixing imperative and reactive, but also use the right _model_ for the job. 13 | To go further on this, we recommend: 14 | 15 | * https://quarkus.io/guides/reactive-routes-guide to use reactive routes 16 | * https://quarkus.io/guides/reactive-sql-clients to access SQL database in a non-blocking fashion 17 | * https://quarkus.io/guides/kafka-guide to integrate with Kafka 18 | * https://quarkus.io/guides/amqp-guide to integrate with AMQP 1.0 19 | * https://quarkus.io/guides/using-vertx to understand how you can use Vert.x directly 20 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/optional-messaging/messaging.adoc: -------------------------------------------------------------------------------- 1 | [[messaging]] 2 | = Event-driven and Reactive microservices 3 | 4 | ''' 5 | 6 | So far, we have build microservices that all use HTTP to interact. 7 | However, HTTP has significant flaws, such as temporal coupling between the different microservices. 8 | If the service is not there or is slow, the caller is directly impacted. 9 | Also, it's hard to guess the capacity of the service you call; maybe you should not call it right now because this service is under heavy load. 10 | 11 | Fortunately, event-driven microservices are rising and avoid most of these issues. 12 | By using events (wrapped in messages), the different microservices enforce a looser coupling. 13 | Depending on the messaging protocol you use, it may handle durability (avoiding the temporal coupling) and back-pressure (avoiding the overload). 14 | 15 | In this section, we are going to see how Quarkus let you build event-driven microservices. 16 | More specially, you are going to see how to: 17 | 18 | * Send messages and process them 19 | * Connect a Quarkus application to Apache Kafka 20 | * Write Kafka records and read them 21 | * Use reactive programming to compute statistics on the fly 22 | * Send messages to the browser using web sockets 23 | 24 | Quarkus uses MicroProfile Reactive Messaging to interact with Apache Kafka, and other messaging middleware (such as AMQP).footnote:[MicroProfile Reactive Messaging https://github.com/eclipse/microprofile-reactive-messaging] 25 | 26 | In this chapter, we are going to use events as a way for microservices to interact. 27 | You are going to extend the current system with the `stats` group depicted on the next figure: 28 | 29 | [plantuml,align=center] 30 | ---- 31 | include::{plantDir}/6-messaging-physical-architecture.puml[] 32 | ---- 33 | 34 | When the application persists a new fight, in the _fight_ microservice, you are going to send it to a Kafka topic. 35 | These messages are read in the _statistics_ microservice, processed, and the result is sent to a UI using web sockets. 36 | 37 | IMPORTANT: This service is exposed on the port 8085. 38 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/optional-messaging/style.puml: -------------------------------------------------------------------------------- 1 | skinparam dpi 300 2 | skinparam useBetaStyle true 3 | skinparam handwritten true 4 | allow_mixing 5 | 6 | skinparam node { 7 | ArrowColor aqua 8 | 9 | borderColor #566573 10 | backgroundColor #F9E79F 11 | fontName Calibri 12 | fontSize 17 13 | fontColor #566573 14 | } 15 | 16 | skinparam database { 17 | borderColor #566573 18 | backgroundColor #D5F5E3 19 | } 20 | 21 | skinparam agent { 22 | backgroundColor<> #D2B4DE 23 | backgroundColor<> #FAE5D3 24 | } 25 | 26 | skinparam arrow { 27 | fontName Calibri 28 | color #FF6655 29 | fontColor #777777 30 | thickness 2 31 | fontSize 11 32 | } 33 | 34 | skinparam class { 35 | backgroundColor #FAE5D3 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/optional-observability/observability.adoc: -------------------------------------------------------------------------------- 1 | [[observability]] 2 | = Observability 3 | 4 | ''' 5 | 6 | Now that we have several microservices, observing them starts to be a bit tricky: 7 | we can't just look at the logs of all the microservices to see if they are up and running or behaving correctly. 8 | In the following sections you will add health checks and several metrics to the Fight, Hero and Villain APIs and gather them within Prometheus. 9 | 10 | [plantuml,align=center] 11 | ---- 12 | include::{plantDir}/7-observability-physical-architecture.puml[] 13 | ---- 14 | 15 | In the following sections, you will learn how to: 16 | 17 | * Add health checks to our microservices 18 | // TODO once metrics and Prometheus are added 19 | //* Add metrics 20 | //* Use Quarkus and PicoCLI to load our system 21 | //* Monitor the entire system with Prometheus 22 | // 23 | //IMPORTANT: Prometheus is exposed on the port 9090. 24 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/optional-quarkus-extension/style.puml: -------------------------------------------------------------------------------- 1 | skinparam dpi 300 2 | skinparam useBetaStyle true 3 | skinparam handwritten true 4 | allow_mixing 5 | 6 | skinparam node { 7 | ArrowColor aqua 8 | 9 | borderColor #566573 10 | backgroundColor #F9E79F 11 | fontName Calibri 12 | fontSize 17 13 | fontColor #566573 14 | } 15 | 16 | skinparam database { 17 | borderColor #566573 18 | backgroundColor #D5F5E3 19 | } 20 | 21 | skinparam agent { 22 | backgroundColor<> #D2B4DE 23 | backgroundColor<> #FAE5D3 24 | } 25 | 26 | skinparam arrow { 27 | fontName Calibri 28 | color #FF6655 29 | fontColor #777777 30 | thickness 2 31 | fontSize 11 32 | } 33 | 34 | skinparam class { 35 | backgroundColor #FAE5D3 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/0-introduction-physical-architecture-ai.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | 4 | left to right direction 5 | 6 | node "Super Hero UI" as ui { 7 | agent "Quarkus" <> as uiQuarkus 8 | } 9 | 10 | node "Hero" as hero { 11 | agent "Quarkus (reactive)" <> as heroQuarkus 12 | database "Postgresql" as heroPostgresql 13 | heroQuarkus .up> heroPostgresql 14 | } 15 | 16 | node "Villain" as villain { 17 | agent "Quarkus (imperative)" <> as villainQuarkus 18 | database "Postgresql" as villainPostgresql 19 | villainQuarkus .up> villainPostgresql 20 | } 21 | 22 | node "Narration" as narration { 23 | agent "Quarkus" <> as narrationQuarkus 24 | hexagon "Semantic Kernel" as sk 25 | narrationQuarkus .up> sk 26 | } 27 | 28 | cloud "Open AI \n Azure OpenAI" as openai 29 | 30 | node "Fight" as fight { 31 | agent "Quarkus" <> as fightQuarkus 32 | database "Postgresql" as fightPostgresql 33 | fightQuarkus .up> fightPostgresql 34 | } 35 | 36 | package "stats" { 37 | node "Statistics" as stat { 38 | agent "HTML+JQuery" <> as statUI 39 | agent "Quarkus (imperative)" <> as statQuarkus 40 | statUI .up> statQuarkus 41 | } 42 | 43 | node "Statistics UI" as statUi { 44 | agent "Browser" <> as uiStats 45 | } 46 | } 47 | 48 | node "Kafka + Zookeeper" as kafka { 49 | } 50 | 51 | node "Prometheus" as prometheus { 52 | } 53 | 54 | 55 | uiQuarkus --> fightQuarkus : HTTP 56 | fightQuarkus --> heroQuarkus : HTTP 57 | fightQuarkus --> villainQuarkus : HTTP 58 | fightQuarkus --> narrationQuarkus : HTTP 59 | 60 | sk --> openai : HTTP 61 | 62 | fightQuarkus ..> kafka : Message 63 | stat <.. kafka : Message 64 | statQuarkus ..> uiStats : Web Sockets 65 | 66 | prometheus .down.> fight : polling 67 | prometheus .> hero : polling 68 | prometheus .> villain : polling 69 | @enduml 70 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/0-introduction-physical-architecture.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | 4 | left to right direction 5 | 6 | node "Super Hero UI" as ui { 7 | agent "Quarkus" <> as uiQuarkus 8 | } 9 | 10 | node "Hero" as hero { 11 | agent "Quarkus (reactive)" <> as heroQuarkus 12 | database "Postgresql" as heroPostgresql 13 | heroQuarkus .up> heroPostgresql 14 | } 15 | 16 | node "Villain" as villain { 17 | agent "Quarkus (imperative)" <> as villainQuarkus 18 | database "Postgresql" as villainPostgresql 19 | villainQuarkus .up> villainPostgresql 20 | } 21 | 22 | node "Fight" as fight { 23 | agent "Quarkus" <> as fightQuarkus 24 | database "Postgresql" as fightPostgresql 25 | fightQuarkus .up> fightPostgresql 26 | } 27 | 28 | package "stats" { 29 | node "Statistics" as stat { 30 | agent "HTML+JQuery" <> as statUI 31 | agent "Quarkus (imperative)" <> as statQuarkus 32 | statUI .up> statQuarkus 33 | } 34 | 35 | node "Statistics UI" as statUi { 36 | agent "Browser" <> as uiStats 37 | } 38 | } 39 | 40 | node "Kafka + Zookeeper" as kafka { 41 | } 42 | 43 | node "Prometheus" as prometheus { 44 | } 45 | 46 | 47 | uiQuarkus --> fightQuarkus : HTTP 48 | fightQuarkus --> heroQuarkus : HTTP 49 | fightQuarkus --> villainQuarkus : HTTP 50 | 51 | fightQuarkus ..> kafka : Message 52 | stat <.. kafka : Message 53 | statQuarkus ..> uiStats : Web Sockets 54 | 55 | prometheus .down.> fight : polling 56 | prometheus .> hero : polling 57 | prometheus .> villain : polling 58 | @enduml 59 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/1-rest-physical-architecture.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | 4 | left to right direction 5 | 6 | node "Villain" as villain { 7 | agent "Quarkus (imperative)" <> as villainQuarkus 8 | database "Postgresql" as villainPostgresql 9 | villainQuarkus .up> villainPostgresql 10 | } 11 | 12 | REST ()-- villainQuarkus 13 | 14 | @enduml 15 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/3-reactive-physical-architecture.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | 4 | left to right direction 5 | 6 | node "Hero" as hero { 7 | agent "Quarkus (reactive)" <> as heroQuarkus 8 | database "Postgresql" as heroPostgresql 9 | heroQuarkus .up> heroPostgresql 10 | } 11 | 12 | REST ()-- heroQuarkus 13 | 14 | @enduml 15 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/4-microservices-fights-sequence.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | skinparam dpi 300 3 | skinparam useBetaStyle true 4 | skinparam handwritten true 5 | 6 | skinparam participant { 7 | backgroundColor<> #D2B4DE 8 | backgroundColor<> #FAE5D3 9 | } 10 | 11 | participant UI as UI <> 12 | participant "Fight Microservice" as Fight <> 13 | participant "Villain Microservice" as Villain <> 14 | participant "Hero Microservice" as Hero <> 15 | 16 | UI -> Fight: GET /api/fights/randomfighters 17 | Fight x--> Hero: GET /api/hero/randomhero 18 | Fight x--> Villain: GET /api/hero/randomvillain 19 | Fight ->x UI : null 20 | @enduml 21 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/4-microservices-physical-architecture.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | 4 | left to right direction 5 | 6 | node "Super Hero UI" as ui { 7 | agent "Quarkus" <> as uiQuarkus 8 | } 9 | 10 | node "Hero" as hero { 11 | agent "Quarkus (reactive)" <> as heroQuarkus 12 | database "Postgresql" as heroPostgresql 13 | heroQuarkus .up> heroPostgresql 14 | } 15 | 16 | node "Villain" as villain { 17 | agent "Quarkus (imperative)" <> as villainQuarkus 18 | database "Postgresql" as villainPostgresql 19 | villainQuarkus .up> villainPostgresql 20 | } 21 | 22 | node "Fight" as fight { 23 | agent "Quarkus" <> as fightQuarkus 24 | database "Postgresql" as fightPostgresql 25 | fightQuarkus .up> fightPostgresql 26 | } 27 | 28 | uiQuarkus -[hidden]-> fightQuarkus : HTTP 29 | fightQuarkus -[hidden]-> heroQuarkus : HTTP 30 | fightQuarkus -[hidden]-> villainQuarkus : HTTP 31 | @enduml 32 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/5-rest-client-physical-architecture.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | 4 | left to right direction 5 | 6 | node "Super Hero UI" as ui { 7 | agent "Quarkus" <> as uiQuarkus 8 | } 9 | 10 | node "Hero" as hero { 11 | agent "Quarkus (reactive)" <> as heroQuarkus 12 | database "Postgresql" as heroPostgresql 13 | heroQuarkus .up> heroPostgresql 14 | } 15 | 16 | node "Villain" as villain { 17 | agent "Quarkus (imperative)" <> as villainQuarkus 18 | database "Postgresql" as villainPostgresql 19 | villainQuarkus .up> villainPostgresql 20 | } 21 | 22 | node "Fight" as fight { 23 | agent "Quarkus" <> as fightQuarkus 24 | database "Postgresql" as fightPostgresql 25 | fightQuarkus .up> fightPostgresql 26 | } 27 | 28 | uiQuarkus --> fightQuarkus : HTTP 29 | fightQuarkus --> heroQuarkus : HTTP 30 | fightQuarkus --> villainQuarkus : HTTP 31 | @enduml 32 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/5a-ai-physical-architecture.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | 4 | left to right direction 5 | 6 | node "Super Hero UI" as ui { 7 | agent "Quarkus" <> as uiQuarkus 8 | } 9 | 10 | node "Hero" as hero { 11 | agent "Quarkus (reactive)" <> as heroQuarkus 12 | database "Postgresql" as heroPostgresql 13 | heroQuarkus .up> heroPostgresql 14 | } 15 | 16 | node "Villain" as villain { 17 | agent "Quarkus (imperative)" <> as villainQuarkus 18 | database "Postgresql" as villainPostgresql 19 | villainQuarkus .up> villainPostgresql 20 | } 21 | 22 | node "Narration" as narration { 23 | agent "Quarkus" <> as narrationQuarkus 24 | hexagon "Semantic Kernel" as sk 25 | narrationQuarkus .up> sk 26 | } 27 | 28 | cloud "Open AI \n Azure OpenAI" as openai 29 | 30 | node "Fight" as fight { 31 | agent "Quarkus" <> as fightQuarkus 32 | database "Postgresql" as fightPostgresql 33 | fightQuarkus .up> fightPostgresql 34 | } 35 | 36 | uiQuarkus --> fightQuarkus : HTTP 37 | fightQuarkus --> heroQuarkus : HTTP 38 | fightQuarkus --> villainQuarkus : HTTP 39 | fightQuarkus --> narrationQuarkus : HTTP 40 | 41 | sk --> openai : HTTP 42 | 43 | @enduml 44 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/5b-ai-narration-microservice.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | 4 | left to right direction 5 | 6 | node "Narration" as hero { 7 | agent "Quarkus" <> as narrationQuarkus 8 | hexagon "Semantic Kernel" as sk 9 | narrationQuarkus .up> sk 10 | } 11 | 12 | cloud "Open AI \n Azure OpenAI" as openai 13 | 14 | REST ()-- narrationQuarkus 15 | sk --> openai : HTTP 16 | 17 | @enduml 18 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/6-messaging-physical-architecture.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | 4 | left to right direction 5 | 6 | node "Super Hero UI" as ui { 7 | agent "Quarkus" <> as uiQuarkus 8 | } 9 | 10 | node "Hero" as hero { 11 | agent "Quarkus (reactive)" <> as heroQuarkus 12 | database "Postgresql" as heroPostgresql 13 | heroQuarkus .up> heroPostgresql 14 | } 15 | 16 | node "Villain" as villain { 17 | agent "Quarkus (imperative)" <> as villainQuarkus 18 | database "Postgresql" as villainPostgresql 19 | villainQuarkus .up> villainPostgresql 20 | } 21 | 22 | node "Fight" as fight { 23 | agent "Quarkus" <> as fightQuarkus 24 | database "Postgresql" as fightPostgresql 25 | fightQuarkus .up> fightPostgresql 26 | } 27 | 28 | package "stats" { 29 | node "Statistics" as stat { 30 | agent "HTML+JQuery" <> as statUI 31 | agent "Quarkus (imperative)" <> as statQuarkus 32 | statUI .up> statQuarkus 33 | } 34 | 35 | node "Statistics UI" as statUi { 36 | agent "Browser" <> as uiStats 37 | } 38 | } 39 | 40 | node "Kafka + Zookeeper" as kafka { 41 | } 42 | 43 | uiQuarkus --> fightQuarkus : HTTP 44 | fightQuarkus --> heroQuarkus : HTTP 45 | fightQuarkus --> villainQuarkus : HTTP 46 | 47 | fightQuarkus ..> kafka : Message 48 | stat <.. kafka : Message 49 | statQuarkus ..> uiStats : Web Sockets 50 | 51 | @enduml 52 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/6-quarkus-http-architecture.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | allow_mixing 4 | 5 | component "Undertow (Servlet)" as undertow { 6 | } 7 | 8 | component "RESTEasy (JaxRS)" as resteasy { 9 | } 10 | 11 | component "Vert.x / Netty" as vertx { 12 | } 13 | 14 | component "Reactive Routes" as rr { 15 | } 16 | 17 | component "Reactive Messaging" as rm { 18 | } 19 | 20 | component "Reactive Data Access" as rdb { 21 | } 22 | 23 | vertx -up-> undertow 24 | vertx -up-> resteasy 25 | vertx -up-> rr 26 | vertx -up-> rm 27 | vertx -up-> rdb 28 | 29 | 30 | @enduml 31 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/7-observability-physical-architecture.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | 4 | left to right direction 5 | 6 | node "Super Hero UI" as ui { 7 | agent "Quarkus" <> as uiQuarkus 8 | } 9 | 10 | node "Hero" as hero { 11 | agent "Quarkus (reactive)" <> as heroQuarkus 12 | database "Postgresql" as heroPostgresql 13 | heroQuarkus .up> heroPostgresql 14 | } 15 | 16 | node "Villain" as villain { 17 | agent "Quarkus (imperative)" <> as villainQuarkus 18 | database "Postgresql" as villainPostgresql 19 | villainQuarkus .up> villainPostgresql 20 | } 21 | 22 | node "Fight" as fight { 23 | agent "Quarkus" <> as fightQuarkus 24 | database "Postgresql" as fightPostgresql 25 | fightQuarkus .up> fightPostgresql 26 | } 27 | 28 | package "stats" { 29 | node "Statistics" as stat { 30 | agent "HTML+JQuery" <> as statUI 31 | agent "Quarkus (imperative)" <> as statQuarkus 32 | statUI .up> statQuarkus 33 | } 34 | 35 | node "Statistics UI" as statUi { 36 | agent "Browser" <> as uiStats 37 | } 38 | } 39 | 40 | node "Kafka + Zookeeper" as kafka { 41 | } 42 | 43 | node "Prometheus" as prometheus { 44 | } 45 | 46 | 47 | uiQuarkus --> fightQuarkus : HTTP 48 | fightQuarkus --> heroQuarkus : HTTP 49 | fightQuarkus --> villainQuarkus : HTTP 50 | 51 | fightQuarkus ..> kafka : Message 52 | stat <.. kafka : Message 53 | statQuarkus ..> uiStats : Web Sockets 54 | 55 | prometheus .down.> fight : polling 56 | prometheus .> hero : polling 57 | prometheus .> villain : polling 58 | @enduml 59 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/8-extension-architecture.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | !include style.puml 3 | 4 | left to right direction 5 | 6 | package "version-deployment" as deployment { 7 | class VersionConfig { 8 | boolean enabled 9 | } 10 | 11 | class VersionExtensionProcessor { 12 | @BuildStep @Record recordVersion() 13 | } 14 | } 15 | 16 | package "version" as runtime { 17 | class VersionRecorder { 18 | print(String version) 19 | } 20 | 21 | } 22 | 23 | 24 | 25 | deployment -up-> runtime : Maven dependency 26 | VersionExtensionProcessor <.up. VersionConfig : Mapped from configuration 27 | VersionExtensionProcessor ..> VersionRecorder : Use 28 | 29 | @enduml 30 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/plantuml/style.puml: -------------------------------------------------------------------------------- 1 | skinparam dpi 300 2 | skinparam useBetaStyle true 3 | skinparam handwritten true 4 | allow_mixing 5 | 6 | skinparam node { 7 | ArrowColor aqua 8 | 9 | borderColor #566573 10 | backgroundColor #F9E79F 11 | fontName Calibri 12 | fontSize 17 13 | fontColor #566573 14 | } 15 | 16 | skinparam database { 17 | borderColor #566573 18 | backgroundColor #D5F5E3 19 | } 20 | 21 | skinparam agent { 22 | backgroundColor<> #D2B4DE 23 | backgroundColor<> #FAE5D3 24 | } 25 | 26 | skinparam arrow { 27 | fontName Calibri 28 | color #FF6655 29 | fontColor #777777 30 | thickness 2 31 | fontSize 11 32 | } 33 | 34 | skinparam class { 35 | backgroundColor #FAE5D3 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/redirect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

Redirect

7 | 8 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/docs/src/docs/asciidoc/style.puml: -------------------------------------------------------------------------------- 1 | skinparam dpi 300 2 | skinparam useBetaStyle true 3 | skinparam handwritten true 4 | allow_mixing 5 | 6 | skinparam node { 7 | ArrowColor aqua 8 | 9 | borderColor #566573 10 | backgroundColor #F9E79F 11 | fontName Calibri 12 | fontSize 17 13 | fontColor #566573 14 | } 15 | 16 | skinparam database { 17 | borderColor #566573 18 | backgroundColor #D5F5E3 19 | } 20 | 21 | skinparam agent { 22 | backgroundColor<> #D2B4DE 23 | backgroundColor<> #FAE5D3 24 | } 25 | 26 | skinparam arrow { 27 | fontName Calibri 28 | color #FF6655 29 | fontColor #777777 30 | thickness 2 31 | fontSize 11 32 | } 33 | 34 | skinparam class { 35 | backgroundColor #FAE5D3 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !target/*-runner 3 | !target/*-runner.jar 4 | !target/lib/* 5 | !target/quarkus-app/* -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/.gitignore: -------------------------------------------------------------------------------- 1 | #Maven 2 | target/ 3 | pom.xml.tag 4 | pom.xml.releaseBackup 5 | pom.xml.versionsBackup 6 | release.properties 7 | .flattened-pom.xml 8 | 9 | # Eclipse 10 | .project 11 | .classpath 12 | .settings/ 13 | bin/ 14 | 15 | # IntelliJ 16 | .idea 17 | *.ipr 18 | *.iml 19 | *.iws 20 | 21 | # NetBeans 22 | nb-configuration.xml 23 | 24 | # Visual Studio Code 25 | .vscode 26 | .factorypath 27 | 28 | # OSX 29 | .DS_Store 30 | 31 | # Vim 32 | *.swp 33 | *.swo 34 | 35 | # patch 36 | *.orig 37 | *.rej 38 | 39 | # Local environment 40 | .env 41 | 42 | # Plugin directory 43 | /.quarkus/cli/plugins/ 44 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/.mvn/wrapper/.gitignore: -------------------------------------------------------------------------------- 1 | maven-wrapper.jar 2 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 19 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/src/main/docker/Dockerfile.build-native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # It uses a micro base image, tuned for Quarkus native executables. 4 | # It reduces the size of the resulting container image. 5 | # Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. 6 | # 7 | # Build the image with: 8 | # 9 | # docker build -f src/main/docker/Dockerfile.build-native -t quarkus/event-statistics . 10 | # 11 | # Then run the container using: 12 | # 13 | # docker run -i --rm -p 8080:8080 quarkus/event-statistics 14 | # 15 | ### 16 | 17 | ## Stage 1 : build with maven builder image with native capabilities 18 | FROM quay.io/quarkus/ubi-quarkus-native-image:22.0-java11 AS build 19 | COPY --chown=quarkus:quarkus mvnw /code/mvnw 20 | COPY --chown=quarkus:quarkus .mvn /code/.mvn 21 | COPY --chown=quarkus:quarkus pom.xml /code/ 22 | USER quarkus 23 | WORKDIR /code 24 | RUN ./mvnw -B org.apache.maven.plugins:maven-dependency-plugin:3.1.2:go-offline 25 | COPY src /code/src 26 | RUN ./mvnw package -Pnative -Dmaven.test.skip=true 27 | 28 | ## Stage 2 : create the docker final image 29 | FROM quay.io/quarkus/quarkus-micro-image:1.0 30 | WORKDIR /work/ 31 | COPY --from=build /code/target/*-runner /work/application 32 | 33 | # set up permissions for user `1001` 34 | RUN chmod 775 /work /work/application \ 35 | && chown -R 1001 /work \ 36 | && chmod -R "g+rwX" /work \ 37 | && chown -R 1001:root /work 38 | 39 | EXPOSE 8080 40 | USER 1001 41 | 42 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] 43 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/src/main/docker/Dockerfile.native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # 4 | # Before building the container image run: 5 | # 6 | # ./mvnw package -Dnative 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/event-statistics . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/event-statistics 15 | # 16 | ### 17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9 18 | WORKDIR /work/ 19 | RUN chown 1001 /work \ 20 | && chmod "g+rwX" /work \ 21 | && chown 1001:root /work 22 | COPY --chown=1001:root target/*-runner /work/application 23 | 24 | EXPOSE 8080 25 | USER 1001 26 | 27 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 28 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/src/main/docker/Dockerfile.native-micro: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # It uses a micro base image, tuned for Quarkus native executables. 4 | # It reduces the size of the resulting container image. 5 | # Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. 6 | # 7 | # Before building the container image run: 8 | # 9 | # ./mvnw package -Dnative 10 | # 11 | # Then, build the image with: 12 | # 13 | # docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/event-statistics . 14 | # 15 | # Then run the container using: 16 | # 17 | # docker run -i --rm -p 8080:8080 quarkus/event-statistics 18 | # 19 | ### 20 | FROM quay.io/quarkus/quarkus-micro-image:2.0 21 | WORKDIR /work/ 22 | RUN chown 1001 /work \ 23 | && chmod "g+rwX" /work \ 24 | && chown 1001:root /work 25 | COPY --chown=1001:root target/*-runner /work/application 26 | 27 | EXPOSE 8080 28 | USER 1001 29 | 30 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 31 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/src/main/java/io/quarkus/workshop/superheroes/statistics/Fight.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.statistics; 2 | 3 | import java.time.Instant; 4 | 5 | import io.quarkus.runtime.annotations.RegisterForReflection; 6 | 7 | @RegisterForReflection 8 | public class Fight { 9 | 10 | public Instant fightDate; 11 | public String winnerName; 12 | public int winnerLevel; 13 | public String winnerPicture; 14 | public String loserName; 15 | public int loserLevel; 16 | public String loserPicture; 17 | public String winnerTeam; 18 | public String loserTeam; 19 | } 20 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/src/main/java/io/quarkus/workshop/superheroes/statistics/FightDeserializer.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.statistics; 2 | 3 | import io.quarkus.kafka.client.serialization.ObjectMapperDeserializer; 4 | 5 | public class FightDeserializer extends ObjectMapperDeserializer { 6 | 7 | public FightDeserializer() { 8 | super(Fight.class); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/src/main/java/io/quarkus/workshop/superheroes/statistics/Ranking.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.statistics; 2 | 3 | import java.util.Collections; 4 | import java.util.Comparator; 5 | import java.util.LinkedList; 6 | 7 | // tag::adocJavadoc[] 8 | /** 9 | * Object used to compute a floating "top" winners. The number of winners to keep track of is defined at construction time. 10 | */ 11 | // end::adocJavadoc[] 12 | public class Ranking { 13 | 14 | private final int max; 15 | 16 | private final Comparator comparator = Comparator.comparingInt(s -> -1 * s.score); 17 | 18 | private final LinkedList top = new LinkedList<>(); 19 | 20 | public Ranking(int size) { 21 | max = size; 22 | } 23 | 24 | // tag::adocJavadoc[] 25 | /** 26 | * Records a new {@link Score} 27 | * @param score The {@link Score} received 28 | * @return The current list of floating top winners and their scores 29 | */ 30 | // end::adocJavadoc[] 31 | public Iterable onNewScore(Score score) { 32 | // Remove score if already present, 33 | top.removeIf(s -> s.name.equalsIgnoreCase(score.name)); 34 | // Add the score 35 | top.add(score); 36 | // Sort 37 | top.sort(comparator); 38 | 39 | // Drop on overflow 40 | if (top.size() > max) { 41 | top.remove(top.getLast()); 42 | } 43 | 44 | return Collections.unmodifiableList(top); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/src/main/java/io/quarkus/workshop/superheroes/statistics/Score.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.statistics; 2 | 3 | import io.quarkus.runtime.annotations.RegisterForReflection; 4 | 5 | // tag::adocJavadoc[] 6 | /** 7 | * Data class for a score 8 | *

9 | * The {@link RegisterForReflection @RegisterForReflection} annotation instructs the native compilation to allow reflection access to the class. Without it, the serialization/deserialization would not work when running the native executable. 10 | *

11 | */ 12 | // end::adocJavadoc[] 13 | @RegisterForReflection 14 | public class Score { 15 | public String name; 16 | public int score; 17 | 18 | public Score() { 19 | this.score = 0; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/src/main/java/io/quarkus/workshop/superheroes/statistics/TeamStats.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.statistics; 2 | 3 | // tag::adocJavadoc[] 4 | /** 5 | * Object keeping track of the number of battles won by heroes and villains 6 | */ 7 | // end::adocJavadoc[] 8 | class TeamStats { 9 | 10 | private int villains = 0; 11 | private int heroes = 0; 12 | 13 | // tag::adocJavadoc[] 14 | /** 15 | * Adds a {@link Fight} 16 | * @param result The {@link Fight} received 17 | * @return A double containing running battle stats by team 18 | */ 19 | // end::adocJavadoc[] 20 | double add(Fight result) { 21 | if (result.winnerTeam.equalsIgnoreCase("heroes")) { 22 | heroes = heroes + 1; 23 | } else { 24 | villains = villains + 1; 25 | } 26 | return ((double) heroes / (heroes + villains)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/src/main/java/io/quarkus/workshop/superheroes/statistics/TeamStatsWebSocket.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.statistics; 2 | 3 | import io.smallrye.mutiny.Multi; 4 | import io.smallrye.mutiny.subscription.Cancellable; 5 | import jakarta.annotation.PostConstruct; 6 | import jakarta.annotation.PreDestroy; 7 | import org.eclipse.microprofile.reactive.messaging.Channel; 8 | import org.jboss.logging.Logger; 9 | 10 | import jakarta.enterprise.context.ApplicationScoped; 11 | import jakarta.inject.Inject; 12 | import jakarta.websocket.OnClose; 13 | import jakarta.websocket.OnOpen; 14 | import jakarta.websocket.Session; 15 | import jakarta.websocket.server.ServerEndpoint; 16 | import java.util.List; 17 | import java.util.concurrent.CopyOnWriteArrayList; 18 | 19 | // tag::adocJavadoc[] 20 | /** 21 | * WebSocket endpoint for the {@code /stats/team} endpoint. Exposes the {@code team-stats} channel over the socket to anyone listening. 22 | *

23 | * Uses field injection via {@link Inject @Inject} over construction injection to show how it is done 24 | *

25 | */ 26 | // end::adocJavadoc[] 27 | @ServerEndpoint("/stats/team") 28 | @ApplicationScoped 29 | public class TeamStatsWebSocket { 30 | 31 | @Channel("team-stats") 32 | Multi stream; 33 | 34 | @Inject Logger logger; 35 | 36 | private final List sessions = new CopyOnWriteArrayList<>(); 37 | private Cancellable cancellable; 38 | 39 | @OnOpen 40 | public void onOpen(Session session) { 41 | sessions.add(session); 42 | } 43 | 44 | @OnClose 45 | public void onClose(Session session) { 46 | sessions.remove(session); 47 | } 48 | 49 | @PostConstruct 50 | public void subscribe() { 51 | cancellable = stream.subscribe() 52 | .with(ratio -> sessions.forEach(session -> write(session, ratio))); 53 | } 54 | 55 | @PreDestroy 56 | public void cleanup() { 57 | cancellable.cancel(); 58 | } 59 | 60 | private void write(Session session, double ratio) { 61 | session.getAsyncRemote().sendText(Double.toString(ratio), result -> { 62 | if (result.getException() != null) { 63 | logger.error("Unable to write message to web socket", result.getException()); 64 | } 65 | }); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.http.port=8085 2 | 3 | ## Custom banner file path 4 | quarkus.banner.path=banner.txt 5 | 6 | ## Kafka configuration 7 | mp.messaging.incoming.fights.connector=smallrye-kafka 8 | mp.messaging.incoming.fights.auto.offset.reset=earliest 9 | mp.messaging.incoming.fights.broadcast=true 10 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/event-statistics/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | _______..___________. ___ .___________. __ _______..___________. __ ______ _______. 2 | / || | / \ | || | / || || | / | / | 3 | | (----``---| |----` / ^ \ `---| |----`| | | (----``---| |----`| | | ,----' | (----` 4 | \ \ | | / /_\ \ | | | | \ \ | | | | | | \ \ 5 | .----) | | | / _____ \ | | | | .----) | | | | | | `----..----) | 6 | |_______/ |__| /__/ \__\ |__| |__| |_______/ |__| |__| \______||_______/ 7 | 8 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/extension-version/deployment/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | io.quarkus.workshop.super-heroes 7 | extension-version-parent 8 | 1.0.0-SNAPSHOT 9 | 10 | extension-version-deployment 11 | Quarkus Workshop :: Extension Version :: Deployment 12 | 13 | 14 | io.quarkus 15 | quarkus-arc-deployment 16 | 17 | 18 | io.quarkus.workshop.super-heroes 19 | extension-version 20 | ${project.version} 21 | 22 | 23 | io.quarkus 24 | quarkus-junit5-internal 25 | test 26 | 27 | 28 | 29 | 30 | 31 | maven-compiler-plugin 32 | 33 | 34 | 35 | io.quarkus 36 | quarkus-extension-processor 37 | ${quarkus.version} 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/extension-version/deployment/src/main/java/io/quarkus/workshop/superheroes/version/deployment/ExtensionVersionProcessor.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.version.deployment; 2 | 3 | import io.quarkus.deployment.annotations.BuildStep; 4 | import io.quarkus.deployment.annotations.ExecutionTime; 5 | import io.quarkus.deployment.annotations.Record; 6 | import io.quarkus.deployment.builditem.ApplicationInfoBuildItem; 7 | import io.quarkus.deployment.builditem.FeatureBuildItem; 8 | import io.quarkus.workshop.superheroes.version.runtime.VersionConfig; 9 | import io.quarkus.workshop.superheroes.version.runtime.VersionRecorder; 10 | 11 | class ExtensionVersionProcessor { 12 | 13 | private static final String FEATURE = "extension-version"; 14 | 15 | @BuildStep 16 | FeatureBuildItem feature() { 17 | return new FeatureBuildItem(FEATURE); 18 | } 19 | 20 | @BuildStep 21 | @Record(ExecutionTime.RUNTIME_INIT) 22 | void recordVersion(ApplicationInfoBuildItem app, VersionConfig versionConfig, VersionRecorder recorder) { 23 | recorder.printVersion(versionConfig, app.getVersion()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/extension-version/runtime/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | io.quarkus.workshop.super-heroes 7 | extension-version-parent 8 | 1.0.0-SNAPSHOT 9 | 10 | extension-version 11 | Quarkus Workshop :: Extension Version :: Runtime 12 | 13 | 14 | io.quarkus 15 | quarkus-arc 16 | 17 | 18 | 19 | 20 | 21 | io.quarkus 22 | quarkus-extension-maven-plugin 23 | ${quarkus.version} 24 | 25 | 26 | compile 27 | 28 | extension-descriptor 29 | 30 | 31 | ${project.groupId}:${project.artifactId}-deployment:${project.version} 32 | 33 | 34 | 35 | 36 | 37 | maven-compiler-plugin 38 | 39 | 40 | 41 | io.quarkus 42 | quarkus-extension-processor 43 | ${quarkus.version} 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/extension-version/runtime/src/main/java/io/quarkus/workshop/superheroes/version/runtime/VersionConfig.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.version.runtime; 2 | 3 | import io.quarkus.runtime.annotations.ConfigPhase; 4 | import io.quarkus.runtime.annotations.ConfigRoot; 5 | import io.smallrye.config.ConfigMapping; 6 | import io.smallrye.config.WithDefault; 7 | 8 | @ConfigMapping(prefix = "quarkus.version") 9 | @ConfigRoot(phase = ConfigPhase.RUN_TIME) 10 | public interface VersionConfig { 11 | 12 | /** 13 | * Enables or disables the version printing at startup. 14 | */ 15 | @WithDefault("true") 16 | boolean enabled(); 17 | } 18 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/extension-version/runtime/src/main/java/io/quarkus/workshop/superheroes/version/runtime/VersionRecorder.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.version.runtime; 2 | 3 | import io.quarkus.runtime.annotations.Recorder; 4 | import org.jboss.logging.Logger; 5 | 6 | @Recorder 7 | public class VersionRecorder { 8 | 9 | public void printVersion(VersionConfig versionConfig, String version) { 10 | if (versionConfig.enabled()) { 11 | Logger.getLogger(VersionRecorder.class.getName()).infof("Version: %s", version); 12 | } 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/extension-version/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Extension Version 2 | #description: Extension Version ... 3 | metadata: 4 | # keywords: 5 | # - extension-version 6 | # guide: ... 7 | # categories: 8 | # - "miscellaneous" 9 | # status: "preview" -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/README.adoc: -------------------------------------------------------------------------------- 1 | = Infrastructure 2 | 3 | == Azure 4 | 5 | To deploy the Azure infrastructure, you need to have an Azure account and the Azure CLI installed. 6 | Then, execute the following scripts: 7 | 8 | ```bash 9 | ./azure-setup-azure-env.sh # Create the Azure resources 10 | ./azure-build-push-registry.sh # Build and push the Docker images to the Azure Container Registry 11 | ./azure-setup-aca-env.sh # Create the Azure Container Apps resources 12 | ./azure-deploy-aca.sh # Deploys the application to Azure Container Apps 13 | ``` 14 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/ai-azure-openai-delete.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Setting up environment variables..." 4 | echo "----------------------------------" 5 | PROJECT="" 6 | RESOURCE_GROUP="rg-$PROJECT" 7 | COGNITIVE_SERVICE="cognit-$PROJECT" 8 | COGNITIVE_DEPLOYMENT="deploy-$PROJECT" 9 | LOCATION="eastus" 10 | TAG="$PROJECT" 11 | 12 | # tag::adocDelete[] 13 | # Clean up 14 | az group delete \ 15 | --name "$RESOURCE_GROUP" \ 16 | --yes 17 | 18 | az cognitiveservices account purge \ 19 | --name "$COGNITIVE_SERVICE" \ 20 | --resource-group "$RESOURCE_GROUP" \ 21 | --location "$LOCATION" 22 | 23 | az cognitiveservices account delete \ 24 | --name "$COGNITIVE_SERVICE" \ 25 | --resource-group "$RESOURCE_GROUP" 26 | # end::adocDelete[] 27 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/db-init/initialize-databases.sql: -------------------------------------------------------------------------------- 1 | CREATE ROLE super WITH LOGIN PASSWORD 'super'; 2 | 3 | CREATE ROLE superman WITH LOGIN PASSWORD 'superman' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION; 4 | CREATE DATABASE heroes_database; 5 | GRANT ALL PRIVILEGES ON DATABASE heroes_database TO superman; 6 | GRANT ALL PRIVILEGES ON DATABASE heroes_database TO super; 7 | 8 | CREATE ROLE superbad WITH LOGIN PASSWORD 'superbad' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION; 9 | CREATE DATABASE villains_database; 10 | GRANT ALL PRIVILEGES ON DATABASE villains_database TO superbad; 11 | GRANT ALL PRIVILEGES ON DATABASE villains_database TO super; 12 | 13 | CREATE ROLE superfight WITH LOGIN PASSWORD 'superfight' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION; 14 | CREATE DATABASE fights_database; 15 | GRANT ALL PRIVILEGES ON DATABASE fights_database TO superfight; 16 | GRANT ALL PRIVILEGES ON DATABASE fights_database TO super; 17 | 18 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/db-init/initialize-tables-fights.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS Fight; 2 | DROP SEQUENCE IF EXISTS fight_seq; 3 | 4 | CREATE SEQUENCE fight_seq START 1 INCREMENT 50; 5 | 6 | create table Fight 7 | ( 8 | id int8 not null, 9 | fightDate timestamp, 10 | loserLevel int4 not null, 11 | loserName varchar(255), 12 | loserPicture varchar(255), 13 | loserTeam varchar(255), 14 | loserPowers TEXT, 15 | winnerLevel int4 not null, 16 | winnerName varchar(255), 17 | winnerPicture varchar(255), 18 | winnerTeam varchar(255), 19 | winnerPowers TEXT, 20 | primary key (id) 21 | ); 22 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/db-init/initialize-tables-heroes.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS Hero; 2 | DROP SEQUENCE IF EXISTS hero_seq; 3 | 4 | CREATE SEQUENCE hero_seq START 1 INCREMENT 50; 5 | 6 | create table Hero 7 | ( 8 | id int8 not null, 9 | level int4 not null, 10 | name varchar(50) not null, 11 | otherName varchar(255), 12 | picture varchar(255), 13 | powers TEXT, 14 | primary key (id) 15 | ); 16 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/db-init/initialize-tables-villains.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS Villain; 2 | DROP SEQUENCE IF EXISTS villain_seq; 3 | 4 | CREATE SEQUENCE villain_seq START 1 INCREMENT 50; 5 | 6 | create table Villain 7 | ( 8 | id int8 not null, 9 | level int4 not null, 10 | name varchar(50) not null, 11 | otherName varchar(255), 12 | picture varchar(255), 13 | powers TEXT, 14 | primary key (id) 15 | ); 16 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/docker-compose-linux.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | database: 4 | image: "postgres:14" 5 | container_name: "super-database" 6 | ports: 7 | - "5432:5432" 8 | environment: 9 | POSTGRES_PASSWORD: password 10 | volumes: 11 | - ./db-init/initialize-databases.sql:/docker-entrypoint-initdb.d/init.sql 12 | 13 | monitoring: 14 | image: "prom/prometheus:v2.30.3" 15 | network_mode: 'host' # On Linux, this is required to let Prometheus access the other containers. 16 | container_name: "super-visor" 17 | ports: 18 | - 9090:9090 19 | volumes: 20 | - ./monitoring/prometheus-linux.yml:/etc/prometheus/prometheus.yml 21 | 22 | zookeeper: 23 | image: quay.io/strimzi/kafka:0.23.0-kafka-2.8.0 24 | container_name: "zookeeper" 25 | command: [ 26 | "sh", "-c", 27 | "bin/zookeeper-server-start.sh config/zookeeper.properties" 28 | ] 29 | ports: 30 | - "2181:2181" 31 | environment: 32 | LOG_DIR: /tmp/logs 33 | 34 | kafka: 35 | image: quay.io/strimzi/kafka:0.23.0-kafka-2.8.0 36 | container_name: "kafka" 37 | command: [ 38 | "sh", "-c", 39 | "bin/kafka-server-start.sh config/server.properties --override listeners=$${KAFKA_LISTENERS} --override advertised.listeners=$${KAFKA_ADVERTISED_LISTENERS} --override zookeeper.connect=$${KAFKA_ZOOKEEPER_CONNECT}" 40 | ] 41 | depends_on: 42 | - zookeeper 43 | ports: 44 | - "9092:9092" 45 | environment: 46 | LOG_DIR: "/tmp/logs" 47 | KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092 48 | KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092 49 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 50 | 51 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | database: 4 | image: "postgres:14" 5 | container_name: "super-database" 6 | ports: 7 | - "5432:5432" 8 | environment: 9 | POSTGRES_PASSWORD: password 10 | volumes: 11 | - ./db-init/initialize-databases.sql:/docker-entrypoint-initdb.d/init.sql 12 | 13 | monitoring: 14 | image: "prom/prometheus:v2.30.3" 15 | container_name: "super-visor" 16 | ports: 17 | - 9090:9090 18 | volumes: 19 | - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml 20 | 21 | zookeeper: 22 | image: quay.io/strimzi/kafka:0.23.0-kafka-2.8.0 23 | container_name: "zookeeper" 24 | command: [ 25 | "sh", "-c", 26 | "bin/zookeeper-server-start.sh config/zookeeper.properties" 27 | ] 28 | ports: 29 | - "2181:2181" 30 | environment: 31 | LOG_DIR: /tmp/logs 32 | 33 | kafka: 34 | image: quay.io/strimzi/kafka:0.23.0-kafka-2.8.0 35 | container_name: "kafka" 36 | command: [ 37 | "sh", "-c", 38 | "bin/kafka-server-start.sh config/server.properties --override listeners=$${KAFKA_LISTENERS} --override advertised.listeners=$${KAFKA_ADVERTISED_LISTENERS} --override zookeeper.connect=$${KAFKA_ZOOKEEPER_CONNECT}" 39 | ] 40 | depends_on: 41 | - zookeeper 42 | ports: 43 | - "9092:9092" 44 | environment: 45 | LOG_DIR: "/tmp/logs" 46 | KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092 47 | KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092 48 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 49 | 50 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/monitoring/prometheus-linux.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s # By default, scrape targets every 15 seconds. 3 | 4 | # tag::adocPrometheus[] 5 | scrape_configs: 6 | - job_name: 'prometheus' 7 | static_configs: 8 | - targets: ['localhost:9090'] 9 | - job_name: 'fights' 10 | metrics_path: '/q/metrics' 11 | static_configs: 12 | - targets: ['localhost:8082'] 13 | - job_name: 'heroes' 14 | metrics_path: '/q/metrics' 15 | static_configs: 16 | - targets: ['localhost:8083'] 17 | - job_name: 'villains' 18 | metrics_path: '/q/metrics' 19 | static_configs: 20 | - targets: ['localhost:8084'] 21 | # end::adocPrometheus[] 22 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/monitoring/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s # By default, scrape targets every 15 seconds. 3 | 4 | # tag::adocPrometheus[] 5 | scrape_configs: 6 | - job_name: 'prometheus' 7 | static_configs: 8 | - targets: ['localhost:9090'] 9 | - job_name: 'fights' 10 | metrics_path: '/q/metrics' 11 | static_configs: 12 | - targets: ['host.docker.internal:8082'] 13 | - job_name: 'heroes' 14 | metrics_path: '/q/metrics' 15 | static_configs: 16 | - targets: ['host.docker.internal:8083'] 17 | - job_name: 'villains' 18 | metrics_path: '/q/metrics' 19 | static_configs: 20 | - targets: ['host.docker.internal:8084'] 21 | # end::adocPrometheus[] 22 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/prometheus-linux.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | monitoring: 4 | image: "prom/prometheus:v2.30.3" 5 | network_mode: 'host' # On Linux, this is required to let Prometheus access the other containers. 6 | container_name: "super-visor" 7 | ports: 8 | - 9090:9090 9 | volumes: 10 | - ./monitoring/prometheus-linux.yml:/etc/prometheus/prometheus.yml 11 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/infrastructure/prometheus.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | monitoring: 4 | image: "prom/prometheus:v2.30.3" 5 | container_name: "super-visor" 6 | ports: 7 | - 9090:9090 8 | volumes: 9 | - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml 10 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/kubernetes/config-fight.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | port: "8080" 4 | database: "jdbc:postgresql://fights-database:5432/fight-database" 5 | kafka: "my-kafka-kafka-brokers:9092" 6 | hero: "http://quarkus-workshop-hero:8080" 7 | villain: "http://quarkus-workshop-villain:8080" 8 | kind: ConfigMap 9 | metadata: 10 | name: fight-config 11 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/kubernetes/config-hero.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | port: "8080" 4 | database: "jdbc:postgresql://heroes-database:5432/heroes-database" 5 | kind: ConfigMap 6 | metadata: 7 | name: hero-config 8 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/kubernetes/config-villain.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | port: "8080" 4 | database: "jdbc:postgresql://villains-database:5432/villains-database" 5 | kind: ConfigMap 6 | metadata: 7 | name: villain-config 8 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/kubernetes/database-fight.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: postgresql.dev4devs.com/v1alpha1 2 | kind: Database 3 | metadata: 4 | name: fights-database 5 | namespace: quarkus-workshop 6 | spec: 7 | databaseCpu: 30m 8 | databaseCpuLimit: 60m 9 | databaseMemoryLimit: 512Mi 10 | databaseMemoryRequest: 128Mi 11 | databaseName: fight-database 12 | databaseNameKeyEnvVar: POSTGRESQL_DATABASE 13 | databasePassword: superfight 14 | databasePasswordKeyEnvVar: POSTGRESQL_PASSWORD 15 | databaseStorageRequest: 1Gi 16 | databaseUser: superfight 17 | databaseUserKeyEnvVar: POSTGRESQL_USER 18 | image: centos/postgresql-96-centos7 19 | size: 1 20 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/kubernetes/database-hero.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: postgresql.dev4devs.com/v1alpha1 2 | kind: Database 3 | metadata: 4 | name: heroes-database 5 | namespace: quarkus-workshop 6 | spec: 7 | databaseCpu: 30m 8 | databaseCpuLimit: 60m 9 | databaseMemoryLimit: 512Mi 10 | databaseMemoryRequest: 128Mi 11 | databaseName: heroes-database 12 | databaseNameKeyEnvVar: POSTGRESQL_DATABASE 13 | databasePassword: superman 14 | databasePasswordKeyEnvVar: POSTGRESQL_PASSWORD 15 | databaseStorageRequest: 1Gi 16 | databaseUser: superman 17 | databaseUserKeyEnvVar: POSTGRESQL_USER 18 | image: centos/postgresql-96-centos7 19 | size: 1 20 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/kubernetes/database-villain.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: postgresql.dev4devs.com/v1alpha1 2 | kind: Database 3 | metadata: 4 | name: villains-database 5 | namespace: quarkus-workshop 6 | spec: 7 | databaseCpu: 30m 8 | databaseCpuLimit: 60m 9 | databaseMemoryLimit: 512Mi 10 | databaseMemoryRequest: 128Mi 11 | databaseName: villains-database 12 | databaseNameKeyEnvVar: POSTGRESQL_DATABASE 13 | databasePassword: superbad 14 | databasePasswordKeyEnvVar: POSTGRESQL_PASSWORD 15 | databaseStorageRequest: 1Gi 16 | databaseUser: superbad 17 | databaseUserKeyEnvVar: POSTGRESQL_USER 18 | image: centos/postgresql-96-centos7 19 | size: 1 20 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/kubernetes/kafka-cluster-descriptor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kafka.strimzi.io/v1beta1 2 | kind: Kafka 3 | metadata: 4 | name: my-kafka 5 | namespace: quarkus-workshop 6 | spec: 7 | kafka: 8 | version: 2.3.0 9 | replicas: 3 10 | listeners: 11 | plain: {} 12 | tls: {} 13 | config: 14 | offsets.topic.replication.factor: 3 15 | transaction.state.log.replication.factor: 3 16 | transaction.state.log.min.isr: 2 17 | log.message.format.version: '2.3' 18 | storage: 19 | type: ephemeral 20 | zookeeper: 21 | replicas: 3 22 | storage: 23 | type: ephemeral 24 | entityOperator: 25 | topicOperator: {} 26 | userOperator: {} 27 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/kubernetes/kafka-topic-fight-descriptor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kafka.strimzi.io/v1beta1 2 | kind: KafkaTopic 3 | metadata: 4 | name: fights 5 | labels: 6 | strimzi.io/cluster: my-kafka 7 | namespace: quarkus-workshop 8 | spec: 9 | partitions: 1 10 | replicas: 3 11 | config: 12 | retention.ms: 604800000 13 | segment.bytes: 1073741824 14 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !target/*-runner 3 | !target/*-runner.jar 4 | !target/lib/* 5 | !target/quarkus-app/* -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/.gitignore: -------------------------------------------------------------------------------- 1 | #Maven 2 | target/ 3 | pom.xml.tag 4 | pom.xml.releaseBackup 5 | pom.xml.versionsBackup 6 | release.properties 7 | .flattened-pom.xml 8 | 9 | # Eclipse 10 | .project 11 | .classpath 12 | .settings/ 13 | bin/ 14 | 15 | # IntelliJ 16 | .idea 17 | *.ipr 18 | *.iml 19 | *.iws 20 | 21 | # NetBeans 22 | nb-configuration.xml 23 | 24 | # Visual Studio Code 25 | .vscode 26 | .factorypath 27 | 28 | # OSX 29 | .DS_Store 30 | 31 | # Vim 32 | *.swp 33 | *.swo 34 | 35 | # patch 36 | *.orig 37 | *.rej 38 | 39 | # Local environment 40 | .env 41 | 42 | # Plugin directory 43 | /.quarkus/cli/plugins/ 44 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/.mvn/wrapper/.gitignore: -------------------------------------------------------------------------------- 1 | maven-wrapper.jar 2 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 19 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/src/main/java/io/quarkus/workshop/superheroes/load/CLIMain.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.load; 2 | 3 | import io.quarkus.logging.Log; 4 | import jakarta.enterprise.context.Dependent; 5 | import picocli.CommandLine; 6 | 7 | import java.util.concurrent.Callable; 8 | 9 | @CommandLine.Command(name = "CLI Super Heroes") 10 | public class CLIMain implements Callable { 11 | 12 | @CommandLine.Option(names = {"-s", "--stop"}, 13 | description = "Write something and press enter to stop", 14 | required = true, 15 | interactive = true) 16 | String stop; 17 | 18 | private final StopMessage stopAction; 19 | 20 | public CLIMain(StopMessage greetingService) { 21 | this.stopAction = greetingService; 22 | } 23 | 24 | @Override 25 | public Integer call() { 26 | stopAction.stop(); 27 | return CommandLine.ExitCode.OK; 28 | } 29 | 30 | @Dependent 31 | static class StopMessage { 32 | void stop() { 33 | Log.info("Stop"); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/src/main/java/io/quarkus/workshop/superheroes/load/client/Fight.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.quarkus.workshop.superheroes.load.client; 18 | 19 | public class Fight { 20 | public Hero hero; 21 | public Villain villain; 22 | } 23 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/src/main/java/io/quarkus/workshop/superheroes/load/client/FightsProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.quarkus.workshop.superheroes.load.client; 18 | 19 | import io.quarkus.rest.client.reactive.ClientExceptionMapper; 20 | import jakarta.ws.rs.GET; 21 | import jakarta.ws.rs.POST; 22 | import jakarta.ws.rs.Path; 23 | import jakarta.ws.rs.PathParam; 24 | import jakarta.ws.rs.Produces; 25 | import jakarta.ws.rs.core.MediaType; 26 | import jakarta.ws.rs.core.Response; 27 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; 28 | 29 | @Path("/api/fights") 30 | @Produces(MediaType.APPLICATION_JSON) 31 | @RegisterRestClient(configKey = "fight") 32 | public interface FightsProxy { 33 | @GET 34 | @Path("/hello") 35 | @Produces(MediaType.TEXT_PLAIN) 36 | Response hello(); 37 | 38 | @GET 39 | Response all(); 40 | 41 | @GET 42 | @Path("/randomfighters") 43 | Response random(); 44 | 45 | @POST 46 | Response create(Fight hero); 47 | 48 | @GET 49 | @Path("/{id}") 50 | Response get(@PathParam("id") String id); 51 | 52 | @ClientExceptionMapper 53 | static RuntimeException toException(Response response) { 54 | return null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/src/main/java/io/quarkus/workshop/superheroes/load/client/Hero.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.quarkus.workshop.superheroes.load.client; 18 | 19 | public class Hero { 20 | public String id; 21 | public String name; 22 | public String otherName; 23 | public int level; 24 | public String picture; 25 | public String powers; 26 | 27 | @Override 28 | public String toString() { 29 | return "Hero{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/src/main/java/io/quarkus/workshop/superheroes/load/client/HeroProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.quarkus.workshop.superheroes.load.client; 18 | 19 | import io.quarkus.rest.client.reactive.ClientExceptionMapper; 20 | import jakarta.ws.rs.DELETE; 21 | import jakarta.ws.rs.GET; 22 | import jakarta.ws.rs.POST; 23 | import jakarta.ws.rs.Path; 24 | import jakarta.ws.rs.PathParam; 25 | import jakarta.ws.rs.Produces; 26 | import jakarta.ws.rs.core.MediaType; 27 | import jakarta.ws.rs.core.Response; 28 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; 29 | 30 | @Path("/api/heroes") 31 | @Produces(MediaType.APPLICATION_JSON) 32 | @RegisterRestClient(configKey = "hero") 33 | public interface HeroProxy { 34 | 35 | @GET 36 | @Path("/hello") 37 | @Produces(MediaType.TEXT_PLAIN) 38 | Response hello(); 39 | 40 | @GET 41 | Response all(); 42 | 43 | @GET 44 | @Path("/random") 45 | Response random(); 46 | 47 | @POST 48 | Response create(Hero hero); 49 | 50 | @GET 51 | @Path("/{id}") 52 | Response get(@PathParam("id") String id); 53 | 54 | @DELETE 55 | @Path("/{id}") 56 | Response delete(@PathParam("id") String id); 57 | 58 | @ClientExceptionMapper 59 | static RuntimeException toException(Response response) { 60 | return null; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/src/main/java/io/quarkus/workshop/superheroes/load/client/RequestLogger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.quarkus.workshop.superheroes.load.client; 18 | 19 | import io.quarkus.logging.Log; 20 | import io.vertx.core.buffer.Buffer; 21 | import io.vertx.core.http.HttpClientRequest; 22 | import io.vertx.core.http.HttpClientResponse; 23 | import jakarta.enterprise.context.ApplicationScoped; 24 | import org.jboss.resteasy.reactive.client.api.ClientLogger; 25 | 26 | @ApplicationScoped 27 | public class RequestLogger implements ClientLogger { 28 | 29 | @Override 30 | public void setBodySize(int bodySize) { 31 | } 32 | 33 | @Override 34 | public void logResponse(HttpClientResponse response, boolean redirect) { 35 | Log.infof("%s - %s - %d", response.request().getMethod().name(), response.request().absoluteURI(), response.statusCode()); 36 | } 37 | 38 | @Override 39 | public void logRequest(HttpClientRequest request, Buffer body, boolean omitBody) { 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/src/main/java/io/quarkus/workshop/superheroes/load/client/Villain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.quarkus.workshop.superheroes.load.client; 18 | 19 | public class Villain { 20 | public String id; 21 | public String name; 22 | public String otherName; 23 | public int level; 24 | public String picture; 25 | public String powers; 26 | 27 | @Override 28 | public String toString() { 29 | return "Villain{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/src/main/java/io/quarkus/workshop/superheroes/load/client/VillainProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.quarkus.workshop.superheroes.load.client; 18 | 19 | import io.quarkus.rest.client.reactive.ClientExceptionMapper; 20 | import jakarta.ws.rs.DELETE; 21 | import jakarta.ws.rs.GET; 22 | import jakarta.ws.rs.POST; 23 | import jakarta.ws.rs.Path; 24 | import jakarta.ws.rs.PathParam; 25 | import jakarta.ws.rs.Produces; 26 | import jakarta.ws.rs.core.MediaType; 27 | import jakarta.ws.rs.core.Response; 28 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; 29 | 30 | @Path("/api/villains") 31 | @Produces(MediaType.APPLICATION_JSON) 32 | @RegisterRestClient(configKey = "villain") 33 | public interface VillainProxy { 34 | @GET 35 | @Path("/hello") 36 | @Produces(MediaType.TEXT_PLAIN) 37 | Response hello(); 38 | 39 | @GET 40 | Response all(); 41 | 42 | @GET 43 | @Path("/random") 44 | Response random(); 45 | 46 | @POST 47 | Response create(Villain villain); 48 | 49 | @GET 50 | @Path("/{id}") 51 | Response get(@PathParam("id") String id); 52 | 53 | @DELETE 54 | @Path("/{id}") 55 | Response delete(@PathParam("id") String id); 56 | 57 | @ClientExceptionMapper 58 | static RuntimeException toException(Response response) { 59 | return null; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/src/main/java/io/quarkus/workshop/superheroes/load/package-info.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.load; 2 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/src/main/java/io/quarkus/workshop/superheroes/load/scenarios/Scenario.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package io.quarkus.workshop.superheroes.load.scenarios; 18 | 19 | import jakarta.ws.rs.core.Response; 20 | 21 | import java.util.List; 22 | import java.util.Random; 23 | import java.util.function.Supplier; 24 | 25 | abstract public class Scenario { 26 | public abstract void run(); 27 | 28 | protected void run(Random random) { 29 | try { 30 | List> suppliers = callSupplier(); 31 | suppliers.get(random.nextInt(suppliers.size())).get(); 32 | } catch (Throwable ex) { 33 | // Ignore 34 | } 35 | } 36 | 37 | protected abstract List> callSupplier(); 38 | 39 | protected abstract E create(); 40 | } 41 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/load-super-heroes/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.tls.trust-all=true 2 | quarkus.log.console.format=%d{yyyy-MM-dd HH:mm:ss} %-5p %s%e%n 3 | quarkus.rest-client.fight.url=http://localhost:8082 4 | quarkus.rest-client.hero.url=http://localhost:8083 5 | quarkus.rest-client.villain.url=http://localhost:8084 6 | quarkus.rest-client.logging.scope=request-response 7 | 8 | # scheduler 9 | villain-scenario.every.expr=2s 10 | hero-scenario.every.expr=2s 11 | fight-scenario.every.expr=1s 12 | #quarkus.native.additional-build-args=--initialize-at-run-time=net.datafaker.service.RandomService\\,sun.java2d.pipe.Region 13 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !target/*-runner 3 | !target/*-runner.jar 4 | !target/lib/* 5 | !target/quarkus-app/* -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/.gitignore: -------------------------------------------------------------------------------- 1 | #Maven 2 | target/ 3 | pom.xml.tag 4 | pom.xml.releaseBackup 5 | pom.xml.versionsBackup 6 | release.properties 7 | .flattened-pom.xml 8 | 9 | # Eclipse 10 | .project 11 | .classpath 12 | .settings/ 13 | bin/ 14 | 15 | # IntelliJ 16 | .idea 17 | *.ipr 18 | *.iml 19 | *.iws 20 | 21 | # NetBeans 22 | nb-configuration.xml 23 | 24 | # Visual Studio Code 25 | .vscode 26 | .factorypath 27 | 28 | # OSX 29 | .DS_Store 30 | 31 | # Vim 32 | *.swp 33 | *.swo 34 | 35 | # patch 36 | *.orig 37 | *.rej 38 | 39 | # Local environment 40 | .env 41 | 42 | # Plugin directory 43 | /.quarkus/cli/plugins/ 44 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/.mvn/wrapper/.gitignore: -------------------------------------------------------------------------------- 1 | maven-wrapper.jar 2 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 19 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/docker/Dockerfile.build-native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # It uses a micro base image, tuned for Quarkus native executables. 4 | # It reduces the size of the resulting container image. 5 | # Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. 6 | # 7 | # Build the image with: 8 | # 9 | # docker build -f src/main/docker/Dockerfile.build-native -t quarkus/rest-fights . 10 | # 11 | # Then run the container using: 12 | # 13 | # docker run -i --rm -p 8080:8080 quarkus/rest-fights 14 | # 15 | ### 16 | 17 | ## Stage 1 : build with maven builder image with native capabilities 18 | FROM quay.io/quarkus/ubi-quarkus-native-image:22.0-java11 AS build 19 | COPY --chown=quarkus:quarkus mvnw /code/mvnw 20 | COPY --chown=quarkus:quarkus .mvn /code/.mvn 21 | COPY --chown=quarkus:quarkus pom.xml /code/ 22 | USER quarkus 23 | WORKDIR /code 24 | RUN ./mvnw -B org.apache.maven.plugins:maven-dependency-plugin:3.1.2:go-offline 25 | COPY src /code/src 26 | RUN ./mvnw package -Pnative -Dmaven.test.skip=true 27 | 28 | ## Stage 2 : create the docker final image 29 | FROM quay.io/quarkus/quarkus-micro-image:1.0 30 | WORKDIR /work/ 31 | COPY --from=build /code/target/*-runner /work/application 32 | 33 | # set up permissions for user `1001` 34 | RUN chmod 775 /work /work/application \ 35 | && chown -R 1001 /work \ 36 | && chmod -R "g+rwX" /work \ 37 | && chown -R 1001:root /work 38 | 39 | EXPOSE 8080 40 | USER 1001 41 | 42 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] 43 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/docker/Dockerfile.native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # 4 | # Before building the container image run: 5 | # 6 | # ./mvnw package -Dnative 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/rest-fights . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/rest-fights 15 | # 16 | ### 17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9 18 | WORKDIR /work/ 19 | RUN chown 1001 /work \ 20 | && chmod "g+rwX" /work \ 21 | && chown 1001:root /work 22 | COPY --chown=1001:root target/*-runner /work/application 23 | 24 | EXPOSE 8080 25 | USER 1001 26 | 27 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 28 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/docker/Dockerfile.native-micro: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # It uses a micro base image, tuned for Quarkus native executables. 4 | # It reduces the size of the resulting container image. 5 | # Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. 6 | # 7 | # Before building the container image run: 8 | # 9 | # ./mvnw package -Dnative 10 | # 11 | # Then, build the image with: 12 | # 13 | # docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/rest-fights . 14 | # 15 | # Then run the container using: 16 | # 17 | # docker run -i --rm -p 8080:8080 quarkus/rest-fights 18 | # 19 | ### 20 | FROM quay.io/quarkus/quarkus-micro-image:2.0 21 | WORKDIR /work/ 22 | RUN chown 1001 /work \ 23 | && chmod "g+rwX" /work \ 24 | && chown 1001:root /work 25 | COPY --chown=1001:root target/*-runner /work/application 26 | 27 | EXPOSE 8080 28 | USER 1001 29 | 30 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 31 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/java/io/quarkus/workshop/superheroes/fight/Fight.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight; 2 | 3 | import io.quarkus.hibernate.orm.panache.PanacheEntity; 4 | import org.eclipse.microprofile.openapi.annotations.media.Schema; 5 | 6 | import jakarta.persistence.Column; 7 | import jakarta.persistence.Entity; 8 | import jakarta.validation.constraints.NotNull; 9 | 10 | import java.time.Instant; 11 | 12 | // tag::adocJavadoc[] 13 | 14 | /** 15 | * Entity class for a Fight. Re-used in the API layer 16 | */ 17 | // end::adocJavadoc[] 18 | @Entity 19 | @Schema(description = "Each fight has a winner and a loser") 20 | public class Fight extends PanacheEntity { 21 | 22 | @NotNull 23 | public Instant fightDate; 24 | @NotNull 25 | public String winnerName; 26 | @NotNull 27 | public int winnerLevel; 28 | @NotNull 29 | @Column(columnDefinition = "TEXT") 30 | public String winnerPowers; 31 | @NotNull 32 | public String winnerPicture; 33 | @NotNull 34 | public String loserName; 35 | @NotNull 36 | public int loserLevel; 37 | @NotNull 38 | @Column(columnDefinition = "TEXT") 39 | public String loserPowers; 40 | @NotNull 41 | public String loserPicture; 42 | @NotNull 43 | public String winnerTeam; 44 | @NotNull 45 | public String loserTeam; 46 | } 47 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/java/io/quarkus/workshop/superheroes/fight/Fighters.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight; 2 | 3 | import io.quarkus.workshop.superheroes.fight.client.Hero; 4 | import io.quarkus.workshop.superheroes.fight.client.Villain; 5 | import org.eclipse.microprofile.openapi.annotations.media.Schema; 6 | 7 | import jakarta.validation.constraints.NotNull; 8 | 9 | // tag::adocJavadoc[] 10 | 11 | /** 12 | * Entity class representing Fighters 13 | */ 14 | // end::adocJavadoc[] 15 | @Schema(description = "A fight between one hero and one villain") 16 | public class Fighters { 17 | 18 | @NotNull 19 | public Hero hero; 20 | @NotNull 21 | public Villain villain; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/java/io/quarkus/workshop/superheroes/fight/client/Hero.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight.client; 2 | 3 | import org.eclipse.microprofile.openapi.annotations.media.Schema; 4 | 5 | import jakarta.validation.constraints.NotNull; 6 | 7 | // tag::adocJavadoc[] 8 | 9 | /** 10 | * POJO representing a Hero response from the Hero service 11 | */ 12 | // end::adocJavadoc[] 13 | @Schema(description = "The hero fighting against the villain") 14 | public class Hero { 15 | 16 | @NotNull 17 | public String name; 18 | @NotNull 19 | public int level; 20 | @NotNull 21 | public String picture; 22 | public String powers; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/java/io/quarkus/workshop/superheroes/fight/client/HeroProxy.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight.client; 2 | 3 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; 4 | 5 | import jakarta.ws.rs.GET; 6 | import jakarta.ws.rs.Path; 7 | import jakarta.ws.rs.Produces; 8 | import jakarta.ws.rs.core.MediaType; 9 | 10 | @Path("/api/heroes") 11 | @Produces(MediaType.APPLICATION_JSON) 12 | @RegisterRestClient(configKey = "hero") 13 | public interface HeroProxy { 14 | 15 | @GET 16 | @Path("/random") 17 | Hero findRandomHero(); 18 | } 19 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/java/io/quarkus/workshop/superheroes/fight/client/NarrationProxy.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight.client; 2 | 3 | import io.quarkus.workshop.superheroes.fight.Fight; 4 | import jakarta.ws.rs.Consumes; 5 | import jakarta.ws.rs.POST; 6 | import jakarta.ws.rs.Path; 7 | import jakarta.ws.rs.Produces; 8 | import jakarta.ws.rs.core.MediaType; 9 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; 10 | 11 | @Path("/api/narration") 12 | @Produces(MediaType.TEXT_PLAIN) 13 | @Consumes(MediaType.APPLICATION_JSON) 14 | @RegisterRestClient(configKey = "narration") 15 | public interface NarrationProxy { 16 | 17 | @POST 18 | String narrate(Fight fight); 19 | } 20 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/java/io/quarkus/workshop/superheroes/fight/client/Villain.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight.client; 2 | 3 | import org.eclipse.microprofile.openapi.annotations.media.Schema; 4 | 5 | import jakarta.validation.constraints.NotNull; 6 | 7 | // tag::adocJavadoc[] 8 | 9 | /** 10 | * POJO representing a Villain response from the Villain service 11 | */ 12 | // end::adocJavadoc[] 13 | @Schema(description = "The villain fighting against the hero") 14 | public class Villain { 15 | 16 | @NotNull 17 | public String name; 18 | @NotNull 19 | public int level; 20 | @NotNull 21 | public String picture; 22 | public String powers; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/java/io/quarkus/workshop/superheroes/fight/client/VillainProxy.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight.client; 2 | 3 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; 4 | 5 | import jakarta.ws.rs.GET; 6 | import jakarta.ws.rs.Path; 7 | import jakarta.ws.rs.Produces; 8 | import jakarta.ws.rs.core.MediaType; 9 | 10 | @Path("/api/villains") 11 | @Produces(MediaType.APPLICATION_JSON) 12 | @RegisterRestClient(configKey = "villain") 13 | public interface VillainProxy { 14 | 15 | @GET 16 | @Path("/random") 17 | Villain findRandomVillain(); 18 | } 19 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/java/io/quarkus/workshop/superheroes/fight/health/PingFightResourceHealthCheck.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight.health; 2 | 3 | import io.quarkus.workshop.superheroes.fight.FightResource; 4 | import org.eclipse.microprofile.health.HealthCheck; 5 | import org.eclipse.microprofile.health.HealthCheckResponse; 6 | import org.eclipse.microprofile.health.Liveness; 7 | 8 | import jakarta.inject.Inject; 9 | 10 | /** 11 | * {@link HealthCheck} to ping the fight service 12 | */ 13 | @Liveness 14 | public class PingFightResourceHealthCheck implements HealthCheck { 15 | 16 | @Inject 17 | FightResource fightResource; 18 | 19 | @Override 20 | public HealthCheckResponse call() { 21 | String response = fightResource.hello(); 22 | return HealthCheckResponse.named("Ping Fight REST Endpoint").withData("Response", response).up().build(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ## HTTP configuration 2 | quarkus.http.port=8082 3 | 4 | ## Custom banner file path 5 | quarkus.banner.path=banner.txt 6 | 7 | ## drop and create the database at startup (use `update` to only update the schema) 8 | quarkus.hibernate-orm.database.generation=drop-and-create 9 | 10 | ## Logging configuration 11 | quarkus.log.console.enable=true 12 | quarkus.log.console.format=%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n 13 | quarkus.log.console.level=DEBUG 14 | 15 | ## Production configuration 16 | %prod.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/fights_database 17 | %prod.quarkus.datasource.db-kind=postgresql 18 | %prod.quarkus.datasource.username=superfight 19 | %prod.quarkus.datasource.password=superfight 20 | %prod.quarkus.hibernate-orm.sql-load-script=import.sql 21 | %prod.quarkus.log.console.level=INFO 22 | %prod.quarkus.hibernate-orm.database.generation=update 23 | 24 | # tag::adocFaultTolerance[] 25 | process.milliseconds=0 26 | # end::adocFaultTolerance[] 27 | 28 | # tag::adocRestClient[] 29 | ## Rest clients 30 | quarkus.rest-client.hero.url=http://localhost:8083 31 | %test.quarkus.rest-client.hero.url=http://localhost:8093 32 | quarkus.rest-client.villain.url=http://localhost:8084 33 | # end::adocRestClient[] 34 | # tag::adocNarrate[] 35 | quarkus.rest-client.narration.url=http://localhost:8086 36 | # end::adocNarrate[] 37 | 38 | ## Kafka configuration 39 | # tag::adocKafka[] 40 | mp.messaging.outgoing.fights.connector=smallrye-kafka 41 | mp.messaging.outgoing.fights.value.serializer=io.quarkus.kafka.client.serialization.ObjectMapperSerializer 42 | # end::adocKafka[] 43 | 44 | # tag::adocCORS[] 45 | ## CORS 46 | quarkus.http.cors.enabled=true 47 | quarkus.http.cors.origins=* 48 | # end::adocCORS[] 49 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | _______ __ _______ __ __ .___________. ___ .______ __ 2 | | ____|| | / _____|| | | | | | / \ | _ \ | | 3 | | |__ | | | | __ | |__| | `---| |----` / ^ \ | |_) | | | 4 | | __| | | | | |_ | | __ | | | / /_\ \ | ___/ | | 5 | | | | | | |__| | | | | | | | / _____ \ | | | | 6 | |__| |__| \______| |__| |__| |__| /__/ \__\ | _| |__| 7 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/main/resources/import.sql: -------------------------------------------------------------------------------- 1 | ALTER SEQUENCE fight_seq RESTART WITH 50; 2 | 3 | INSERT INTO fight(id, fightDate, winnerName, winnerLevel, winnerPicture, winnerPowers, loserName, loserLevel, loserPicture, loserPowers, winnerTeam, loserTeam) 4 | VALUES (nextval('fight_seq'), current_timestamp, 5 | 'Chewbacca', 5, 'https://www.superherodb.com/pictures2/portraits/10/050/10466.jpg', 'Agility, Longevity, Marksmanship, Natural Weapons, Stealth, Super Strength, Weapons Master', 6 | 'Buuccolo', 3, 'https://www.superherodb.com/pictures2/portraits/10/050/15355.jpg', 'Accelerated Healing, Adaptation, Agility, Flight, Immortality, Intelligence, Invulnerability, Reflexes, Self-Sustenance, Size Changing, Spatial Awareness, Stamina, Stealth, Super Breath, Super Speed, Super Strength, Teleportation', 7 | 'heroes', 'villains'); 8 | INSERT INTO fight(id, fightDate, winnerName, winnerLevel, winnerPicture, winnerPowers, loserName, loserLevel, loserPicture, loserPowers, winnerTeam, loserTeam) 9 | VALUES (nextval('fight_seq'), current_timestamp, 10 | 'Galadriel', 10, 'https://www.superherodb.com/pictures2/portraits/10/050/11796.jpg', 'Danger Sense, Immortality, Intelligence, Invisibility, Magic, Precognition, Telekinesis, Telepathy', 11 | 'Darth Vader', 8, 'https://www.superherodb.com/pictures2/portraits/10/050/10444.jpg', 'Accelerated Healing, Agility, Astral Projection, Cloaking, Danger Sense, Durability, Electrokinesis, Energy Blasts, Enhanced Hearing, Enhanced Senses, Force Fields, Hypnokinesis, Illusions, Intelligence, Jump, Light Control, Marksmanship, Precognition, Psionic Powers, Reflexes, Stealth, Super Speed, Telekinesis, Telepathy, The Force, Weapons Master', 12 | 'heroes', 'villains'); 13 | INSERT INTO fight(id, fightDate, winnerName, winnerLevel, winnerPicture, winnerPowers, loserName, loserLevel, loserPicture, loserPowers, winnerTeam, loserTeam) 14 | VALUES (nextval('fight_seq'), current_timestamp, 15 | 'Annihilus', 23, 'https://www.superherodb.com/pictures2/portraits/10/050/1307.jpg', 'Agility, Durability, Flight, Reflexes, Stamina, Super Speed, Super Strength', 16 | 'Shikamaru', 1, 'https://www.superherodb.com/pictures2/portraits/10/050/11742.jpg', 'Adaptation, Agility, Element Control, Fire Control, Intelligence, Jump, Marksmanship, Possession, Reflexes, Shapeshifting, Stamina, Stealth, Telekinesis, Wallcrawling, Weapon-based Powers, Weapons Master', 17 | 'villains', 'heroes'); 18 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/test/java/io/quarkus/workshop/superheroes/fight/client/DefaultTestHero.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight.client; 2 | 3 | public class DefaultTestHero extends Hero { 4 | public static final String DEFAULT_HERO_NAME = "Super Baguette"; 5 | public static final String DEFAULT_HERO_PICTURE = "super_baguette.png"; 6 | public static final String DEFAULT_HERO_POWERS = "eats baguette really quickly"; 7 | public static final int DEFAULT_HERO_LEVEL = 42; 8 | 9 | public static final DefaultTestHero INSTANCE = new DefaultTestHero(); 10 | 11 | private DefaultTestHero() { 12 | this.name = DEFAULT_HERO_NAME; 13 | this.picture = DEFAULT_HERO_PICTURE; 14 | this.powers = DEFAULT_HERO_POWERS; 15 | this.level = DEFAULT_HERO_LEVEL; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/test/java/io/quarkus/workshop/superheroes/fight/client/DefaultTestVillain.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight.client; 2 | 3 | public class DefaultTestVillain extends Villain { 4 | public static final String DEFAULT_VILLAIN_NAME = "Super Chocolatine"; 5 | public static final String DEFAULT_VILLAIN_PICTURE = "super_chocolatine.png"; 6 | public static final String DEFAULT_VILLAIN_POWERS = "does not eat pain au chocolat"; 7 | public static final int DEFAULT_VILLAIN_LEVEL = 42; 8 | 9 | public static final DefaultTestVillain INSTANCE = new DefaultTestVillain(); 10 | 11 | private DefaultTestVillain() { 12 | this.name = DEFAULT_VILLAIN_NAME; 13 | this.picture = DEFAULT_VILLAIN_PICTURE; 14 | this.powers = DEFAULT_VILLAIN_POWERS; 15 | this.level = DEFAULT_VILLAIN_LEVEL; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/test/java/io/quarkus/workshop/superheroes/fight/client/MockNarrationProxy.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight.client; 2 | 3 | import io.quarkus.test.Mock; 4 | import io.quarkus.workshop.superheroes.fight.Fight; 5 | import jakarta.enterprise.context.ApplicationScoped; 6 | import org.eclipse.microprofile.rest.client.inject.RestClient; 7 | 8 | @Mock 9 | @ApplicationScoped 10 | @RestClient 11 | public class MockNarrationProxy implements NarrationProxy { 12 | 13 | @Override 14 | public String narrate(Fight fight) { 15 | return """ 16 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 17 | Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 18 | Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 19 | Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 20 | """; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-fights/src/test/java/io/quarkus/workshop/superheroes/fight/client/MockVillainProxy.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.fight.client; 2 | 3 | import io.quarkus.test.Mock; 4 | import org.eclipse.microprofile.rest.client.inject.RestClient; 5 | 6 | import jakarta.enterprise.context.ApplicationScoped; 7 | 8 | @Mock 9 | @ApplicationScoped 10 | @RestClient 11 | public class MockVillainProxy implements VillainProxy { 12 | 13 | @Override 14 | public Villain findRandomVillain() { 15 | return DefaultTestVillain.INSTANCE; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !target/*-runner 3 | !target/*-runner.jar 4 | !target/lib/* 5 | !target/quarkus-app/* -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/.gitignore: -------------------------------------------------------------------------------- 1 | #Maven 2 | target/ 3 | pom.xml.tag 4 | pom.xml.releaseBackup 5 | pom.xml.versionsBackup 6 | release.properties 7 | .flattened-pom.xml 8 | 9 | # Eclipse 10 | .project 11 | .classpath 12 | .settings/ 13 | bin/ 14 | 15 | # IntelliJ 16 | .idea 17 | *.ipr 18 | *.iml 19 | *.iws 20 | 21 | # NetBeans 22 | nb-configuration.xml 23 | 24 | # Visual Studio Code 25 | .vscode 26 | .factorypath 27 | 28 | # OSX 29 | .DS_Store 30 | 31 | # Vim 32 | *.swp 33 | *.swo 34 | 35 | # patch 36 | *.orig 37 | *.rej 38 | 39 | # Local environment 40 | .env 41 | 42 | # Plugin directory 43 | /.quarkus/cli/plugins/ 44 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/.mvn/wrapper/.gitignore: -------------------------------------------------------------------------------- 1 | maven-wrapper.jar 2 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 19 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/src/main/docker/Dockerfile.build-native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # It uses a micro base image, tuned for Quarkus native executables. 4 | # It reduces the size of the resulting container image. 5 | # Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. 6 | # 7 | # Build the image with: 8 | # 9 | # docker build -f src/main/docker/Dockerfile.build-native -t quarkus/rest-heroes . 10 | # 11 | # Then run the container using: 12 | # 13 | # docker run -i --rm -p 8080:8080 quarkus/rest-heroes 14 | # 15 | ### 16 | 17 | ## Stage 1 : build with maven builder image with native capabilities 18 | FROM quay.io/quarkus/ubi-quarkus-native-image:22.0-java11 AS build 19 | COPY --chown=quarkus:quarkus mvnw /code/mvnw 20 | COPY --chown=quarkus:quarkus .mvn /code/.mvn 21 | COPY --chown=quarkus:quarkus pom.xml /code/ 22 | USER quarkus 23 | WORKDIR /code 24 | RUN ./mvnw -B org.apache.maven.plugins:maven-dependency-plugin:3.1.2:go-offline 25 | COPY src /code/src 26 | RUN ./mvnw package -Pnative -Dmaven.test.skip=true 27 | 28 | ## Stage 2 : create the docker final image 29 | FROM quay.io/quarkus/quarkus-micro-image:1.0 30 | WORKDIR /work/ 31 | COPY --from=build /code/target/*-runner /work/application 32 | 33 | # set up permissions for user `1001` 34 | RUN chmod 775 /work /work/application \ 35 | && chown -R 1001 /work \ 36 | && chmod -R "g+rwX" /work \ 37 | && chown -R 1001:root /work 38 | 39 | EXPOSE 8080 40 | USER 1001 41 | 42 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] 43 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/src/main/docker/Dockerfile.native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # 4 | # Before building the container image run: 5 | # 6 | # ./mvnw package -Dnative 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/rest-heroes . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/rest-heroes 15 | # 16 | ### 17 | # tag::adocSnippet[] 18 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9 19 | WORKDIR /work/ 20 | RUN chown 1001 /work \ 21 | && chmod "g+rwX" /work \ 22 | && chown 1001:root /work 23 | COPY --chown=1001:root target/*-runner /work/application 24 | 25 | EXPOSE 8080 26 | USER 1001 27 | 28 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 29 | # end::adocSnippet[] 30 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/src/main/docker/Dockerfile.native-micro: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # It uses a micro base image, tuned for Quarkus native executables. 4 | # It reduces the size of the resulting container image. 5 | # Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. 6 | # 7 | # Before building the container image run: 8 | # 9 | # ./mvnw package -Dnative 10 | # 11 | # Then, build the image with: 12 | # 13 | # docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/rest-heroes . 14 | # 15 | # Then run the container using: 16 | # 17 | # docker run -i --rm -p 8080:8080 quarkus/rest-heroes 18 | # 19 | ### 20 | FROM quay.io/quarkus/quarkus-micro-image:2.0 21 | WORKDIR /work/ 22 | RUN chown 1001 /work \ 23 | && chmod "g+rwX" /work \ 24 | && chown 1001:root /work 25 | COPY --chown=1001:root target/*-runner /work/application 26 | 27 | EXPOSE 8080 28 | USER 1001 29 | 30 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 31 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/src/main/java/io/quarkus/workshop/superheroes/hero/Hero.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.hero; 2 | 3 | import io.quarkus.hibernate.reactive.panache.PanacheEntity; 4 | import io.smallrye.mutiny.Uni; 5 | 6 | import jakarta.persistence.Column; 7 | import jakarta.persistence.Entity; 8 | import jakarta.validation.constraints.Min; 9 | import jakarta.validation.constraints.NotNull; 10 | import jakarta.validation.constraints.Size; 11 | 12 | import java.util.Random; 13 | 14 | // tag::adocJavadoc[] 15 | 16 | /** 17 | * JPA entity class for a Hero. Re-used in the API layer. 18 | */ 19 | // end::adocJavadoc[] 20 | @Entity 21 | public class Hero extends PanacheEntity { 22 | 23 | @NotNull 24 | @Size(min = 3, max = 50) 25 | public String name; 26 | 27 | public String otherName; 28 | 29 | @NotNull 30 | @Min(1) 31 | public int level; 32 | public String picture; 33 | 34 | @Column(columnDefinition = "TEXT") 35 | public String powers; 36 | 37 | public static Uni findRandom() { 38 | Random random = new Random(); 39 | return count() 40 | .map(count -> random.nextInt(count.intValue())) 41 | .chain(randomHero -> findAll().page(randomHero, 1) 42 | .firstResult()); 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "Hero{" + 48 | "id=" + id + 49 | ", name='" + name + '\'' + 50 | ", otherName='" + otherName + '\'' + 51 | ", level=" + level + 52 | ", picture='" + picture + '\'' + 53 | ", powers='" + powers + '\'' + 54 | '}'; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/src/main/java/io/quarkus/workshop/superheroes/hero/health/PingHeroResourceHealthCheck.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.hero.health; 2 | 3 | import io.quarkus.workshop.superheroes.hero.HeroResource; 4 | import org.eclipse.microprofile.health.HealthCheck; 5 | import org.eclipse.microprofile.health.HealthCheckResponse; 6 | import org.eclipse.microprofile.health.Liveness; 7 | 8 | import jakarta.inject.Inject; 9 | 10 | /** 11 | * {@link HealthCheck} to ping the Hero service 12 | */ 13 | @Liveness 14 | public class PingHeroResourceHealthCheck implements HealthCheck { 15 | 16 | @Inject 17 | HeroResource heroResource; 18 | 19 | @Override 20 | public HealthCheckResponse call() { 21 | String response = heroResource.hello(); 22 | return HealthCheckResponse.named("Ping Hero REST Endpoint").withData("Response", response).up().build(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ## HTTP configuration 2 | quarkus.http.port=8083 3 | 4 | ## Custom banner file path 5 | quarkus.banner.path=banner.txt 6 | 7 | # drop and create the database at startup (use `update` to only update the schema) 8 | quarkus.hibernate-orm.database.generation=drop-and-create 9 | 10 | %prod.quarkus.datasource.username=superman 11 | %prod.quarkus.datasource.password=superman 12 | %prod.quarkus.datasource.reactive.url=postgresql://localhost:5432/heroes_database 13 | %prod.quarkus.hibernate-orm.sql-load-script=import.sql 14 | 15 | # tag::adocCORS[] 16 | ## CORS 17 | quarkus.http.cors.enabled=true 18 | quarkus.http.cors.origins=* 19 | # end::adocCORS[] 20 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | __ __ _______ .______ ______ ___ .______ __ 2 | | | | | | ____|| _ \ / __ \ / \ | _ \ | | 3 | | |__| | | |__ | |_) | | | | | / ^ \ | |_) | | | 4 | | __ | | __| | / | | | | / /_\ \ | ___/ | | 5 | | | | | | |____ | |\ \----.| `--' | / _____ \ | | | | 6 | |__| |__| |_______|| _| `._____| \______/ /__/ \__\ | _| |__| 7 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-heroes/src/test/java/io/quarkus/workshop/superheroes/hero/HeroResourceIT.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.hero; 2 | 3 | import io.quarkus.test.junit.QuarkusIntegrationTest; 4 | 5 | @QuarkusIntegrationTest 6 | public class HeroResourceIT extends HeroResourceTest { 7 | // Execute the same tests but in packaged mode. 8 | } 9 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !target/*-runner 3 | !target/*-runner.jar 4 | !target/lib/* 5 | !target/quarkus-app/* -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/.gitignore: -------------------------------------------------------------------------------- 1 | #Maven 2 | target/ 3 | pom.xml.tag 4 | pom.xml.releaseBackup 5 | pom.xml.versionsBackup 6 | release.properties 7 | .flattened-pom.xml 8 | 9 | # Eclipse 10 | .project 11 | .classpath 12 | .settings/ 13 | bin/ 14 | 15 | # IntelliJ 16 | .idea 17 | *.ipr 18 | *.iml 19 | *.iws 20 | 21 | # NetBeans 22 | nb-configuration.xml 23 | 24 | # Visual Studio Code 25 | .vscode 26 | .factorypath 27 | 28 | # OSX 29 | .DS_Store 30 | 31 | # Vim 32 | *.swp 33 | *.swo 34 | 35 | # patch 36 | *.orig 37 | *.rej 38 | 39 | # Local environment 40 | .env 41 | 42 | # Plugin directory 43 | /.quarkus/cli/plugins/ 44 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/.mvn/wrapper/.gitignore: -------------------------------------------------------------------------------- 1 | maven-wrapper.jar 2 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 19 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/src/main/docker/Dockerfile.native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # 4 | # Before building the container image run: 5 | # 6 | # ./mvnw package -Dnative 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/rest-narration . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/rest-narration 15 | # 16 | ### 17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9 18 | WORKDIR /work/ 19 | RUN chown 1001 /work \ 20 | && chmod "g+rwX" /work \ 21 | && chown 1001:root /work 22 | COPY --chown=1001:root target/*-runner /work/application 23 | 24 | EXPOSE 8080 25 | USER 1001 26 | 27 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 28 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/src/main/docker/Dockerfile.native-micro: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # It uses a micro base image, tuned for Quarkus native executables. 4 | # It reduces the size of the resulting container image. 5 | # Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. 6 | # 7 | # Before building the container image run: 8 | # 9 | # ./mvnw package -Dnative 10 | # 11 | # Then, build the image with: 12 | # 13 | # docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/rest-narration . 14 | # 15 | # Then run the container using: 16 | # 17 | # docker run -i --rm -p 8080:8080 quarkus/rest-narration 18 | # 19 | ### 20 | FROM quay.io/quarkus/quarkus-micro-image:2.0 21 | WORKDIR /work/ 22 | RUN chown 1001 /work \ 23 | && chmod "g+rwX" /work \ 24 | && chown 1001:root /work 25 | COPY --chown=1001:root target/*-runner /work/application 26 | 27 | EXPOSE 8080 28 | USER 1001 29 | 30 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 31 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/src/main/java/io/quarkus/workshop/superheroes/narration/Fight.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.narration; 2 | 3 | import org.eclipse.microprofile.openapi.annotations.media.Schema; 4 | 5 | @Schema(description = "The fight that is narrated") 6 | public class Fight { 7 | 8 | public String winnerName; 9 | public int winnerLevel; 10 | public String winnerPowers; 11 | public String loserName; 12 | public int loserLevel; 13 | public String loserPowers; 14 | public String winnerTeam; 15 | public String loserTeam; 16 | } 17 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/src/main/java/io/quarkus/workshop/superheroes/narration/NarrationResource.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.narration; 2 | 3 | import jakarta.inject.Inject; 4 | import jakarta.ws.rs.*; 5 | import jakarta.ws.rs.core.MediaType; 6 | import jakarta.ws.rs.core.Response; 7 | import org.eclipse.microprofile.openapi.annotations.tags.Tag; 8 | 9 | /** 10 | * JAX-RS API endpoints with /api/narration as the base URI for all endpoints 11 | */ 12 | 13 | @Path("/api/narration") 14 | @Produces(MediaType.TEXT_PLAIN) 15 | @Consumes(MediaType.APPLICATION_JSON) 16 | @Tag(name = "narration") 17 | public class NarrationResource { 18 | 19 | @Inject 20 | NarrationService service; 21 | 22 | @POST 23 | public Response narrate(Fight fight) throws Exception { 24 | String narration = service.narrate(fight); 25 | return Response.status(Response.Status.CREATED).entity(narration).build(); 26 | } 27 | 28 | @GET 29 | @Path("/hello") 30 | public String hello() { 31 | return "Hello Narration Resource"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/src/main/java/io/quarkus/workshop/superheroes/narration/NarrationService.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.narration; 2 | 3 | public interface NarrationService { 4 | String narrate(Fight fight) throws Exception; 5 | } 6 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/src/main/resources/NarrationSkill/NarrateFight/skprompt.txt: -------------------------------------------------------------------------------- 1 | ACT LIKE YOU WERE A MARVEL COMICS WRITTER, EXPERT IN ALL SORTS OF SUPER HEROES AND SUPER VILLAINS. 2 | NARRATE THE FIGHT BETWEEN A SUPER HERO AND A SUPER VILLAIN. 3 | DURING THE NARRATION DON'T REPEAT "super hero" OR "super villain" WE KNOW WHO IS WHO. 4 | WRITE 4 PARAGRAPHS MAXIMUM. 5 | 6 | THE NARRATION MUST BE: 7 | - G RATED 8 | - WORKPLACE/FAMILY SAFE 9 | NO SEXISM, RACISM OR OTHER BIAS/BIGOTRY 10 | 11 | BE CREATIVE. 12 | 13 | HERE IS THE DATA YOU WILL USE FOR THE WINNER: 14 | 15 | +++++ 16 | name: {{$winner_name}} 17 | powers: {{$winner_powers}} 18 | level: {{$winner_level}} 19 | +++++ 20 | 21 | HERE IS THE DATA YOU WILL USE FOR THE LOSER: 22 | 23 | +++++ 24 | name: {{$loser_name}} 25 | powers: {{$loser_powers}} 26 | level: {{$loser_level}} 27 | +++++ 28 | 29 | HERE IS THE DATA YOU WILL USE FOR THE FIGHT: 30 | 31 | +++++ 32 | {{$winner_name}} WHO IS A {{$winner_team}} HAS WON THE FIGHT AGAINST {{$loser_name}} WHO IS A {{$loser_team}}. 33 | +++++ 34 | 35 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ## HTTP configuration 2 | quarkus.http.port=8086 3 | 4 | ## Custom banner file path 5 | quarkus.banner.path=banner.txt 6 | 7 | ## CORS 8 | quarkus.http.cors.enabled=true 9 | quarkus.http.cors.origins=* 10 | ## Logging configuration 11 | quarkus.log.category."com.microsoft.semantickernel".level=DEBUG 12 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-narration/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | .__ __. ___ .______ .______ ___ .___________. _______ 2 | | \ | | / \ | _ \ | _ \ / \ | || ____| 3 | | \| | / ^ \ | |_) | | |_) | / ^ \ `---| |----`| |__ 4 | | . ` | / /_\ \ | / | / / /_\ \ | | | __| 5 | | |\ | / _____ \ | |\ \----.| |\ \----./ _____ \ | | | |____ 6 | |__| \__| /__/ \__\ | _| `._____|| _| `._____/__/ \__\ |__| |_______| 7 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !target/*-runner 3 | !target/*-runner.jar 4 | !target/lib/* 5 | !target/quarkus-app/* -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/.gitignore: -------------------------------------------------------------------------------- 1 | #Maven 2 | target/ 3 | pom.xml.tag 4 | pom.xml.releaseBackup 5 | pom.xml.versionsBackup 6 | release.properties 7 | .flattened-pom.xml 8 | 9 | # Eclipse 10 | .project 11 | .classpath 12 | .settings/ 13 | bin/ 14 | 15 | # IntelliJ 16 | .idea 17 | *.ipr 18 | *.iml 19 | *.iws 20 | 21 | # NetBeans 22 | nb-configuration.xml 23 | 24 | # Visual Studio Code 25 | .vscode 26 | .factorypath 27 | 28 | # OSX 29 | .DS_Store 30 | 31 | # Vim 32 | *.swp 33 | *.swo 34 | 35 | # patch 36 | *.orig 37 | *.rej 38 | 39 | # Local environment 40 | .env 41 | 42 | # Plugin directory 43 | /.quarkus/cli/plugins/ 44 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/.mvn/wrapper/.gitignore: -------------------------------------------------------------------------------- 1 | maven-wrapper.jar 2 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 19 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/jd-gui.cfg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | false 8 | 9 | com.apple.laf.AquaLookAndFeel 10 | 11 | 12 | /Users/clement/Development/quarkus/quarkus-workshops/quarkus-workshop-super-heroes/super-heroes/rest-villains-complete/target/quarkus-app/quarkus/transformed-bytecode.jar 13 | 14 | 15 | /Users/clement/Development/quarkus/quarkus-workshops/quarkus-workshop-super-heroes/super-heroes/rest-villains-complete 16 | /Users/clement/Development/quarkus/quarkus-workshops/quarkus-workshop-super-heroes/super-heroes/rest-villains-complete 17 | 18 | 19 | 0xFF6666 20 | 1.1.3 21 | 22 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/src/main/docker/Dockerfile.build-native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # It uses a micro base image, tuned for Quarkus native executables. 4 | # It reduces the size of the resulting container image. 5 | # Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. 6 | # 7 | # Build the image with: 8 | # 9 | # Make sure you are in the rest-villains directory 10 | # docker build -f src/main/docker/Dockerfile.build-native -t quarkus/rest-villains ../.. 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/rest-villains 15 | # 16 | ### 17 | 18 | ## Stage 1 : build with maven builder image with native capabilities 19 | FROM quay.io/quarkus/ubi-quarkus-native-image:22.0-java11 AS build 20 | USER quarkus 21 | WORKDIR /code 22 | COPY --chown=quarkus:quarkus . ${WORKDIR} 23 | 24 | RUN ./mvnw -B clean install -DskipTests -pl :extension-version-parent -amd 25 | RUN ./mvnw -B clean package -f super-heroes/rest-villains -DskipTests -Pnative 26 | 27 | ## Stage 2 : create the docker final image 28 | FROM quay.io/quarkus/quarkus-micro-image:1.0 29 | WORKDIR /work/ 30 | COPY --from=build /code/super-heroes/rest-villains/target/*-runner /work/application 31 | 32 | # set up permissions for user `1001` 33 | RUN chmod 775 /work /work/application \ 34 | && chown -R 1001 /work \ 35 | && chmod -R "g+rwX" /work \ 36 | && chown -R 1001:root /work 37 | 38 | EXPOSE 8080 39 | USER 1001 40 | 41 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] 42 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/src/main/docker/Dockerfile.native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # 4 | # Before building the container image run: 5 | # 6 | # ./mvnw package -Dnative 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/rest-villains . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/rest-villains 15 | # 16 | ### 17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9 18 | WORKDIR /work/ 19 | RUN chown 1001 /work \ 20 | && chmod "g+rwX" /work \ 21 | && chown 1001:root /work 22 | COPY --chown=1001:root target/*-runner /work/application 23 | 24 | EXPOSE 8080 25 | USER 1001 26 | 27 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 28 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/src/main/docker/Dockerfile.native-micro: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # It uses a micro base image, tuned for Quarkus native executables. 4 | # It reduces the size of the resulting container image. 5 | # Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. 6 | # 7 | # Before building the container image run: 8 | # 9 | # ./mvnw package -Dnative 10 | # 11 | # Then, build the image with: 12 | # 13 | # docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/rest-villains . 14 | # 15 | # Then run the container using: 16 | # 17 | # docker run -i --rm -p 8080:8080 quarkus/rest-villains 18 | # 19 | ### 20 | FROM quay.io/quarkus/quarkus-micro-image:2.0 21 | WORKDIR /work/ 22 | RUN chown 1001 /work \ 23 | && chmod "g+rwX" /work \ 24 | && chown 1001:root /work 25 | COPY --chown=1001:root target/*-runner /work/application 26 | 27 | EXPOSE 8080 28 | USER 1001 29 | 30 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 31 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/src/main/java/io/quarkus/workshop/superheroes/villain/Villain.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.villain; 2 | 3 | import io.quarkus.hibernate.orm.panache.PanacheEntity; 4 | 5 | import jakarta.persistence.Column; 6 | import jakarta.persistence.Entity; 7 | import jakarta.validation.constraints.Min; 8 | import jakarta.validation.constraints.NotNull; 9 | import jakarta.validation.constraints.Size; 10 | 11 | import java.util.Random; 12 | 13 | // tag::adocJavadoc[] 14 | 15 | /** 16 | * JPA entity class for a Villain. Re-used in the API layer. 17 | */ 18 | // end::adocJavadoc[] 19 | @Entity 20 | public class Villain extends PanacheEntity { 21 | 22 | @NotNull 23 | @Size(min = 3, max = 50) 24 | public String name; 25 | 26 | public String otherName; 27 | 28 | @NotNull 29 | @Min(1) 30 | public int level; 31 | 32 | public String picture; 33 | 34 | @Column(columnDefinition = "TEXT") 35 | public String powers; 36 | 37 | // tag::adocMethodFindRandom[] 38 | public static Villain findRandom() { 39 | long countVillains = count(); 40 | Random random = new Random(); 41 | int randomVillain = random.nextInt((int) countVillains); 42 | return findAll().page(randomVillain, 1).firstResult(); 43 | } 44 | // end::adocMethodFindRandom[] 45 | 46 | @Override 47 | public String toString() { 48 | return "Villain{" + 49 | "id=" + id + 50 | ", name='" + name + '\'' + 51 | ", otherName='" + otherName + '\'' + 52 | ", level=" + level + 53 | ", picture='" + picture + '\'' + 54 | ", powers='" + powers + '\'' + 55 | '}'; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/src/main/java/io/quarkus/workshop/superheroes/villain/VillainApplication.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.villain; 2 | 3 | import jakarta.ws.rs.ApplicationPath; 4 | import jakarta.ws.rs.core.Application; 5 | import org.eclipse.microprofile.openapi.annotations.ExternalDocumentation; 6 | import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition; 7 | import org.eclipse.microprofile.openapi.annotations.info.Contact; 8 | import org.eclipse.microprofile.openapi.annotations.info.Info; 9 | import org.eclipse.microprofile.openapi.annotations.servers.Server; 10 | 11 | @ApplicationPath("/") 12 | @OpenAPIDefinition( 13 | info = @Info( 14 | title = "Villain API", 15 | description = "This API allows CRUD operations on a villain", 16 | version = "1.0", 17 | contact = @Contact(name = "Quarkus", url = "https://github.com/quarkusio") 18 | ), 19 | servers = { @Server(url = "http://localhost:8084") }, 20 | externalDocs = @ExternalDocumentation(url = "https://github.com/quarkusio/quarkus-workshops", description = "All the Quarkus workshops") 21 | ) 22 | public class VillainApplication extends Application { 23 | // Empty body 24 | } 25 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/src/main/java/io/quarkus/workshop/superheroes/villain/VillainApplicationLifeCycle.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.villain; 2 | 3 | import io.quarkus.runtime.ShutdownEvent; 4 | import io.quarkus.runtime.StartupEvent; 5 | import io.quarkus.runtime.configuration.ConfigUtils; 6 | import jakarta.enterprise.context.ApplicationScoped; 7 | import jakarta.enterprise.event.Observes; 8 | import org.jboss.logging.Logger; 9 | 10 | // tag::adocJavadoc[] 11 | 12 | /** 13 | * Demonstrates how to use Quarkus {@link StartupEvent}s and {@link ShutdownEvent}s as well as how to gain access to the {@link ConfigUtils}. 14 | */ 15 | // end::adocJavadoc[] 16 | @ApplicationScoped 17 | public class VillainApplicationLifeCycle { 18 | 19 | private static final Logger LOGGER = Logger.getLogger(VillainApplicationLifeCycle.class); 20 | 21 | void onStart(@Observes StartupEvent ev) { 22 | LOGGER.info(" __ ___ _ _ _ _ ____ ___ "); 23 | LOGGER.info(" \\ \\ / (_) | | __ _(_)_ __ / \\ | _ \\_ _|"); 24 | LOGGER.info(" \\ \\ / /| | | |/ _` | | '_ \\ / _ \\ | |_) | | "); 25 | LOGGER.info(" \\ V / | | | | (_| | | | | | / ___ \\| __/| | "); 26 | LOGGER.info(" \\_/ |_|_|_|\\__,_|_|_| |_| /_/ \\_\\_| |___|"); 27 | // tag::adocProfile[] 28 | LOGGER.info("The application VILLAIN is starting with profile " + ConfigUtils.getProfiles()); 29 | // end::adocProfile[] 30 | } 31 | 32 | void onStop(@Observes ShutdownEvent ev) { 33 | LOGGER.info("The application VILLAIN is stopping..."); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/src/main/java/io/quarkus/workshop/superheroes/villain/VillainService.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.villain; 2 | 3 | import static jakarta.transaction.Transactional.TxType.REQUIRED; 4 | import static jakarta.transaction.Transactional.TxType.SUPPORTS; 5 | 6 | import java.util.List; 7 | 8 | import jakarta.enterprise.context.ApplicationScoped; 9 | import jakarta.transaction.Transactional; 10 | import jakarta.validation.Valid; 11 | import org.eclipse.microprofile.config.inject.ConfigProperty; 12 | 13 | // tag::adocJavadoc[] 14 | 15 | /** 16 | * Service class containing business methods for the application. 17 | */ 18 | // end::adocJavadoc[] 19 | @ApplicationScoped 20 | @Transactional(REQUIRED) 21 | public class VillainService { 22 | 23 | // tag::adocLevel[] 24 | @ConfigProperty(name = "level.multiplier", defaultValue = "1.0") 25 | double levelMultiplier; 26 | // end::adocLevel[] 27 | 28 | @Transactional(SUPPORTS) 29 | public List findAllVillains() { 30 | return Villain.listAll(); 31 | } 32 | 33 | @Transactional(SUPPORTS) 34 | public Villain findVillainById(Long id) { 35 | return Villain.findById(id); 36 | } 37 | 38 | @Transactional(SUPPORTS) 39 | public Villain findRandomVillain() { 40 | Villain randomVillain = null; 41 | while (randomVillain == null) { 42 | randomVillain = Villain.findRandom(); 43 | } 44 | return randomVillain; 45 | } 46 | 47 | public Villain persistVillain(@Valid Villain villain) { 48 | // tag::adocLevel[] 49 | villain.level = (int) Math.round(villain.level * levelMultiplier); 50 | // end::adocLevel[] 51 | villain.persist(); 52 | return villain; 53 | } 54 | 55 | public Villain updateVillain(@Valid Villain villain) { 56 | Villain entity = Villain.findById(villain.id); 57 | entity.name = villain.name; 58 | entity.otherName = villain.otherName; 59 | entity.level = villain.level; 60 | entity.picture = villain.picture; 61 | entity.powers = villain.powers; 62 | return entity; 63 | } 64 | 65 | public void deleteVillain(Long id) { 66 | Villain.deleteById(id); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/src/main/java/io/quarkus/workshop/superheroes/villain/health/PingVillainResourceHealthCheck.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.villain.health; 2 | 3 | import io.quarkus.workshop.superheroes.villain.VillainResource; 4 | import jakarta.inject.Inject; 5 | import org.eclipse.microprofile.health.HealthCheck; 6 | import org.eclipse.microprofile.health.HealthCheckResponse; 7 | import org.eclipse.microprofile.health.Liveness; 8 | 9 | @Liveness 10 | public class PingVillainResourceHealthCheck implements HealthCheck { 11 | @Inject 12 | VillainResource villainResource; 13 | 14 | @Override 15 | public HealthCheckResponse call() { 16 | String response = villainResource.hello(); 17 | return HealthCheckResponse.named("Ping Villain REST Endpoint").withData("Response", response).up().build(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ## HTTP configuration 2 | quarkus.http.port=8084 3 | 4 | # drop and create the database at startup (use `update` to only update the schema) 5 | quarkus.hibernate-orm.database.generation=drop-and-create 6 | 7 | level.multiplier=0.5 8 | %test.level.multiplier=1 9 | 10 | quarkus.log.console.enable=true 11 | quarkus.log.console.format=%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n 12 | quarkus.log.console.level=INFO 13 | quarkus.log.console.darken=1 14 | 15 | ## CORS 16 | quarkus.http.cors.enabled=true 17 | quarkus.http.cors.origins=* 18 | 19 | %prod.quarkus.datasource.username=superbad 20 | %prod.quarkus.datasource.password=superbad 21 | %prod.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/villains_database 22 | %prod.quarkus.hibernate-orm.sql-load-script=import.sql 23 | 24 | quarkus.version.enabled=false 25 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/rest-villains/src/test/java/io/quarkus/workshop/superheroes/villain/VillainResourceIT.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.villain; 2 | 3 | import io.quarkus.test.junit.QuarkusIntegrationTest; 4 | 5 | @QuarkusIntegrationTest 6 | public class VillainResourceIT extends VillainResourceTest { 7 | // Execute the same tests but in packaged mode. 8 | } 9 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/.dockerignore: -------------------------------------------------------------------------------- 1 | node 2 | images 3 | dist 4 | deploy 5 | src/main 6 | 7 | .dockerignore 8 | Dockerfile* 9 | .gitignore 10 | .git 11 | 12 | *.md 13 | *.iml 14 | 15 | # Logs 16 | logs 17 | *.log 18 | 19 | # Runtime data 20 | pids 21 | *.pid 22 | *.seed 23 | 24 | # Directory for instrumented libs generated by jscoverage/JSCover 25 | lib-cov 26 | 27 | # Coverage directory used by tools like istanbul 28 | coverage 29 | 30 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 31 | .grunt 32 | 33 | # node-waf configuration 34 | .lock-wscript 35 | 36 | # Compiled binary addons (http://nodejs.org/api/addons.html) 37 | build/Release 38 | 39 | # Dependency directory 40 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 41 | node_modules 42 | 43 | server/*.spec.js 44 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/.mvn/wrapper/.gitignore: -------------------------------------------------------------------------------- 1 | maven-wrapper.jar 2 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.3/apache-maven-3.9.3-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 19 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/main/docker/Dockerfile.native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # 4 | # Before building the container image run: 5 | # 6 | # ./mvnw package -Dnative 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/ui-super-heroes . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/ui-super-heroes 15 | # 16 | ### 17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8 18 | WORKDIR /work/ 19 | RUN chown 1001 /work \ 20 | && chmod "g+rwX" /work \ 21 | && chown 1001:root /work 22 | COPY --chown=1001:root target/*-runner /work/application 23 | 24 | EXPOSE 8080 25 | USER 1001 26 | 27 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 28 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/main/docker/Dockerfile.native-micro: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode. 3 | # It uses a micro base image, tuned for Quarkus native executables. 4 | # It reduces the size of the resulting container image. 5 | # Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image. 6 | # 7 | # Before building the container image run: 8 | # 9 | # ./mvnw package -Dnative 10 | # 11 | # Then, build the image with: 12 | # 13 | # docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/ui-super-heroes . 14 | # 15 | # Then run the container using: 16 | # 17 | # docker run -i --rm -p 8080:8080 quarkus/ui-super-heroes 18 | # 19 | ### 20 | FROM quay.io/quarkus/quarkus-micro-image:2.0 21 | WORKDIR /work/ 22 | RUN chown 1001 /work \ 23 | && chmod "g+rwX" /work \ 24 | && chown 1001:root /work 25 | COPY --chown=1001:root target/*-runner /work/application 26 | 27 | EXPOSE 8080 28 | USER 1001 29 | 30 | ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"] 31 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/main/java/io/quarkus/workshop/superheroes/ui/Config.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.ui; 2 | 3 | import com.fasterxml.jackson.databind.PropertyNamingStrategies; 4 | import com.fasterxml.jackson.databind.annotation.JsonNaming; 5 | import io.quarkus.runtime.annotations.RegisterForReflection; 6 | 7 | /* 8 | Why do we need to register this for reflection? Normally this would be automatic if 9 | we return it from a REST endpoint, but because we're handling our own 10 | object mapping, we need to do our own registering. 11 | */ 12 | @JsonNaming(PropertyNamingStrategies.UpperSnakeCaseStrategy.class) 13 | @RegisterForReflection 14 | public record Config(String apiBaseUrl, boolean calculateApiBaseUrl) { 15 | } 16 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/main/java/io/quarkus/workshop/superheroes/ui/EnvResource.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.ui; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import org.eclipse.microprofile.config.inject.ConfigProperty; 6 | 7 | import jakarta.inject.Inject; 8 | import jakarta.ws.rs.GET; 9 | import jakarta.ws.rs.Path; 10 | import jakarta.ws.rs.Produces; 11 | 12 | import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; 13 | 14 | /** 15 | * JAX-RS API endpoints to serve configuration to a front-end. 16 | */ 17 | @Path("/") 18 | public class EnvResource { 19 | 20 | @ConfigProperty(name = "api.base.url", defaultValue = "http://localhost:8082") 21 | String url; 22 | 23 | @ConfigProperty(name = "calculate.api.base.url", defaultValue = "false") 24 | boolean calculateApiBaseUrl; 25 | 26 | @Inject 27 | ObjectMapper objectMapper; 28 | 29 | @GET 30 | @Produces(APPLICATION_JSON) 31 | @Path("/env.js") 32 | public String getConfig() throws JsonProcessingException { 33 | Config config = new Config(url, 34 | calculateApiBaseUrl); 35 | // We could just return the Config object, but that would be json, and we want a 36 | // javascript snippet we can include with 15 | 16 | 17 | 18 | 19 |
20 | 21 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/main/webui/src/app/App.js: -------------------------------------------------------------------------------- 1 | import {FightList} from "./fight-list/FightList" 2 | import Fight from "./fight/Fight" 3 | import {useEffect, useState} from "react" 4 | import {getFights} from "./shared/api/fight-service" 5 | 6 | function App() { 7 | 8 | const [fights, setFights] = useState() 9 | 10 | const refreshFights = () => getFights().then(answer => setFights(answer)) 11 | 12 | useEffect(() => { 13 | refreshFights() 14 | }, [] 15 | ) 16 | 17 | return ( 18 | <> 19 |

20 | Welcome to Super Heroes Fight! 21 |

22 | 23 | 24 | 25 | ) 26 | } 27 | 28 | export default App 29 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/main/webui/src/app/fight-list/FightList.js: -------------------------------------------------------------------------------- 1 | export function FightList({fights}) { 2 | 3 | return ( 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {fights && fights.map(element => ( 17 | 18 | 19 | 20 | 21 | 22 | ))} 23 | 24 |
IdFight DateWinnerLoser
{element.id} {element.fightDate} {element.winnerName} {element.loserName}
25 | ) 26 | } 27 | 28 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/main/webui/src/app/shared/.gitignore: -------------------------------------------------------------------------------- 1 | wwwroot/*.js 2 | node_modules 3 | typings 4 | dist 5 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/main/webui/src/app/shared/git_push.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ 3 | # 4 | # Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update" 5 | 6 | git_user_id=$1 7 | git_repo_id=$2 8 | release_note=$3 9 | 10 | if [ "$git_user_id" = "" ]; then 11 | git_user_id="GIT_USER_ID" 12 | echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" 13 | fi 14 | 15 | if [ "$git_repo_id" = "" ]; then 16 | git_repo_id="GIT_REPO_ID" 17 | echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" 18 | fi 19 | 20 | if [ "$release_note" = "" ]; then 21 | release_note="Minor update" 22 | echo "[INFO] No command line input provided. Set \$release_note to $release_note" 23 | fi 24 | 25 | # Initialize the local directory as a Git repository 26 | git init 27 | 28 | # Adds the files in the local repository and stages them for commit. 29 | git add . 30 | 31 | # Commits the tracked changes and prepares them to be pushed to a remote repository. 32 | git commit -m "$release_note" 33 | 34 | # Sets the new remote 35 | git_remote=`git remote` 36 | if [ "$git_remote" = "" ]; then # git remote not defined 37 | 38 | if [ "$GIT_TOKEN" = "" ]; then 39 | echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." 40 | git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git 41 | else 42 | git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git 43 | fi 44 | 45 | fi 46 | 47 | git pull origin master 48 | 49 | # Pushes (Forces) the changes in the local repository up to the remote repository 50 | echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" 51 | git push origin master 2>&1 | grep -v 'To https' 52 | 53 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/main/webui/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkusio/quarkus-workshops/e2a008875c824b39ba25615d833461301b05547f/quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/main/webui/src/assets/.gitkeep -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/main/webui/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './styles.css'; 4 | import App from './app/App'; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById('root')); 7 | root.render( 8 | 9 | 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/test/java/io/quarkus/workshop/superheroes/ui/EnvResourceTests.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.ui; 2 | 3 | import io.quarkus.test.junit.QuarkusTest; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static io.restassured.RestAssured.get; 7 | import static jakarta.ws.rs.core.Response.Status.OK; 8 | import static org.hamcrest.Matchers.is; 9 | 10 | /** 11 | * Tests the resource layer ({@link EnvResource}). 12 | */ 13 | @QuarkusTest 14 | public class EnvResourceTests { 15 | 16 | /** 17 | * Checks that the react app would be able to do 18 | * 19 | * and get something sensible back 20 | */ 21 | @Test 22 | public void javascriptEndpoint() { 23 | get("/env.js") 24 | .then() 25 | .statusCode(OK.getStatusCode()) 26 | .body( 27 | is("window.APP_CONFIG={\"API_BASE_URL\":\"http://localhost:8082\"," + 28 | "\"CALCULATE_API_BASE_URL\":false}")); 29 | // This content is javascript, not json. Doing a simple equality check like this 30 | // is brittle, but we can update it to something more flexible if we start to see issues 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /quarkus-workshop-super-heroes/super-heroes/ui-super-heroes/src/test/java/io/quarkus/workshop/superheroes/ui/WebUITests.java: -------------------------------------------------------------------------------- 1 | package io.quarkus.workshop.superheroes.ui; 2 | 3 | import io.quarkiverse.quinoa.testing.QuinoaTestProfiles; 4 | import io.quarkus.test.junit.QuarkusTest; 5 | import io.quarkus.test.junit.TestProfile; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import java.util.regex.Pattern; 9 | 10 | import static io.restassured.RestAssured.get; 11 | import static io.restassured.http.ContentType.HTML; 12 | import static jakarta.ws.rs.core.Response.Status.OK; 13 | import static org.hamcrest.Matchers.matchesPattern; 14 | 15 | /** 16 | * Tests the served javascript application. 17 | * By default, the Web UI is not build/served in @QuarkusTest. The goal is to be able to test 18 | * your api without having to wait for the Web UI build. 19 | * The `Enable` test profile enables the Web UI (build and serve). 20 | */ 21 | @QuarkusTest 22 | @TestProfile(QuinoaTestProfiles.EnableAndRunTests.class) 23 | public class WebUITests { 24 | 25 | @Test 26 | public void webApplicationEndpoint() { 27 | get("/") 28 | .then() 29 | .statusCode(OK.getStatusCode()) 30 | .contentType(HTML) 31 | .body(matchesPattern(Pattern.compile(".*
.*", Pattern.DOTALL))); 32 | // We don't want to do full HTML parsing here, because that should 33 | // be in the javascript tests. Instead, just confirm that we 34 | // are successfully serving the HTML content on / 35 | } 36 | } 37 | --------------------------------------------------------------------------------