├── .github
├── dependabot.yml
└── workflows
│ └── main.yml
├── .gitignore
├── LICENSE
├── README.md
├── build.sh
├── demo-helidon.adoc
├── demo-micronaut.adoc
├── demo-quarkus.adoc
├── demo-spring-boot.adoc
├── demo.adoc
├── helidon
├── .dockerignore
├── .gitignore
├── .helidon
├── Dockerfile
├── Dockerfile.jlink
├── Dockerfile.native
├── README.md
├── app.yaml
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── okta
│ │ │ └── rest
│ │ │ ├── HelloApplication.java
│ │ │ ├── controller
│ │ │ └── HelloResource.java
│ │ │ └── package-info.java
│ └── resources
│ │ ├── META-INF
│ │ ├── beans.xml
│ │ ├── microprofile-config.properties
│ │ └── native-image
│ │ │ └── reflect-config.json
│ │ ├── application.yaml
│ │ └── logging.properties
│ └── test
│ └── resources
│ └── application.yaml
├── micronaut
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── README.md
├── aot-jar.properties
├── micronaut-cli.yml
├── mvnw
├── mvnw.bat
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── okta
│ │ │ └── rest
│ │ │ ├── Application.java
│ │ │ └── controller
│ │ │ └── HelloController.java
│ └── resources
│ │ ├── application.yml
│ │ └── logback.xml
│ └── test
│ └── java
│ └── com
│ └── okta
│ └── rest
│ └── AppTest.java
├── quarkus
├── .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
│ │ └── com
│ │ │ └── okta
│ │ │ └── rest
│ │ │ └── quarkus
│ │ │ └── HelloResource.java
│ └── resources
│ │ ├── META-INF
│ │ └── resources
│ │ │ └── index.html
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── okta
│ └── rest
│ └── quarkus
│ ├── HelloResourceIT.java
│ └── HelloResourceTest.java
└── spring-boot
├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── HELP.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── okta
│ │ └── rest
│ │ ├── Application.java
│ │ └── controller
│ │ └── HelloController.java
└── resources
│ └── application.properties
└── test
└── java
└── com
└── okta
└── rest
└── ApplicationTests.java
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | directory: "/"
5 | schedule:
6 | interval: "weekly"
7 | - package-ecosystem: "maven"
8 | directory: "/helidon"
9 | schedule:
10 | interval: "weekly"
11 | - package-ecosystem: "maven"
12 | directory: "/micronaut"
13 | schedule:
14 | interval: "weekly"
15 | - package-ecosystem: "maven"
16 | directory: "/quarkus"
17 | schedule:
18 | interval: "weekly"
19 | - package-ecosystem: "maven"
20 | directory: "/spring-boot"
21 | schedule:
22 | interval: "weekly"
23 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Maven CI
2 |
3 | on:
4 | push:
5 | branches: # build any changes to main
6 | - main
7 | pull_request: # build all PRs
8 |
9 | jobs:
10 | build:
11 | strategy:
12 | matrix:
13 | framework: [helidon, micronaut, quarkus, spring-boot]
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v3
17 | - name: Set up JDK 17
18 | uses: actions/setup-java@v3
19 | with:
20 | java-version: '17'
21 | distribution: 'temurin'
22 | cache: maven
23 | - name: Build with Maven
24 | run: mvn -ntp -q package -f ${{ matrix.framework }}/pom.xml
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### IntelliJ IDEA ###
2 | .idea
3 | *.iws
4 | *.iml
5 | *.ipr
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2021-Present Okta, Inc.
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Native Java Examples: Micronaut, Quarkus, Spring Boot, and Helidon
2 |
3 | This repository contains example OAuth 2.0 resource servers built with Micronaut, Quarkus, and Spring Boot. If you'd like to see how they were built, please read [Build Native Java Apps with Micronaut, Quarkus, and Spring Boot][blog].
4 |
5 | This project also contains a Helidon example. You can read about how it was built and how it compares in [Build REST APIs and Native Java Apps with Helidon][blog-helidon].
6 |
7 | **Prerequisites:** [Java 17 with GraalVM](https://sdkman.io/), [HTTPie](https://httpie.io/), and [Docker](https://docs.docker.com/engine/install/) (optional).
8 |
9 | * [Getting Started](#getting-started)
10 | * [Links](#links)
11 | * [Help](#help)
12 | * [License](#license)
13 |
14 | ## Getting Started
15 |
16 | First, clone this repository:
17 |
18 | ```bash
19 | git clone https://github.com/oktadev/native-java-examples.git
20 | ```
21 |
22 | You will need a JDK with GraalVM and its native-image compiler. Using [SDKMAN](https://sdkman.io), run the following command and set it as the default:
23 |
24 | ```bash
25 | sdk install java 22.3.r17-grl
26 | ```
27 |
28 | Next, you'll need a free Okta developer account. Install the [Okta CLI](https://cli.okta.com/) and run `okta register` to sign up for a new account. If you already have an account, run `okta login`. Then, run `okta apps create`. Select the default app name, or change it as you see fit. Choose **Single-Page App** and press **Enter**.
29 |
30 | Use `https://oidcdebugger.com/debug` for the Redirect URI and accept the default Logout Redirect URI of `https://oidcdebugger.com/`.
31 |
32 | Take note of the `clientId` and `issuer` values. You'll need those to get an access token and to configure each framework for JWT authentication.
33 |
34 | Change the following files for each framework to match your Okta domain:
35 |
36 | - Micronaut: `micronaut/src/main/resources/application.yml`
37 | - Quarkus: `quarkus/src/main/resources/application.properties`
38 | - Spring Boot: `spring-boot/src/main/resources/application.properties`
39 | - Helidon: `helidon/src/main/resources/META-INF/microprofile-config.properties`
40 |
41 | You can start each app using Maven. Note that you will only be able to start one at a time since they all run on port 8080.
42 |
43 | - Micronaut: `./mvnw mn:run`
44 | - Quarkus: `./mvnw quarkus:dev`
45 | - Spring Boot: `./mvnw spring-boot:run`
46 | - Helidon: `mvn package && java -jar target/helidon.jar`
47 |
48 | Then, you can test them with an access token and HTTPie.
49 |
50 | You can generate an access token using [OpenID Connect Debugger](https://oidcdebugger.com/). First, you must configure your application on Okta to use OpenID Connect's implicit flow.
51 |
52 | Run `okta login` and open the resulting URL in your browser. Go to the **Applications** section and select the application you created with the CLI. Edit its General Settings and add **Implicit (Hybrid)** as an allowed grant type, with access token enabled. Click **Save** and copy the client ID for the next step.
53 |
54 | Now, navigate to the [OpenID Connect Debugger website](https://oidcdebugger.com/). Fill in your client ID, and use `https://{yourOktaDomain}/oauth2/default/v1/authorize` for the Authorize URI. The state field must be filled but can contain any characters. Select **token** for the response type. Click **Send Request** to continue.
55 |
56 | Once you have an access token, set it as a `TOKEN` environment variable in a terminal window.
57 |
58 | ```bash
59 | TOKEN=eyJraWQiOiJYa2pXdjMzTDRBYU1ZSzNGM...
60 | ```
61 |
62 | Use HTTPie to pass the JWT in as a bearer token in the `Authorization` header.
63 |
64 | ```bash
65 | http :8080/hello Authorization:"Bearer $TOKEN"
66 | ```
67 |
68 | You should see your email address printed to your terminal.
69 |
70 | You can also build and run each example as a native app.
71 |
72 | - Micronaut: `./mvnw package -Dpackaging=native-image`
73 | - Quarkus: `./mvnw package -Pnative`
74 | - Spring Boot: `./mvnw package -Pnative` (if you'd rather use Docker: `./mvnw spring-boot:build-image`)
75 | - Helidon: `mvn package -Pnative-image`
76 |
77 | Then, start each app as a native executable.
78 |
79 | - Micronaut: `./target/app`
80 | - Quarkus: `./target/quarkus-1.0.0-SNAPSHOT-runner`
81 | - Spring Boot: `./target/demo` (if Docker: `docker run -p 8080:8080 demo:0.0.1-SNAPSHOT`)
82 | - Helidon: `./target/helidon`
83 |
84 | Please read [Build Native Java Apps with Micronaut, Quarkus, and Spring Boot][blog] for performance numbers and analysis. To see how Helidon compares, see [Build REST APIs and Native Java Apps with Helidon][blog-helidon].
85 |
86 | ## Links
87 |
88 | This example uses the following open source libraries:
89 |
90 | * [Micronaut](https://micronaut.io)
91 | * [Quarkus](https://quarkus.io)
92 | * [Spring Boot](https://spring.io/projects/spring-boot)
93 | * [Helidon](https://helidon.io)
94 |
95 | ## Help
96 |
97 | Please post any questions as comments on [this example's blog post][blog], or on the [Okta Developer Forums](https://devforum.okta.com/).
98 |
99 | ## License
100 |
101 | Apache 2.0, see [LICENSE](LICENSE).
102 |
103 | [blog]: https://developer.okta.com/blog/2021/06/18/native-java-framework-comparison
104 | [blog-helidon]: https://developer.okta.com/blog/2022/01/06/native-java-helidon
105 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # exit when any command fails
4 | set -e
5 |
6 | rm -rf {helidon,micronaut,quarkus,spring-boot}/target
7 |
8 | cd micronaut && ./mvnw package -Dpackaging=native-image
9 |
10 | cd ../quarkus && ./mvnw package -Pnative
11 |
12 | cd ../spring-boot && ./mvnw native:compile -Pnative
13 |
14 | cd ../helidon && mvn package -Pnative-image
15 |
--------------------------------------------------------------------------------
/demo-helidon.adoc:
--------------------------------------------------------------------------------
1 | :experimental:
2 | :commandkey: ⌘
3 | :toc: macro
4 | :source-highlighter: highlight.js
5 |
6 | = Build a Secure Java REST API with Helidon
7 |
8 | In this demo, I'll show how to create a secure REST API and native image with Helidon. You'll see how to run a secure, OAuth 2.0-protected, Java REST API that allows JWT authentication. Then, I'll compare its performance with Micronaut, Quarkus, and Spring Boot.
9 |
10 | _Check this video's description below for links to its blog post, comments, demo script, and code example._
11 |
12 | **Prerequisites:**
13 |
14 | - https://sdkman.io/[SDKMAN] (for Java 17 with GraalVM)
15 | - https://httpie.io/[HTTPie] (a better version of cURL)
16 | - An https://developer.okta.com[Okta Developer] Account (or the https://cli.okta.com/[Okta CLI])
17 |
18 | TIP: The brackets at the end of some steps indicate the IntelliJ Live Templates to use. You can find the template definitions at https://github.com/mraible/idea-live-templates[mraible/idea-live-templates].
19 |
20 | toc::[]
21 |
22 | == Install a JDK with GraalVM
23 |
24 | Use SDKMAN to install Java 17 with GraalVM
25 |
26 | sdk install java 22.3.r17-grl
27 |
28 | == Generate an OAuth 2.0 Access Token
29 |
30 | . Install the https://cli.okta.com/[Okta CLI] and run `okta register` to sign up for a new account. If you already have an account, run `okta login`.
31 |
32 | . Run `okta apps create spa`. Set `oidcdebugger` as an app name and press **Enter**.
33 |
34 | . Use `\https://oidcdebugger.com/debug` for the Redirect URI and set the Logout Redirect URI to `\https://oidcdebugger.com`.
35 |
36 | . Navigate to the https://oidcdebugger.com/[OpenID Connect Debugger website].
37 |
38 | .. Fill in your client ID
39 | .. Use `\https://{yourOktaDomain}/oauth2/default/v1/authorize` for the Authorize URI
40 | .. Select **code** for the response type and **Use PKCE**
41 | .. Click **Send Request** to continue
42 |
43 | . Set the access token as a `TOKEN` environment variable in a terminal window.
44 |
45 | TOKEN=eyJraWQiOiJYa2pXdjMzTDRBYU1ZSzNGM...
46 |
47 | == Build a Java REST API with Helidon
48 |
49 | . Create a Helidon app with OAuth 2.0 support:
50 | +
51 | [source,shell]
52 | ----
53 | mvn -U archetype:generate -DinteractiveMode=false \
54 | -DarchetypeGroupId=io.helidon.archetypes \
55 | -DarchetypeArtifactId=helidon-quickstart-mp \
56 | -DarchetypeVersion=3.0.2 \
57 | -DgroupId=com.okta.rest \
58 | -DartifactId=helidon \
59 | -Dpackage=com.okta.rest
60 | ----
61 | +
62 | TIP: You can also install the https://helidon.io/docs/latest/#/about/cli[Helidon's CLI] and run `helidon init`.
63 |
64 | . Add MicroProfile JWT support in `pom.xml`:
65 | +
66 | [source,xml]
67 | ----
68 |
69 | io.helidon.microprofile.jwt
70 | helidon-microprofile-jwt-auth
71 |
72 | ----
73 |
74 | . Add a `HelloResource` class that returns the user's information: [`h-hello`]
75 | +
76 | [source,java]
77 | ----
78 | package com.okta.rest.controller;
79 |
80 | import io.helidon.security.Principal;
81 | import io.helidon.security.annotations.Authenticated;
82 |
83 | import jakarta.ws.rs.GET;
84 | import jakarta.ws.rs.Path;
85 | import jakarta.ws.rs.core.Context;
86 |
87 | @Path("/hello")
88 | public class HelloResource {
89 |
90 | @Authenticated
91 | @GET
92 | public String hello(@Context SecurityContext context) {
93 | return "Hello, " + context.userName() + "!";
94 | }
95 | }
96 | ----
97 |
98 | . Add a `HelloApplication` class in `src/main/java/com/okta/rest` to register your resource and configure JWT authentication: [`h-app`]
99 | +
100 | [source,java]
101 | ----
102 | package com.okta.rest;
103 |
104 | import com.okta.rest.controller.HelloResource;
105 | import org.eclipse.microprofile.auth.LoginConfig;
106 |
107 | import jakarta.enterprise.context.ApplicationScoped;
108 | import jakarta.ws.rs.core.Application;
109 | import java.util.Set;
110 |
111 | @LoginConfig(authMethod = "MP-JWT")
112 | @ApplicationScoped
113 | public class HelloApplication extends Application {
114 |
115 | @Override
116 | public Set> getClasses() {
117 | return Set.of(HelloResource.class);
118 | }
119 | }
120 | ----
121 |
122 | . Add your Okta endpoints to `src/main/resources/META-INF/microprofile-config.properties`.
123 | +
124 | [source,properties]
125 | ----
126 | mp.jwt.verify.issuer=https://{yourOktaDomain}/oauth2/default
127 | mp.jwt.verify.publickey.location=${mp.jwt.verify.issuer}/v1/keys
128 | ----
129 |
130 | === Run and Test Your Helidon REST API with HTTPie
131 |
132 | . Start your app from your IDE or using a terminal:
133 |
134 | mvn package && java -jar ./target/helidon.jar
135 |
136 | . Test your API with an access token.
137 |
138 | http :8080/hello Authorization:"Bearer $TOKEN"
139 |
140 | === Build a native Helidon app with GraalVM
141 |
142 | . Compile your Helidon app into a native executable using the `native-image` profile:
143 |
144 | mvn package -Pnative-image
145 |
146 | . Start your Helidon app:
147 |
148 | ./target/helidon
149 |
150 | . Test your API with an access token.
151 |
152 | http :8080/hello Authorization:"Bearer $TOKEN"
153 |
154 | == Startup Time Comparison
155 |
156 | . Run each image three times before recording the numbers, then each command five times
157 |
158 | . Write each time down, add them up, and divide by five for the average. For example:
159 | +
160 | ----
161 | Helidon: (45 + 44 + 45 + 39 + 43) / 5 = 43.2
162 | Micronaut: (17 + 19 + 19 + 20 + 15) / 5 = 18
163 | Quarkus: (25 + 18 + 20 + 19 + 21) / 5 = 20.6
164 | Spring Boot: (39 + 40 + 38 + 37 + 41) / 5 = 39
165 | ----
166 |
167 | .Native Java startup times in milliseconds
168 | |===
169 | |Framework | Command executed | Milliseconds to start
170 |
171 | |Helidon | `./helidon/target/helidon` | 43.2
172 | |Micronaut | `./micronaut/target/app` | 18
173 | |Quarkus | `./quarkus/target/quarkus-1.0.0-SNAPSHOT-runner` | 20.6
174 | |Spring Boot | `./spring-boot/target/demo` | 39
175 | |===
176 |
177 | == Memory Usage Comparison
178 |
179 | Test the memory usage in MB of each app using the command below. Make sure to send an HTTP request to each one before measuring.
180 |
181 | [source,shell]
182 | ----
183 | ps -o pid,rss,command | grep --color | awk '{$2=int($2/1024)"M";}{ print;}'
184 | ----
185 |
186 | Substitute `` as follows:
187 |
188 | .Native Java memory used in megabytes
189 | |===
190 | |Framework | Executable | Megabytes before request | Megabytes after request| Megabytes after 5 requests
191 |
192 | |Helidon | `helidon` | 79 | 97 | 131
193 | |Micronaut | `app` | 43 | 58 | 69
194 | |Quarkus | `quarkus` | 37 | 48 | 50
195 | |Spring Boot | `demo` | 74 | 98 | 99
196 | |===
197 |
198 | IMPORTANT: If you disagree with these numbers and think X framework should be faster, I encourage you to clone https://github.com/oktadev/native-java-examples[the repo] and run these tests yourself. If you get faster startup times for Helidon, do you get faster startup times for Micronaut and Quarkus too?
199 |
200 | == Secure Native Java with Helidon FTW!
201 |
202 | ⚡️ Create a secure REST API with Helidon: `okta start helidon`
203 |
204 | 🚀 Find this example's code on GitHub: https://github.com/oktadev/native-java-examples/tree/main/helidon[@oktadev/native-java-examples/helidon]
205 |
206 | 👀 Read the blog post: https://developer.okta.com/blog/2022/01/06/native-java-helidon[Build REST APIs and Native Java Apps with Helidon]
207 |
--------------------------------------------------------------------------------
/demo-micronaut.adoc:
--------------------------------------------------------------------------------
1 | :experimental:
2 | :commandkey: ⌘
3 | :toc: macro
4 | :source-highlighter: highlight.js
5 |
6 | = Build a Secure Java REST API with Micronaut
7 |
8 | In this demo, I'll show how to create a secure REST API and native image with Micronaut. You'll see how to run a secure, OAuth 2.0-protected, Java REST API that allows JWT authentication. Then, I'll compare its performance with Quarkus, Spring Boot, and Helidon.
9 |
10 | _Check this video's description below for links to its blog post, comments, demo script, and code example._
11 |
12 | **Prerequisites:**
13 |
14 | - https://sdkman.io/[SDKMAN] (for Java 17 with GraalVM)
15 | - https://httpie.io/[HTTPie] (a better version of cURL)
16 | - An https://developer.okta.com[Okta Developer] Account (or the https://cli.okta.com/[Okta CLI])
17 |
18 | TIP: The brackets at the end of some steps indicate the IntelliJ Live Templates to use. You can find the template definitions at https://github.com/mraible/idea-live-templates[mraible/idea-live-templates].
19 |
20 | toc::[]
21 |
22 | == Install a JDK with GraalVM
23 |
24 | Use SDKMAN to install Java 17 with GraalVM
25 |
26 | sdk install java 22.3.r17-grl
27 |
28 | == Generate an OAuth 2.0 Access Token
29 |
30 | . Install the https://cli.okta.com/[Okta CLI] and run `okta register` to sign up for a new account. If you already have an account, run `okta login`.
31 |
32 | . Run `okta apps create spa`. Set `oidcdebugger` as an app name and press **Enter**.
33 |
34 | . Use `\https://oidcdebugger.com/debug` for the Redirect URI and set the Logout Redirect URI to `\https://oidcdebugger.com`.
35 |
36 | . Navigate to the https://oidcdebugger.com/[OpenID Connect Debugger website].
37 |
38 | .. Fill in your client ID
39 | .. Use `\https://{yourOktaDomain}/oauth2/default/v1/authorize` for the Authorize URI
40 | .. Select **code** for the response type and **Use PKCE**
41 | .. Click **Send Request** to continue
42 |
43 | . Set the access token as a `TOKEN` environment variable in a terminal window.
44 |
45 | TOKEN=eyJraWQiOiJYa2pXdjMzTDRBYU1ZSzNGM...
46 |
47 | == Make a Micronaut Java REST API
48 |
49 | . Use SDKMAN to install Micronaut's CLI and create an app:
50 | +
51 | [source,shell]
52 | ----
53 | sdk install micronaut
54 | mn create-app com.okta.rest.app --build maven -f security-jwt -f micronaut-aot
55 | mv app micronaut
56 | ----
57 |
58 | . Create `controller/HelloController.java`: [`mn-hello`]
59 | +
60 | [source,java]
61 | ----
62 | package com.okta.rest.controller;
63 |
64 | import io.micronaut.http.MediaType;
65 | import io.micronaut.http.annotation.Controller;
66 | import io.micronaut.http.annotation.Get;
67 | import io.micronaut.http.annotation.Produces;
68 | import io.micronaut.security.annotation.Secured;
69 | import io.micronaut.security.rules.SecurityRule;
70 |
71 | import java.security.Principal;
72 |
73 | @Controller("/hello")
74 | public class HelloController {
75 |
76 | @Get
77 | @Secured(SecurityRule.IS_AUTHENTICATED)
78 | @Produces(MediaType.TEXT_PLAIN)
79 | public String hello(Principal principal) {
80 | return "Hello, " + principal.getName() + "!";
81 | }
82 |
83 | }
84 | ----
85 |
86 | . Enable and configure JWT security in `src/main/resources/application.yml`: [`mn-security-config`]
87 | +
88 | [source,yaml]
89 | ----
90 | micronaut:
91 | ...
92 | security:
93 | enabled: true
94 | token:
95 | jwt:
96 | enabled: true
97 | claims-validators:
98 | issuer: https://{yourOktaDomain}/oauth2/default
99 | signatures:
100 | jwks:
101 | okta:
102 | url: https://{yourOktaDomain}/oauth2/default/v1/keys
103 | ----
104 |
105 | === Run and Test Your Micronaut REST API with HTTPie
106 |
107 | . Start your app:
108 |
109 | ./mvnw mn:run
110 |
111 | . Use HTTPie to pass the JWT in as a bearer token in the `Authorization` header:
112 |
113 | http :8080/hello Authorization:"Bearer $TOKEN"
114 | +
115 | You should get a 200 response with your email in it.
116 |
117 | === Build a Native Micronaut App
118 |
119 | . Compile your Micronaut app into a native binary:
120 |
121 | ./mvnw package -Dpackaging=native-image
122 |
123 | . Start your Micronaut app:
124 |
125 | ./target/app
126 |
127 | . Test it with HTTPie and an access token. You may have to generate a new JWT with oidcdebugger.com if yours has expired.
128 |
129 | http :8080/hello Authorization:"Bearer $TOKEN"
130 |
131 | == Startup Time Comparison
132 |
133 | . Run each image three times before recording the numbers, then each command five times
134 |
135 | . Write each time down, add them up, and divide by five for the average. For example:
136 | +
137 | ----
138 | Micronaut: (17 + 19 + 19 + 20 + 15) / 5 = 18
139 | Quarkus: (25 + 18 + 20 + 19 + 21) / 5 = 20.6
140 | Spring Boot: (39 + 40 + 38 + 37 + 41) / 5 = 39
141 | Helidon: (45 + 44 + 45 + 39 + 43) / 5 = 43.2
142 | ----
143 |
144 | .Native Java startup times in milliseconds
145 | |===
146 | |Framework | Command executed | Milliseconds to start
147 |
148 | |Micronaut | `./micronaut/target/app` | 18
149 | |Quarkus | `./quarkus/target/quarkus-1.0.0-SNAPSHOT-runner` | 20.6
150 | |Spring Boot | `./spring-boot/target/demo` | 39
151 | |Helidon | `./helidon/target/helidon` | 43.2
152 | |===
153 |
154 | == Memory Usage Comparison
155 |
156 | Test the memory usage in MB of each app using the command below. Make sure to send an HTTP request to each one before measuring.
157 |
158 | [source,shell]
159 | ----
160 | ps -o pid,rss,command | grep --color | awk '{$2=int($2/1024)"M";}{ print;}'
161 | ----
162 |
163 | Substitute `` as follows:
164 |
165 | .Native Java memory used in megabytes
166 | |===
167 | |Framework | Executable | Megabytes before request | Megabytes after request| Megabytes after 5 requests
168 |
169 | |Micronaut | `app` | 43 | 58 | 69
170 | |Quarkus | `quarkus` | 37 | 48 | 50
171 | |Spring Boot | `demo` | 74 | 98 | 99
172 | |Helidon | `helidon` | 79 | 97 | 131
173 | |===
174 |
175 | IMPORTANT: If you disagree with these numbers and think X framework should be faster, I encourage you to clone https://github.com/oktadev/native-java-examples[the repo] and run these tests yourself. If you get faster startup times for Micronaut, do you get faster startup times for Helidon, Quarkus, and Spring Boot too?
176 |
177 | == Secure Native Java with Micronaut FTW!
178 |
179 | ⚡️ Create a secure REST API with Micronaut: `okta start micronaut`
180 |
181 | 🚀 Find this example's code on GitHub: https://github.com/oktadev/native-java-examples/tree/main/micronaut[@oktadev/native-java-examples/micronaut]
182 |
183 | 👀 Read the blog post: https://developer.okta.com/blog/2021/06/18/native-java-framework-comparison[Build Native Java Apps with Micronaut, Quarkus, and Spring Boot]
184 |
--------------------------------------------------------------------------------
/demo-quarkus.adoc:
--------------------------------------------------------------------------------
1 | :experimental:
2 | :commandkey: ⌘
3 | :toc: macro
4 | :source-highlighter: highlight.js
5 |
6 | = Build a Secure Java REST API with Quarkus
7 |
8 | In this demo, I'll show how to create a secure REST API and native image with Quarkus. You'll see how to run a secure, OAuth 2.0-protected, Java REST API that allows JWT authentication. Then, I'll compare its performance with Micronaut, Spring Boot, and Helidon.
9 |
10 | _Check this video's description below for links to its blog post, comments, demo script, and code example._
11 |
12 | **Prerequisites:**
13 |
14 | - https://sdkman.io/[SDKMAN] (for Java 17 with GraalVM)
15 | - https://httpie.io/[HTTPie] (a better version of cURL)
16 | - An https://developer.okta.com[Okta Developer] Account (or the https://cli.okta.com/[Okta CLI])
17 |
18 | TIP: The brackets at the end of some steps indicate the IntelliJ Live Templates to use. You can find the template definitions at https://github.com/mraible/idea-live-templates[mraible/idea-live-templates].
19 |
20 | toc::[]
21 |
22 | == Install a JDK with GraalVM
23 |
24 | Use SDKMAN to install Java 17 with GraalVM
25 |
26 | sdk install java 22.3.r17-grl
27 |
28 | == Generate an OAuth 2.0 Access Token
29 |
30 | . Install the https://cli.okta.com/[Okta CLI] and run `okta register` to sign up for a new account. If you already have an account, run `okta login`.
31 |
32 | . Run `okta apps create spa`. Set `oidcdebugger` as an app name and press **Enter**.
33 |
34 | . Use `\https://oidcdebugger.com/debug` for the Redirect URI and set the Logout Redirect URI to `\https://oidcdebugger.com`.
35 |
36 | . Navigate to the https://oidcdebugger.com/[OpenID Connect Debugger website].
37 |
38 | .. Fill in your client ID
39 | .. Use `\https://{yourOktaDomain}/oauth2/default/v1/authorize` for the Authorize URI
40 | .. Select **code** for the response type and **Use PKCE**
41 | .. Click **Send Request** to continue
42 |
43 | . Set the access token as a `TOKEN` environment variable in a terminal window.
44 |
45 | TOKEN=eyJraWQiOiJYa2pXdjMzTDRBYU1ZSzNGM...
46 |
47 | == Create a Quarkus Java REST API
48 |
49 | . Use Maven to generate a new Quarkus app with JWT support:
50 | +
51 | [source,shell]
52 | ----
53 | mvn io.quarkus:quarkus-maven-plugin:2.13.3.Final:create \
54 | -DprojectGroupId=com.okta.rest \
55 | -DprojectArtifactId=quarkus \
56 | -DclassName="com.okta.rest.quarkus.HelloResource" \
57 | -Dpath="/hello" \
58 | -Dextensions="smallrye-jwt,resteasy-reactive"
59 | ----
60 |
61 | . Edit `src/java/com/okta/rest/quarkus/HelloResource.java` and add user information to the `hello()` method: [`qk-hello`]
62 | +
63 | [source,java]
64 | ----
65 | package com.okta.rest.quarkus;
66 |
67 | import io.quarkus.security.Authenticated;
68 |
69 | import javax.ws.rs.GET;
70 | import javax.ws.rs.Path;
71 | import javax.ws.rs.Produces;
72 | import javax.ws.rs.core.Context;
73 | import javax.ws.rs.core.MediaType;
74 | import javax.ws.rs.core.SecurityContext;
75 | import java.security.Principal;
76 |
77 | @Path("/hello")
78 | public class HelloResource {
79 |
80 | @GET
81 | @Authenticated
82 | @Produces(MediaType.TEXT_PLAIN)
83 | public String hello(@Context SecurityContext context) {
84 | Principal userPrincipal = context.getUserPrincipal();
85 | return "Hello, " + userPrincipal.getName() + "!";
86 | }
87 | }
88 | ----
89 |
90 | . Add your Okta endpoints to `src/main/resources/application.properties`: [`qk-properties`]
91 | +
92 | [source,properties]
93 | ----
94 | mp.jwt.verify.issuer=https://{yourOktaDomain}/oauth2/default
95 | mp.jwt.verify.publickey.location=${mp.jwt.verify.issuer}/v1/keys
96 | ----
97 |
98 | . Modify the `HelloResourceTest` to expect a 401 instead of a 200:
99 | +
100 | [source,java]
101 | ----
102 | package com.okta.rest.quarkus;
103 |
104 | import io.quarkus.test.junit.QuarkusTest;
105 | import org.junit.jupiter.api.Test;
106 |
107 | import static io.restassured.RestAssured.given;
108 |
109 | @QuarkusTest
110 | public class HelloResourceTest {
111 |
112 | @Test
113 | public void testHelloEndpoint() {
114 | given()
115 | .when().get("/hello")
116 | .then()
117 | .statusCode(401);
118 | }
119 |
120 | }
121 | ----
122 |
123 | === Run and Test Your Quarkus REST API with HTTPie
124 |
125 | . Run your Quarkus app:
126 |
127 | ./mvnw quarkus:dev
128 |
129 | . Test it from another terminal:
130 |
131 | http :8080/hello
132 |
133 | . Test with access token:
134 |
135 | http :8080/hello Authorization:"Bearer $TOKEN"
136 |
137 | === Build a Native Quarkus App
138 |
139 | . Compile your Quarkus app into a native binary:
140 |
141 | ./mvnw package -Pnative
142 |
143 | . Start your Quarkus app:
144 |
145 | ./target/quarkus-1.0.0-SNAPSHOT-runner
146 |
147 | . Test it with HTTPie and an access token:
148 |
149 | http :8080/hello Authorization:"Bearer $TOKEN"
150 |
151 | == Startup Time Comparison
152 |
153 | . Run each image three times before recording the numbers, then each command five times
154 |
155 | . Write each time down, add them up, and divide by five for the average. For example:
156 | +
157 | ----
158 | Quarkus: (25 + 18 + 20 + 19 + 21) / 5 = 20.6
159 | Micronaut: (17 + 19 + 19 + 20 + 15) / 5 = 18
160 | Spring Boot: (39 + 40 + 38 + 37 + 41) / 5 = 39
161 | Helidon: (45 + 44 + 45 + 39 + 43) / 5 = 43.2
162 | ----
163 |
164 | .Native Java startup times in milliseconds
165 | |===
166 | |Framework | Command executed | Milliseconds to start
167 |
168 | |Quarkus | `./quarkus/target/quarkus-1.0.0-SNAPSHOT-runner` | 20.6
169 | |Micronaut | `./micronaut/target/app` | 18
170 | |Spring Boot | `./spring-boot/target/demo` | 39
171 | |Helidon | `./helidon/target/helidon` | 43.2
172 | |===
173 |
174 | == Memory Usage Comparison
175 |
176 | Test the memory usage in MB of each app using the command below. Make sure to send an HTTP request to each one before measuring.
177 |
178 | [source,shell]
179 | ----
180 | ps -o pid,rss,command | grep --color | awk '{$2=int($2/1024)"M";}{ print;}'
181 | ----
182 |
183 | Substitute `` as follows:
184 |
185 | .Native Java memory used in megabytes
186 | |===
187 | |Framework | Executable | Megabytes before request | Megabytes after request| Megabytes after 5 requests
188 |
189 | |Quarkus | `quarkus` | 37 | 48 | 50
190 | |Micronaut | `app` | 43 | 58 | 69
191 | |Spring Boot | `demo` | 74 | 98 | 99
192 | |Helidon | `helidon` | 79 | 97 | 131
193 | |===
194 |
195 | IMPORTANT: If you disagree with these numbers and think X framework should be faster, I encourage you to clone https://github.com/oktadev/native-java-examples[the repo] and run these tests yourself. If you get faster startup times for Quarkus, do you get faster startup times for Helidon, Micronaut, and Spring Boot too?
196 |
197 | == Secure Native Java with Quarkus FTW!
198 |
199 | ⚡️ Create a secure REST API with Quarkus: `okta start quarkus`
200 |
201 | 🚀 Find this example's code on GitHub: https://github.com/oktadev/native-java-examples/tree/main/quarkus[@oktadev/native-java-examples/quarkus]
202 |
203 | 👀 Read the blog post: https://developer.okta.com/blog/2021/06/18/native-java-framework-comparison[Build Native Java Apps with Micronaut, Quarkus, and Spring Boot]
204 |
--------------------------------------------------------------------------------
/demo-spring-boot.adoc:
--------------------------------------------------------------------------------
1 | :experimental:
2 | :commandkey: ⌘
3 | :toc: macro
4 | :source-highlighter: highlight.js
5 |
6 | = Build a Secure Java REST API with Spring Boot
7 |
8 | In this demo, I'll show how to create a secure REST API and native image with Spring Boot. You'll see how to run a secure, OAuth 2.0-protected, Java REST API that allows JWT authentication. Then, I'll compare its performance with Micronaut, Quarkus, and Helidon.
9 |
10 | _Check this video's description below for links to its blog post, comments, demo script, and code example._
11 |
12 | **Prerequisites:**
13 |
14 | - https://sdkman.io/[SDKMAN] (for Java 17 with GraalVM)
15 | - https://httpie.io/[HTTPie] (a better version of cURL)
16 | - An https://developer.okta.com[Okta Developer] Account (or the https://cli.okta.com/[Okta CLI])
17 |
18 | TIP: The brackets at the end of some steps indicate the IntelliJ Live Templates to use. You can find the template definitions at https://github.com/mraible/idea-live-templates[mraible/idea-live-templates].
19 |
20 | toc::[]
21 |
22 | == Install a JDK with GraalVM
23 |
24 | Use SDKMAN to install Java 17 with GraalVM
25 |
26 | sdk install java 22.3.r17-grl
27 |
28 | == Generate an OAuth 2.0 Access Token
29 |
30 | . Install the https://cli.okta.com/[Okta CLI] and run `okta register` to sign up for a new account. If you already have an account, run `okta login`.
31 |
32 | . Run `okta apps create spa`. Set `oidcdebugger` as an app name and press **Enter**.
33 |
34 | . Use `\https://oidcdebugger.com/debug` for the Redirect URI and set the Logout Redirect URI to `\https://oidcdebugger.com`.
35 |
36 | . Navigate to the https://oidcdebugger.com/[OpenID Connect Debugger website].
37 |
38 | .. Fill in your client ID
39 | .. Use `\https://{yourOktaDomain}/oauth2/default/v1/authorize` for the Authorize URI
40 | .. Select **code** for the response type and **Use PKCE**
41 | .. Click **Send Request** to continue
42 |
43 | . Set the access token as a `TOKEN` environment variable in a terminal window.
44 |
45 | TOKEN=eyJraWQiOiJYa2pXdjMzTDRBYU1ZSzNGM...
46 |
47 | == Start a Spring Boot Java REST API
48 |
49 | . Create a Spring Boot app with OAuth 2.0 support:
50 | +
51 | [source,shell]
52 | ----
53 | https start.spring.io/starter.zip \
54 | bootVersion==3.0.0-RC1 \
55 | dependencies==web,oauth2-resource-server,native \
56 | packageName==com.okta.rest \
57 | name==spring-boot \
58 | type==maven-project \
59 | baseDir==spring-boot | tar -xzvf -
60 | ----
61 |
62 | . Add a `HelloController` class that returns the user's information: [`sb-hello`]
63 | +
64 | [source,java]
65 | ----
66 | package com.okta.rest.controller;
67 |
68 | import org.springframework.web.bind.annotation.GetMapping;
69 | import org.springframework.web.bind.annotation.RestController;
70 |
71 | import java.security.Principal;
72 |
73 | @RestController
74 | public class HelloController {
75 |
76 | @GetMapping("/hello")
77 | public String hello(Principal principal) {
78 | return "Hello, " + principal.getName() + "!";
79 | }
80 | }
81 | ----
82 |
83 | . Configure the app to be an OAuth 2.0 resource server by adding the issuer to `application.properties`.
84 | +
85 | [source,properties]
86 | ----
87 | spring.security.oauth2.resourceserver.jwt.issuer-uri=https://{yourOktaDomain}/oauth2/default
88 | ----
89 |
90 | === Run and Test Your Spring Boot REST API with HTTPie
91 |
92 | . Start your app from your IDE or using a terminal:
93 |
94 | ./mvnw spring-boot:run
95 |
96 | . Test your API with an access token.
97 |
98 | http :8080/hello Authorization:"Bearer $TOKEN"
99 |
100 | === Build a Native Spring Boot App
101 |
102 | . Compile your Spring Boot app into a native executable using the `native` profile:
103 |
104 | ./mvnw native:compile -Pnative
105 | +
106 | TIP: To build a native app and a Docker container, use the Spring Boot Maven plugin and `./mvnw spring-boot:build-image -Pnative`.
107 |
108 | . Start your Spring Boot app:
109 |
110 | ./target/demo
111 |
112 | . Test your API with an access token.
113 |
114 | http :8080/hello Authorization:"Bearer $TOKEN"
115 |
116 | == Startup Time Comparison
117 |
118 | . Run each image three times before recording the numbers, then each command five times
119 |
120 | . Write each time down, add them up, and divide by five for the average. For example:
121 | +
122 | ----
123 | Spring Boot: (39 + 40 + 38 + 37 + 41) / 5 = 39
124 | Micronaut: (17 + 19 + 19 + 20 + 15) / 5 = 18
125 | Quarkus: (25 + 18 + 20 + 19 + 21) / 5 = 20.6
126 | Helidon: (45 + 44 + 45 + 39 + 43) / 5 = 43.2
127 | ----
128 |
129 | .Native Java startup times in milliseconds
130 | |===
131 | |Framework | Command executed | Milliseconds to start
132 |
133 | |Spring Boot | `./spring-boot/target/demo` | 39
134 | |Micronaut | `./micronaut/target/app` | 18
135 | |Quarkus | `./quarkus/target/quarkus-1.0.0-SNAPSHOT-runner` | 20.6
136 | |Helidon | `./helidon/target/helidon` | 43.2
137 | |===
138 |
139 | == Memory Usage Comparison
140 |
141 | Test the memory usage in MB of each app using the command below. Make sure to send an HTTP request to each one before measuring.
142 |
143 | [source,shell]
144 | ----
145 | ps -o pid,rss,command | grep --color | awk '{$2=int($2/1024)"M";}{ print;}'
146 | ----
147 |
148 | Substitute `` as follows:
149 |
150 | .Native Java memory used in megabytes
151 | |===
152 | |Framework | Executable | Megabytes before request | Megabytes after request| Megabytes after 5 requests
153 |
154 | |Spring Boot | `demo` | 74 | 98 | 99
155 | |Micronaut | `app` | 43 | 58 | 69
156 | |Quarkus | `quarkus` | 37 | 48 | 50
157 | |Helidon | `helidon` | 79 | 97 | 131
158 | |===
159 |
160 | IMPORTANT: If you disagree with these numbers and think X framework should be faster, I encourage you to clone https://github.com/oktadev/native-java-examples[the repo] and run these tests yourself. If you get faster startup times for Spring Boot, do you get faster startup times for Helidon, Micronaut, and Quarkus too?
161 |
162 | == Secure Native Java with Spring Boot FTW!
163 |
164 | ⚡️ Create a secure REST API with Spring Boot:
165 |
166 | [source,shell]
167 | ----
168 | okta start spring-boot
169 | okta start spring-boot -b webflux
170 | ----
171 |
172 | 🚀 Find this example's code on GitHub: https://github.com/oktadev/native-java-examples/tree/main/spring-boot[@oktadev/native-java-examples/spring-boot]
173 |
174 | 👀 Read the blog post: https://developer.okta.com/blog/2021/06/18/native-java-framework-comparison[Build Native Java Apps with Micronaut, Quarkus, and Spring Boot]
175 |
--------------------------------------------------------------------------------
/demo.adoc:
--------------------------------------------------------------------------------
1 | :experimental:
2 | :commandkey: ⌘
3 | :toc: macro
4 | :source-highlighter: highlight.js
5 |
6 | = Native Java REST API Demo Steps
7 |
8 | In this demo, I'll show how to create native images with Micronaut, Quarkus, and Spring Boot. You'll see how to run a secure, OAuth 2.0-protected, Java REST API that allows JWT authentication.
9 |
10 | **Prerequisites:**
11 |
12 | - https://sdkman.io/[SDKMAN] (for Java 17 with GraalVM)
13 | - https://httpie.io/[HTTPie] (a better version of cURL)
14 | - An https://developer.okta.com[Okta Developer] Account (or the https://cli.okta.com/[Okta CLI])
15 |
16 | TIP: The brackets at the end of some steps indicate the IntelliJ Live Templates to use. You can find the template definitions at https://github.com/mraible/idea-live-templates[mraible/idea-live-templates].
17 |
18 | toc::[]
19 |
20 | == Install a JDK with GraalVM
21 |
22 | Use SDKMAN to install Java 17 with GraalVM
23 |
24 | sdk install java 22.3.r17-grl
25 |
26 | == Generate an OAuth 2.0 Access Token
27 |
28 | . Install the https://cli.okta.com/[Okta CLI] and run `okta register` to sign up for a new account. If you already have an account, run `okta login`.
29 |
30 | . Run `okta apps create spa`. Set `oidcdebugger` as an app name and press **Enter**.
31 |
32 | . Use `\https://oidcdebugger.com/debug` for the Redirect URI and set the Logout Redirect URI to `\https://oidcdebugger.com`.
33 |
34 | . Navigate to the https://oidcdebugger.com/[OpenID Connect Debugger website].
35 |
36 | .. Fill in your client ID
37 | .. Use `\https://{yourOktaDomain}/oauth2/default/v1/authorize` for the Authorize URI
38 | .. Select **code** for the response type and **Use PKCE**
39 | .. Click **Send Request** to continue
40 |
41 | . Set the access token as a `TOKEN` environment variable in a terminal window.
42 |
43 | TOKEN=eyJraWQiOiJYa2pXdjMzTDRBYU1ZSzNGM...
44 |
45 | == Make a Micronaut Java API
46 |
47 | . Use SDKMAN to install Micronaut's CLI and create an app:
48 | +
49 | [source,shell]
50 | ----
51 | sdk install micronaut
52 | mn create-app com.okta.rest.app --build maven -f security-jwt -f micronaut-aot
53 | mv app micronaut
54 | ----
55 |
56 | . Create `controller/HelloController.java`: [`mn-hello`]
57 | +
58 | [source,java]
59 | ----
60 | package com.okta.rest.controller;
61 |
62 | import io.micronaut.http.MediaType;
63 | import io.micronaut.http.annotation.Controller;
64 | import io.micronaut.http.annotation.Get;
65 | import io.micronaut.http.annotation.Produces;
66 | import io.micronaut.security.annotation.Secured;
67 | import io.micronaut.security.rules.SecurityRule;
68 |
69 | import java.security.Principal;
70 |
71 | @Controller("/hello")
72 | public class HelloController {
73 |
74 | @Get
75 | @Secured(SecurityRule.IS_AUTHENTICATED)
76 | @Produces(MediaType.TEXT_PLAIN)
77 | public String hello(Principal principal) {
78 | return "Hello, " + principal.getName() + "!";
79 | }
80 |
81 | }
82 | ----
83 |
84 | . Enable and configure JWT security in `src/main/resources/application.yml`: [`mn-security-config`]
85 | +
86 | [source,yaml]
87 | ----
88 | micronaut:
89 | ...
90 | security:
91 | enabled: true
92 | token:
93 | jwt:
94 | enabled: true
95 | claims-validators:
96 | issuer: https://{yourOktaDomain}/oauth2/default
97 | signatures:
98 | jwks:
99 | okta:
100 | url: https://{yourOktaDomain}/oauth2/default/v1/keys
101 | ----
102 |
103 | === Run and Test Your Micronaut API with HTTPie
104 |
105 | . Start your app:
106 |
107 | ./mvnw mn:run
108 |
109 | . Use HTTPie to pass the JWT in as a bearer token in the `Authorization` header:
110 |
111 | http :8080/hello Authorization:"Bearer $TOKEN"
112 | +
113 | You should get a 200 response with your email in it.
114 |
115 | === Build a Native Micronaut App
116 |
117 | . Compile your Micronaut app into a native binary:
118 |
119 | ./mvnw package -Dpackaging=native-image
120 |
121 | . Start your Micronaut app:
122 |
123 | ./target/app
124 |
125 | . Test it with HTTPie and an access token. You may have to generate a new JWT with oidcdebugger.com if yours has expired.
126 |
127 | http :8080/hello Authorization:"Bearer $TOKEN"
128 |
129 | == Create a Quarkus Java API
130 |
131 | . Use Maven to generate a new Quarkus app with JWT support:
132 | +
133 | [source,shell]
134 | ----
135 | mvn io.quarkus:quarkus-maven-plugin:2.13.3.Final:create \
136 | -DprojectGroupId=com.okta.rest \
137 | -DprojectArtifactId=quarkus \
138 | -DclassName="com.okta.rest.quarkus.HelloResource" \
139 | -Dpath="/hello" \
140 | -Dextensions="smallrye-jwt,resteasy-reactive"
141 | ----
142 |
143 | . Edit `src/java/com/okta/rest/quarkus/HelloResource.java` and add user information to the `hello()` method: [`qk-hello`]
144 | +
145 | [source,java]
146 | ----
147 | package com.okta.rest.quarkus;
148 |
149 | import io.quarkus.security.Authenticated;
150 |
151 | import javax.ws.rs.GET;
152 | import javax.ws.rs.Path;
153 | import javax.ws.rs.Produces;
154 | import javax.ws.rs.core.Context;
155 | import javax.ws.rs.core.MediaType;
156 | import javax.ws.rs.core.SecurityContext;
157 | import java.security.Principal;
158 |
159 | @Path("/hello")
160 | public class HelloResource {
161 |
162 | @GET
163 | @Authenticated
164 | @Produces(MediaType.TEXT_PLAIN)
165 | public String hello(@Context SecurityContext context) {
166 | Principal userPrincipal = context.getUserPrincipal();
167 | return "Hello, " + userPrincipal.getName() + "!";
168 | }
169 | }
170 | ----
171 |
172 | . Add your Okta endpoints to `src/main/resources/application.properties`: [`qk-properties`]
173 | +
174 | [source,properties]
175 | ----
176 | mp.jwt.verify.publickey.location=https://{yourOktaDomain}/oauth2/default/v1/keys
177 | mp.jwt.verify.issuer=https://{yourOktaDomain}/oauth2/default
178 | ----
179 |
180 | . Modify the `HelloResourceTest` to expect a 401 instead of a 200:
181 | +
182 | [source,java]
183 | ----
184 | package com.okta.rest.quarkus;
185 |
186 | import io.quarkus.test.junit.QuarkusTest;
187 | import org.junit.jupiter.api.Test;
188 |
189 | import static io.restassured.RestAssured.given;
190 |
191 | @QuarkusTest
192 | public class HelloResourceTest {
193 |
194 | @Test
195 | public void testHelloEndpoint() {
196 | given()
197 | .when().get("/hello")
198 | .then()
199 | .statusCode(401);
200 | }
201 |
202 | }
203 | ----
204 |
205 | === Run and Test Your Quarkus API with HTTPie
206 |
207 | . Run your Quarkus app:
208 |
209 | ./mvnw quarkus:dev
210 |
211 | . Test it from another terminal:
212 |
213 | http :8080/hello
214 |
215 | . Test with access token:
216 |
217 | http :8080/hello Authorization:"Bearer $TOKEN"
218 |
219 | === Build a Native Quarkus App
220 |
221 | . Compile your Quarkus app into a native binary:
222 |
223 | ./mvnw package -Pnative
224 |
225 | . Start your Quarkus app:
226 |
227 | ./target/quarkus-1.0.0-SNAPSHOT-runner
228 |
229 | . Test it with HTTPie and an access token:
230 |
231 | http :8080/hello Authorization:"Bearer $TOKEN"
232 |
233 | == Start a Spring Boot Java API
234 |
235 | . Create a Spring Boot app with OAuth 2.0 support:
236 | +
237 | [source,shell]
238 | ----
239 | https start.spring.io/starter.zip \
240 | bootVersion==3.0.0-RC1 \
241 | dependencies==web,oauth2-resource-server,native \
242 | packageName==com.okta.rest \
243 | name==spring-boot \
244 | type==maven-project \
245 | baseDir==spring-boot | tar -xzvf -
246 | ----
247 |
248 | . Add a `HelloController` class that returns the user's information: [`sb-hello`]
249 | +
250 | [source,java]
251 | ----
252 | package com.okta.rest.controller;
253 |
254 | import org.springframework.web.bind.annotation.GetMapping;
255 | import org.springframework.web.bind.annotation.RestController;
256 |
257 | import java.security.Principal;
258 |
259 | @RestController
260 | public class HelloController {
261 |
262 | @GetMapping("/hello")
263 | public String hello(Principal principal) {
264 | return "Hello, " + principal.getName() + "!";
265 | }
266 |
267 | }
268 | ----
269 |
270 | . Configure the app to be an OAuth 2.0 resource server by adding the issuer to `application.properties`.
271 | +
272 | [source,properties]
273 | ----
274 | spring.security.oauth2.resourceserver.jwt.issuer-uri=https://{yourOktaDomain}/oauth2/default
275 | ----
276 |
277 | === Run and Test Your Spring Boot API with HTTPie
278 |
279 | . Start your app from your IDE or using a terminal:
280 |
281 | ./mvnw spring-boot:run
282 |
283 | . Test your API with an access token.
284 |
285 | http :8080/hello Authorization:"Bearer $TOKEN"
286 |
287 | === Build a Native Spring Boot App
288 |
289 | . Compile your Spring Boot app into a native executable using the `native` profile:
290 |
291 | ./mvnw native:compile -Pnative
292 | +
293 | TIP: To build a native app and a Docker container, use the Spring Boot Maven plugin and `./mvnw spring-boot:build-image`.
294 |
295 | . Start your Spring Boot app:
296 |
297 | ./target/demo
298 |
299 | . Test your API with an access token.
300 |
301 | http :8080/hello Authorization:"Bearer $TOKEN"
302 |
303 | == Startup Time Comparison
304 |
305 | . Run each image three times before recording the numbers, then each command five times
306 |
307 | . Write each time down, add them up, and divide by five for the average. For example:
308 | +
309 | ----
310 | Micronaut: (17 + 19 + 19 + 20 + 15) / 5 = 18
311 | Quarkus: (25 + 18 + 20 + 19 + 21) / 5 = 20.6
312 | Spring Boot: (39 + 40 + 38 + 37 + 41) / 5 = 39
313 | ----
314 |
315 | .Native Java startup times in milliseconds
316 | |===
317 | |Framework | Command executed | Milliseconds to start
318 |
319 | |Micronaut | `./micronaut/target/app` | 18
320 | |Quarkus | `./quarkus/target/quarkus-1.0.0-SNAPSHOT-runner` | 20.6
321 | |Spring Boot | `./spring-boot/target/demo` | 39
322 | |===
323 |
324 | == Memory Usage Comparison
325 |
326 | Test the memory usage in MB of each app using the command below. Make sure to send an HTTP request to each one before measuring.
327 |
328 | [source,shell]
329 | ----
330 | ps -o pid,rss,command | grep --color | awk '{$2=int($2/1024)"M";}{ print;}'
331 | ----
332 |
333 | Substitute `` as follows:
334 |
335 | .Native Java memory used in megabytes
336 | |===
337 | |Framework | Executable | Megabytes before request | Megabytes after request| Megabytes after 5 requests
338 |
339 | |Micronaut | `app` | 43 | 58 | 69
340 | |Quarkus | `quarkus` | 37 | 48 | 50
341 | |Spring Boot | `demo` | 74 | 98 | 99
342 | |===
343 |
344 | IMPORTANT: If you disagree with these numbers and think X framework should be faster, I encourage you to clone https://github.com/oktadev/native-java-examples[the repo] and run these tests yourself. If you get faster startup times for Spring Boot, do you get faster startup times for Micronaut and Quarkus too?
345 |
346 | == Native Java REST APIs FTW!
347 |
348 | 🚀 Find the code on GitHub: https://github.com/oktadev/native-java-examples[@oktadev/native-java-examples]
349 |
350 | 📖 Read the blog post: https://developer.okta.com/blog/2021/06/18/native-java-framework-comparison[Build Native Java Apps with Micronaut, Quarkus, and Spring Boot]
351 |
--------------------------------------------------------------------------------
/helidon/.dockerignore:
--------------------------------------------------------------------------------
1 | target/*
--------------------------------------------------------------------------------
/helidon/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | target/
3 |
--------------------------------------------------------------------------------
/helidon/.helidon:
--------------------------------------------------------------------------------
1 | #Helidon Project Configuration
2 | #Fri Oct 21 12:42:35 MDT 2022
3 | schema.version=1.1.0
4 | helidon.version=3.0.2
5 | project.flavor=mp
6 | project.archetype=quickstart
7 |
--------------------------------------------------------------------------------
/helidon/Dockerfile:
--------------------------------------------------------------------------------
1 |
2 | # 1st stage, build the app
3 | FROM maven:3.8.4-openjdk-17-slim as build
4 |
5 | WORKDIR /helidon
6 |
7 | # Create a first layer to cache the "Maven World" in the local repository.
8 | # Incremental docker builds will always resume after that, unless you update
9 | # the pom
10 | ADD pom.xml .
11 | RUN mvn package -Dmaven.test.skip -Declipselink.weave.skip
12 |
13 | # Do the Maven build!
14 | # Incremental docker builds will resume here when you change sources
15 | ADD src src
16 | RUN mvn package -DskipTests
17 |
18 | RUN echo "done!"
19 |
20 | # 2nd stage, build the runtime image
21 | FROM openjdk:17-jdk-slim
22 | WORKDIR /helidon
23 |
24 | # Copy the binary built in the 1st stage
25 | COPY --from=build /helidon/target/helidon.jar ./
26 | COPY --from=build /helidon/target/libs ./libs
27 |
28 | CMD ["java", "-jar", "helidon.jar"]
29 |
30 | EXPOSE 8080
31 |
--------------------------------------------------------------------------------
/helidon/Dockerfile.jlink:
--------------------------------------------------------------------------------
1 |
2 | # 1st stage, build the app
3 | FROM maven:3.8.4-openjdk-17-slim as build
4 |
5 | WORKDIR /helidon
6 |
7 | # Create a first layer to cache the "Maven World" in the local repository.
8 | # Incremental docker builds will always resume after that, unless you update
9 | # the pom
10 | ADD pom.xml .
11 | RUN mvn package -Dmaven.test.skip -Declipselink.weave.skip
12 |
13 | # Do the Maven build to create the custom Java Runtime Image
14 | # Incremental docker builds will resume here when you change sources
15 | ADD src src
16 | # Don't generate CDS archive to work around JVM bug https://bugs.openjdk.org/browse/JDK-8274944
17 | RUN mvn -Ddocker.build=true package -Pjlink-image -DskipTests -Djlink.image.addClassDataSharingArchive=false
18 | RUN echo "done!"
19 |
20 | # 2nd stage, build the final image with the JRI built in the 1st stage
21 |
22 | FROM debian:stretch-slim
23 | WORKDIR /helidon
24 | COPY --from=build /helidon/target/helidon-jri ./
25 | ENTRYPOINT ["/bin/bash", "/helidon/bin/start"]
26 | EXPOSE 8080
27 |
--------------------------------------------------------------------------------
/helidon/Dockerfile.native:
--------------------------------------------------------------------------------
1 |
2 | # 1st stage, build the app
3 | FROM ghcr.io/graalvm/graalvm-ce:java17-21.3.0 as build
4 |
5 | # Install native-image
6 | RUN gu install native-image
7 |
8 | WORKDIR /usr/share
9 |
10 | # Install maven
11 | RUN set -x && \
12 | curl -O https://archive.apache.org/dist/maven/maven-3/3.8.4/binaries/apache-maven-3.8.4-bin.tar.gz && \
13 | tar -xvf apache-maven-*-bin.tar.gz && \
14 | rm apache-maven-*-bin.tar.gz && \
15 | mv apache-maven-* maven && \
16 | ln -s /usr/share/maven/bin/mvn /bin/
17 |
18 | WORKDIR /helidon
19 |
20 | # Create a first layer to cache the "Maven World" in the local repository.
21 | # Incremental docker builds will always resume after that, unless you update
22 | # the pom
23 | ADD pom.xml .
24 | RUN mvn package -Pnative-image -Dnative.image.skip -Dmaven.test.skip -Declipselink.weave.skip
25 |
26 | # Do the Maven build!
27 | # Incremental docker builds will resume here when you change sources
28 | ADD src src
29 | RUN mvn package -Pnative-image -Dnative.image.buildStatic -DskipTests
30 |
31 | RUN echo "done!"
32 |
33 | # 2nd stage, build the runtime image
34 | FROM scratch
35 | WORKDIR /helidon
36 |
37 | # Copy the binary built in the 1st stage
38 | COPY --from=build /helidon/target/helidon .
39 |
40 | ENTRYPOINT ["./helidon"]
41 |
42 | EXPOSE 8080
43 |
--------------------------------------------------------------------------------
/helidon/README.md:
--------------------------------------------------------------------------------
1 | # helidon
2 |
3 | Minimal Helidon MP project suitable to start from scratch.
4 |
5 | ## Build and run
6 |
7 |
8 | With JDK17+
9 | ```bash
10 | mvn package
11 | java -jar target/helidon.jar
12 | ```
13 |
14 | ## Exercise the application
15 | ```
16 | curl -X GET http://localhost:8080/simple-greet
17 | {"message":"Hello World!"}
18 | ```
19 |
20 | ```
21 | curl -X GET http://localhost:8080/greet
22 | {"message":"Hello World!"}
23 |
24 | curl -X GET http://localhost:8080/greet/Joe
25 | {"message":"Hello Joe!"}
26 |
27 | curl -X PUT -H "Content-Type: application/json" -d '{"greeting" : "Hola"}' http://localhost:8080/greet/greeting
28 |
29 | curl -X GET http://localhost:8080/greet/Jose
30 | {"message":"Hola Jose!"}
31 | ```
32 |
33 |
34 |
35 | ## Building a Native Image
36 |
37 | Make sure you have GraalVM locally installed:
38 |
39 | ```
40 | $GRAALVM_HOME/bin/native-image --version
41 | ```
42 |
43 | Build the native image using the native image profile:
44 |
45 | ```
46 | mvn package -Pnative-image
47 | ```
48 |
49 | This uses the helidon-maven-plugin to perform the native compilation using your installed copy of GraalVM. It might take a while to complete.
50 | Once it completes start the application using the native executable (no JVM!):
51 |
52 | ```
53 | ./target/helidon
54 | ```
55 |
56 | Yep, it starts fast. You can exercise the application’s endpoints as before.
57 |
58 |
59 | ## Try metrics
60 |
61 | ```
62 | # Prometheus Format
63 | curl -s -X GET http://localhost:8080/metrics
64 | # TYPE base:gc_g1_young_generation_count gauge
65 | . . .
66 |
67 | # JSON Format
68 | curl -H 'Accept: application/json' -X GET http://localhost:8080/metrics
69 | {"base":...
70 | . . .
71 | ```
72 |
73 |
74 |
75 | ## Try health
76 |
77 | ```
78 | curl -s -X GET http://localhost:8080/health
79 | {"outcome":"UP",...
80 |
81 | ```
82 |
83 |
84 |
85 | ## Building the Docker Image
86 | ```
87 | docker build -t helidon .
88 | ```
89 |
90 | ## Running the Docker Image
91 |
92 | ```
93 | docker run --rm -p 8080:8080 helidon:latest
94 | ```
95 |
96 | Exercise the application as described above.
97 |
98 |
99 | ## Building a Custom Runtime Image
100 |
101 | Build the custom runtime image using the jlink image profile:
102 |
103 | ```
104 | mvn package -Pjlink-image
105 | ```
106 |
107 | This uses the helidon-maven-plugin to perform the custom image generation.
108 | After the build completes it will report some statistics about the build including the reduction in image size.
109 |
110 | The target/helidon-jri directory is a self contained custom image of your application. It contains your application,
111 | its runtime dependencies and the JDK modules it depends on. You can start your application using the provide start script:
112 |
113 | ```
114 | ./target/helidon-jri/bin/start
115 | ```
116 |
117 | Class Data Sharing (CDS) Archive
118 | Also included in the custom image is a Class Data Sharing (CDS) archive that improves your application’s startup
119 | performance and in-memory footprint. You can learn more about Class Data Sharing in the JDK documentation.
120 |
121 | The CDS archive increases your image size to get these performance optimizations. It can be of significant size (tens of MB).
122 | The size of the CDS archive is reported at the end of the build output.
123 |
124 | If you’d rather have a smaller image size (with a slightly increased startup time) you can skip the creation of the CDS
125 | archive by executing your build like this:
126 |
127 | ```
128 | mvn package -Pjlink-image -Djlink.image.addClassDataSharingArchive=false
129 | ```
130 |
131 | For more information on available configuration options see the helidon-maven-plugin documentation.
132 |
133 |
--------------------------------------------------------------------------------
/helidon/app.yaml:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2018, 2021 Oracle and/or its affiliates. All rights reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | kind: Service
18 | apiVersion: v1
19 | metadata:
20 | name: helidon
21 | labels:
22 | app: helidon
23 | spec:
24 | type: NodePort
25 | selector:
26 | app: helidon
27 | ports:
28 | - port: 8080
29 | targetPort: 8080
30 | name: http
31 | ---
32 |
33 |
--------------------------------------------------------------------------------
/helidon/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | io.helidon.applications
8 | helidon-mp
9 | 3.0.2
10 |
11 |
12 | com.okta.rest
13 | helidon
14 | 1.0-SNAPSHOT
15 |
16 |
17 |
18 |
19 |
20 |
21 | io.helidon.microprofile.bundles
22 | helidon-microprofile-core
23 |
24 |
25 | io.helidon.microprofile.openapi
26 | helidon-microprofile-openapi
27 |
28 |
29 | org.eclipse.microprofile.metrics
30 | microprofile-metrics-api
31 |
32 |
33 | io.helidon.microprofile.metrics
34 | helidon-microprofile-metrics
35 |
36 |
37 | io.helidon.microprofile.health
38 | helidon-microprofile-health
39 |
40 |
41 | io.helidon.microprofile.jwt
42 | helidon-microprofile-jwt-auth
43 |
44 |
45 | com.fasterxml.jackson.core
46 | jackson-databind
47 |
48 |
49 | org.glassfish.jersey.media
50 | jersey-media-json-jackson
51 | runtime
52 |
53 |
54 | org.jboss
55 | jandex
56 | runtime
57 |
58 |
59 | jakarta.activation
60 | jakarta.activation-api
61 | runtime
62 |
63 |
64 | org.junit.jupiter
65 | junit-jupiter-api
66 | test
67 |
68 |
69 | io.helidon.microprofile.tests
70 | helidon-microprofile-tests-junit5
71 | test
72 |
73 |
74 | org.hamcrest
75 | hamcrest-all
76 | test
77 |
78 |
79 |
80 |
81 |
82 |
83 | org.apache.maven.plugins
84 | maven-dependency-plugin
85 |
86 |
87 | copy-libs
88 |
89 |
90 |
91 |
92 | io.helidon.build-tools
93 | helidon-maven-plugin
94 |
95 |
96 | third-party-license-report
97 |
98 |
99 |
100 |
101 | org.jboss.jandex
102 | jandex-maven-plugin
103 |
104 |
105 | make-index
106 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/helidon/src/main/java/com/okta/rest/HelloApplication.java:
--------------------------------------------------------------------------------
1 | package com.okta.rest;
2 |
3 | import com.okta.rest.controller.HelloResource;
4 | import org.eclipse.microprofile.auth.LoginConfig;
5 |
6 | import jakarta.enterprise.context.ApplicationScoped;
7 | import jakarta.ws.rs.core.Application;
8 | import java.util.Set;
9 |
10 | @LoginConfig(authMethod = "MP-JWT")
11 | @ApplicationScoped
12 | public class HelloApplication extends Application {
13 |
14 | @Override
15 | public Set> getClasses() {
16 | return Set.of(HelloResource.class);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/helidon/src/main/java/com/okta/rest/controller/HelloResource.java:
--------------------------------------------------------------------------------
1 | package com.okta.rest.controller;
2 |
3 | import io.helidon.security.SecurityContext;
4 | import io.helidon.security.annotations.Authenticated;
5 |
6 | import jakarta.ws.rs.GET;
7 | import jakarta.ws.rs.Path;
8 | import jakarta.ws.rs.core.Context;
9 |
10 | @Path("/hello")
11 | public class HelloResource {
12 |
13 | @Authenticated
14 | @GET
15 | public String hello(@Context SecurityContext context) {
16 | return "Hello, " + context.userName() + "!";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/helidon/src/main/java/com/okta/rest/package-info.java:
--------------------------------------------------------------------------------
1 |
2 | package com.okta.rest;
3 |
--------------------------------------------------------------------------------
/helidon/src/main/resources/META-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/helidon/src/main/resources/META-INF/microprofile-config.properties:
--------------------------------------------------------------------------------
1 | # Microprofile server properties
2 | server.port=8080
3 | server.host=0.0.0.0
4 |
5 | # Change the following to true to enable the optional MicroProfile Metrics REST.request metrics
6 | metrics.rest-request.enabled=false
7 |
8 | # Application properties. This is the default greeting
9 | app.greeting=Hello
10 |
--------------------------------------------------------------------------------
/helidon/src/main/resources/META-INF/native-image/reflect-config.json:
--------------------------------------------------------------------------------
1 | []
2 |
--------------------------------------------------------------------------------
/helidon/src/main/resources/application.yaml:
--------------------------------------------------------------------------------
1 | mp.jwt.verify.issuer: https://dev-17700857.okta.com/oauth2/default
2 | mp.jwt.verify.publickey.location: ${mp.jwt.verify.issuer}/v1/keys
3 |
--------------------------------------------------------------------------------
/helidon/src/main/resources/logging.properties:
--------------------------------------------------------------------------------
1 |
2 | # Example Logging Configuration File
3 | # For more information see $JAVA_HOME/jre/lib/logging.properties
4 |
5 | # Send messages to the console
6 | handlers=io.helidon.common.HelidonConsoleHandler
7 |
8 | # HelidonConsoleHandler uses a SimpleFormatter subclass that replaces "!thread!" with the current thread
9 | java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS %4$s %3$s !thread!: %5$s%6$s%n
10 |
11 | # Global logging level. Can be overridden by specific loggers
12 | .level=INFO
13 |
14 | # Quiet Weld
15 | org.jboss.level=WARNING
16 |
17 | # Component specific log levels
18 | #io.helidon.webserver.level=INFO
19 | #io.helidon.config.level=INFO
20 | #io.helidon.security.level=INFO
21 | #io.helidon.common.level=INFO
22 | #io.netty.level=INFO
23 |
--------------------------------------------------------------------------------
/helidon/src/test/resources/application.yaml:
--------------------------------------------------------------------------------
1 | security:
2 | enabled: false
--------------------------------------------------------------------------------
/micronaut/.gitignore:
--------------------------------------------------------------------------------
1 | Thumbs.db
2 | .DS_Store
3 | .gradle
4 | build/
5 | target/
6 | out/
7 | .micronaut/
8 | .idea
9 | *.iml
10 | *.ipr
11 | *.iws
12 | .project
13 | .settings
14 | .classpath
15 | .factorypath
16 |
--------------------------------------------------------------------------------
/micronaut/.mvn/wrapper/MavenWrapperDownloader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import java.io.File;
18 | import java.io.FileInputStream;
19 | import java.io.FileOutputStream;
20 | import java.io.IOException;
21 | import java.net.Authenticator;
22 | import java.net.PasswordAuthentication;
23 | import java.net.URL;
24 | import java.nio.channels.Channels;
25 | import java.nio.channels.ReadableByteChannel;
26 | import java.util.Properties;
27 |
28 | public class MavenWrapperDownloader {
29 |
30 | private static final String WRAPPER_VERSION = "0.5.6";
31 | /**
32 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
33 | */
34 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
35 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
36 |
37 | /**
38 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
39 | * use instead of the default one.
40 | */
41 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
42 | ".mvn/wrapper/maven-wrapper.properties";
43 |
44 | /**
45 | * Path where the maven-wrapper.jar will be saved to.
46 | */
47 | private static final String MAVEN_WRAPPER_JAR_PATH =
48 | ".mvn/wrapper/maven-wrapper.jar";
49 |
50 | /**
51 | * Name of the property which should be used to override the default download url for the wrapper.
52 | */
53 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
54 |
55 | public static void main(String args[]) {
56 | System.out.println("- Downloader started");
57 | File baseDirectory = new File(args[0]);
58 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
59 |
60 | // If the maven-wrapper.properties exists, read it and check if it contains a custom
61 | // wrapperUrl parameter.
62 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
63 | String url = DEFAULT_DOWNLOAD_URL;
64 | if(mavenWrapperPropertyFile.exists()) {
65 | FileInputStream mavenWrapperPropertyFileInputStream = null;
66 | try {
67 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
68 | Properties mavenWrapperProperties = new Properties();
69 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
70 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
71 | } catch (IOException e) {
72 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
73 | } finally {
74 | try {
75 | if(mavenWrapperPropertyFileInputStream != null) {
76 | mavenWrapperPropertyFileInputStream.close();
77 | }
78 | } catch (IOException e) {
79 | // Ignore ...
80 | }
81 | }
82 | }
83 | System.out.println("- Downloading from: " + url);
84 |
85 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
86 | if(!outputFile.getParentFile().exists()) {
87 | if(!outputFile.getParentFile().mkdirs()) {
88 | System.out.println(
89 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
90 | }
91 | }
92 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
93 | try {
94 | downloadFileFromURL(url, outputFile);
95 | System.out.println("Done");
96 | System.exit(0);
97 | } catch (Throwable e) {
98 | System.out.println("- Error downloading");
99 | e.printStackTrace();
100 | System.exit(1);
101 | }
102 | }
103 |
104 | private static void downloadFileFromURL(String urlString, File destination) throws Exception {
105 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
106 | String username = System.getenv("MVNW_USERNAME");
107 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
108 | Authenticator.setDefault(new Authenticator() {
109 | @Override
110 | protected PasswordAuthentication getPasswordAuthentication() {
111 | return new PasswordAuthentication(username, password);
112 | }
113 | });
114 | }
115 | URL website = new URL(urlString);
116 | ReadableByteChannel rbc;
117 | rbc = Channels.newChannel(website.openStream());
118 | FileOutputStream fos = new FileOutputStream(destination);
119 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
120 | fos.close();
121 | rbc.close();
122 | }
123 |
124 | }
125 |
--------------------------------------------------------------------------------
/micronaut/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oktadev/native-java-examples/2c9d53a25150a0a9febcbfd9e9edf08186c6ee02/micronaut/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/micronaut/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
3 |
--------------------------------------------------------------------------------
/micronaut/README.md:
--------------------------------------------------------------------------------
1 | ## Micronaut 3.7.2 Documentation
2 |
3 | - [User Guide](https://docs.micronaut.io/3.7.2/guide/index.html)
4 | - [API Reference](https://docs.micronaut.io/3.7.2/api/index.html)
5 | - [Configuration Reference](https://docs.micronaut.io/3.7.2/guide/configurationreference.html)
6 | - [Micronaut Guides](https://guides.micronaut.io/index.html)
7 | ---
8 |
9 | ## Feature http-client documentation
10 |
11 | - [Micronaut HTTP Client documentation](https://docs.micronaut.io/latest/guide/index.html#httpClient)
12 |
13 |
14 | ## Feature micronaut-aot documentation
15 |
16 | - [Micronaut AOT documentation](https://micronaut-projects.github.io/micronaut-aot/latest/guide/)
17 |
18 |
19 | ## Feature security-jwt documentation
20 |
21 | - [Micronaut Security JWT documentation](https://micronaut-projects.github.io/micronaut-security/latest/guide/index.html)
22 |
23 |
24 |
--------------------------------------------------------------------------------
/micronaut/aot-jar.properties:
--------------------------------------------------------------------------------
1 | # AOT configuration properties for jar packaging
2 | # Please review carefully the optimizations enabled below
3 | # Check https://micronaut-projects.github.io/micronaut-aot/latest/guide/ for more details
4 |
5 | # Caches environment property values: environment properties will be deemed immutable after application startup.
6 | cached.environment.enabled=true
7 |
8 | # Precomputes Micronaut configuration property keys from the current environment variables
9 | precompute.environment.properties.enabled=true
10 |
11 | # Converts YAML configuration files to Java configuration
12 | yaml.to.java.config.enabled=true
13 |
14 | # Scans for service types ahead-of-time, avoiding classpath scanning at startup
15 | serviceloading.jit.enabled = true
16 |
17 | # Scans reactive types at build time instead of runtime
18 | scan.reactive.types.enabled=true
19 |
20 | # Deduces the environment at build time instead of runtime
21 | deduce.environment.enabled=true
22 |
23 | # Checks of existence of some types at build time instead of runtime
24 | known.missing.types.enabled=true
25 |
26 | # Precomputes property sources at build time
27 | sealed.property.source.enabled=true
28 |
29 | # The list of service types to be scanned (comma separated)
30 | service.types=io.micronaut.context.env.PropertySourceLoader,io.micronaut.inject.BeanConfiguration,io.micronaut.inject.BeanDefinitionReference,io.micronaut.http.HttpRequestFactory,io.micronaut.http.HttpResponseFactory,io.micronaut.core.beans.BeanIntrospectionReference
31 |
32 | # A list of types that the AOT analyzer needs to check for existence (comma separated)
33 | known.missing.types.list=io.reactivex.Observable,reactor.core.publisher.Flux,kotlinx.coroutines.flow.Flow,io.reactivex.rxjava3.core.Flowable,io.reactivex.rxjava3.core.Observable,io.reactivex.Single,reactor.core.publisher.Mono,io.reactivex.Maybe,io.reactivex.rxjava3.core.Single,io.reactivex.rxjava3.core.Maybe,io.reactivex.Completable,io.reactivex.rxjava3.core.Completable,io.methvin.watchservice.MacOSXListeningWatchService,io.micronaut.core.async.publisher.CompletableFuturePublisher,io.micronaut.core.async.publisher.Publishers.JustPublisher,io.micronaut.core.async.subscriber.Completable
--------------------------------------------------------------------------------
/micronaut/micronaut-cli.yml:
--------------------------------------------------------------------------------
1 | applicationType: default
2 | defaultPackage: com.okta.rest
3 | testFramework: junit
4 | sourceLanguage: java
5 | buildTool: maven
6 | features: [annotation-api, app-name, http-client, jackson-databind, java, java-application, junit, logback, maven, micronaut-aot, netty-server, readme, security-annotations, security-jwt, shade, yaml]
7 |
--------------------------------------------------------------------------------
/micronaut/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # https://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Mingw, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | fi
118 |
119 | if [ -z "$JAVA_HOME" ]; then
120 | javaExecutable="`which javac`"
121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
122 | # readlink(1) is not available as standard on Solaris 10.
123 | readLink=`which readlink`
124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
125 | if $darwin ; then
126 | javaHome="`dirname \"$javaExecutable\"`"
127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
128 | else
129 | javaExecutable="`readlink -f \"$javaExecutable\"`"
130 | fi
131 | javaHome="`dirname \"$javaExecutable\"`"
132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
133 | JAVA_HOME="$javaHome"
134 | export JAVA_HOME
135 | fi
136 | fi
137 | fi
138 |
139 | if [ -z "$JAVACMD" ] ; then
140 | if [ -n "$JAVA_HOME" ] ; then
141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
142 | # IBM's JDK on AIX uses strange locations for the executables
143 | JAVACMD="$JAVA_HOME/jre/sh/java"
144 | else
145 | JAVACMD="$JAVA_HOME/bin/java"
146 | fi
147 | else
148 | JAVACMD="`which java`"
149 | fi
150 | fi
151 |
152 | if [ ! -x "$JAVACMD" ] ; then
153 | echo "Error: JAVA_HOME is not defined correctly." >&2
154 | echo " We cannot execute $JAVACMD" >&2
155 | exit 1
156 | fi
157 |
158 | if [ -z "$JAVA_HOME" ] ; then
159 | echo "Warning: JAVA_HOME environment variable is not set."
160 | fi
161 |
162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
163 |
164 | # traverses directory structure from process work directory to filesystem root
165 | # first directory with .mvn subdirectory is considered project base directory
166 | find_maven_basedir() {
167 |
168 | if [ -z "$1" ]
169 | then
170 | echo "Path not specified to find_maven_basedir"
171 | return 1
172 | fi
173 |
174 | basedir="$1"
175 | wdir="$1"
176 | while [ "$wdir" != '/' ] ; do
177 | if [ -d "$wdir"/.mvn ] ; then
178 | basedir=$wdir
179 | break
180 | fi
181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
182 | if [ -d "${wdir}" ]; then
183 | wdir=`cd "$wdir/.."; pwd`
184 | fi
185 | # end of workaround
186 | done
187 | echo "${basedir}"
188 | }
189 |
190 | # concatenates all lines of a file
191 | concat_lines() {
192 | if [ -f "$1" ]; then
193 | echo "$(tr -s '\n' ' ' < "$1")"
194 | fi
195 | }
196 |
197 | BASE_DIR=`find_maven_basedir "$(pwd)"`
198 | if [ -z "$BASE_DIR" ]; then
199 | exit 1;
200 | fi
201 |
202 | ##########################################################################################
203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
204 | # This allows using the maven wrapper in projects that prohibit checking in binary data.
205 | ##########################################################################################
206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
207 | if [ "$MVNW_VERBOSE" = true ]; then
208 | echo "Found .mvn/wrapper/maven-wrapper.jar"
209 | fi
210 | else
211 | if [ "$MVNW_VERBOSE" = true ]; then
212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
213 | fi
214 | if [ -n "$MVNW_REPOURL" ]; then
215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
216 | else
217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
218 | fi
219 | while IFS="=" read key value; do
220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
221 | esac
222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
223 | if [ "$MVNW_VERBOSE" = true ]; then
224 | echo "Downloading from: $jarUrl"
225 | fi
226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
227 | if $cygwin; then
228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
229 | fi
230 |
231 | if command -v wget > /dev/null; then
232 | if [ "$MVNW_VERBOSE" = true ]; then
233 | echo "Found wget ... using wget"
234 | fi
235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
236 | wget "$jarUrl" -O "$wrapperJarPath"
237 | else
238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
239 | fi
240 | elif command -v curl > /dev/null; then
241 | if [ "$MVNW_VERBOSE" = true ]; then
242 | echo "Found curl ... using curl"
243 | fi
244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
245 | curl -o "$wrapperJarPath" "$jarUrl" -f
246 | else
247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
248 | fi
249 |
250 | else
251 | if [ "$MVNW_VERBOSE" = true ]; then
252 | echo "Falling back to using Java to download"
253 | fi
254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
255 | # For Cygwin, switch paths to Windows format before running javac
256 | if $cygwin; then
257 | javaClass=`cygpath --path --windows "$javaClass"`
258 | fi
259 | if [ -e "$javaClass" ]; then
260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
261 | if [ "$MVNW_VERBOSE" = true ]; then
262 | echo " - Compiling MavenWrapperDownloader.java ..."
263 | fi
264 | # Compiling the Java class
265 | ("$JAVA_HOME/bin/javac" "$javaClass")
266 | fi
267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
268 | # Running the downloader
269 | if [ "$MVNW_VERBOSE" = true ]; then
270 | echo " - Running MavenWrapperDownloader.java ..."
271 | fi
272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
273 | fi
274 | fi
275 | fi
276 | fi
277 | ##########################################################################################
278 | # End of extension
279 | ##########################################################################################
280 |
281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
282 | if [ "$MVNW_VERBOSE" = true ]; then
283 | echo $MAVEN_PROJECTBASEDIR
284 | fi
285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
286 |
287 | # For Cygwin, switch paths to Windows format before running java
288 | if $cygwin; then
289 | [ -n "$M2_HOME" ] &&
290 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
291 | [ -n "$JAVA_HOME" ] &&
292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
293 | [ -n "$CLASSPATH" ] &&
294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
295 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
297 | fi
298 |
299 | # Provide a "standardized" way to retrieve the CLI args that will
300 | # work with both Windows and non-Windows executions.
301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
302 | export MAVEN_CMD_LINE_ARGS
303 |
304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
305 |
306 | exec "$JAVACMD" \
307 | $MAVEN_OPTS \
308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
311 |
--------------------------------------------------------------------------------
/micronaut/mvnw.bat:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM https://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM set title of command window
39 | title %0
40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
42 |
43 | @REM set %HOME% to equivalent of $HOME
44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
45 |
46 | @REM Execute a user defined script before this one
47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
51 | :skipRcPre
52 |
53 | @setlocal
54 |
55 | set ERROR_CODE=0
56 |
57 | @REM To isolate internal variables from possible post scripts, we use another setlocal
58 | @setlocal
59 |
60 | @REM ==== START VALIDATION ====
61 | if not "%JAVA_HOME%" == "" goto OkJHome
62 |
63 | echo.
64 | echo Error: JAVA_HOME not found in your environment. >&2
65 | echo Please set the JAVA_HOME variable in your environment to match the >&2
66 | echo location of your Java installation. >&2
67 | echo.
68 | goto error
69 |
70 | :OkJHome
71 | if exist "%JAVA_HOME%\bin\java.exe" goto init
72 |
73 | echo.
74 | echo Error: JAVA_HOME is set to an invalid directory. >&2
75 | echo JAVA_HOME = "%JAVA_HOME%" >&2
76 | echo Please set the JAVA_HOME variable in your environment to match the >&2
77 | echo location of your Java installation. >&2
78 | echo.
79 | goto error
80 |
81 | @REM ==== END VALIDATION ====
82 |
83 | :init
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
122 |
123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
124 |
125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
127 | )
128 |
129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data.
131 | if exist %WRAPPER_JAR% (
132 | if "%MVNW_VERBOSE%" == "true" (
133 | echo Found %WRAPPER_JAR%
134 | )
135 | ) else (
136 | if not "%MVNW_REPOURL%" == "" (
137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
138 | )
139 | if "%MVNW_VERBOSE%" == "true" (
140 | echo Couldn't find %WRAPPER_JAR%, downloading it ...
141 | echo Downloading from: %DOWNLOAD_URL%
142 | )
143 |
144 | powershell -Command "&{"^
145 | "$webclient = new-object System.Net.WebClient;"^
146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
148 | "}"^
149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
150 | "}"
151 | if "%MVNW_VERBOSE%" == "true" (
152 | echo Finished downloading %WRAPPER_JAR%
153 | )
154 | )
155 | @REM End of extension
156 |
157 | @REM Provide a "standardized" way to retrieve the CLI args that will
158 | @REM work with both Windows and non-Windows executions.
159 | set MAVEN_CMD_LINE_ARGS=%*
160 |
161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
162 | if ERRORLEVEL 1 goto error
163 | goto end
164 |
165 | :error
166 | set ERROR_CODE=1
167 |
168 | :end
169 | @endlocal & set ERROR_CODE=%ERROR_CODE%
170 |
171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
175 | :skipRcPost
176 |
177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
179 |
180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
181 |
182 | exit /B %ERROR_CODE%
183 |
--------------------------------------------------------------------------------
/micronaut/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.okta.rest
6 | app
7 | 0.1
8 | ${packaging}
9 |
10 |
11 | io.micronaut
12 | micronaut-parent
13 | 3.7.2
14 |
15 |
16 |
17 | jar
18 | 11
19 | 11
20 | 3.7.2
21 | true
22 | com.okta.rest.aot.generated
23 | netty
24 | com.okta.rest.Application
25 |
26 |
27 |
28 |
29 | central
30 | https://repo.maven.apache.org/maven2
31 |
32 |
33 |
34 |
35 |
36 | io.micronaut
37 | micronaut-inject
38 | compile
39 |
40 |
41 | io.micronaut
42 | micronaut-validation
43 | compile
44 |
45 |
46 | io.micronaut
47 | micronaut-http-client
48 | compile
49 |
50 |
51 | io.micronaut
52 | micronaut-http-server-netty
53 | compile
54 |
55 |
56 | io.micronaut
57 | micronaut-jackson-databind
58 | compile
59 |
60 |
61 | io.micronaut.security
62 | micronaut-security-jwt
63 | compile
64 |
65 |
66 | jakarta.annotation
67 | jakarta.annotation-api
68 | compile
69 |
70 |
71 | ch.qos.logback
72 | logback-classic
73 | runtime
74 |
75 |
76 | io.micronaut.test
77 | micronaut-test-junit5
78 | test
79 |
80 |
81 | org.junit.jupiter
82 | junit-jupiter-api
83 | test
84 |
85 |
86 | org.junit.jupiter
87 | junit-jupiter-engine
88 | test
89 |
90 |
91 |
92 |
93 |
94 |
95 | io.micronaut.build
96 | micronaut-maven-plugin
97 |
98 | aot-${packaging}.properties
99 |
100 |
101 |
102 |
103 | org.apache.maven.plugins
104 | maven-compiler-plugin
105 |
106 |
107 |
108 |
109 |
110 |
111 | io.micronaut
112 | micronaut-http-validation
113 | ${micronaut.version}
114 |
115 |
116 | io.micronaut.security
117 | micronaut-security-annotations
118 | ${micronaut.security.version}
119 |
120 |
121 |
122 | -Amicronaut.processing.group=com.okta.rest
123 | -Amicronaut.processing.module=app
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/micronaut/src/main/java/com/okta/rest/Application.java:
--------------------------------------------------------------------------------
1 | package com.okta.rest;
2 |
3 | import io.micronaut.runtime.Micronaut;
4 |
5 | public class Application {
6 | public static void main(String[] args) {
7 | Micronaut.run(Application.class, args);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/micronaut/src/main/java/com/okta/rest/controller/HelloController.java:
--------------------------------------------------------------------------------
1 | package com.okta.rest.controller;
2 |
3 | import io.micronaut.http.MediaType;
4 | import io.micronaut.http.annotation.Controller;
5 | import io.micronaut.http.annotation.Get;
6 | import io.micronaut.http.annotation.Produces;
7 | import io.micronaut.security.annotation.Secured;
8 | import io.micronaut.security.rules.SecurityRule;
9 |
10 | import java.security.Principal;
11 |
12 | @Controller("/hello")
13 | public class HelloController {
14 |
15 | @Get
16 | @Secured(SecurityRule.IS_AUTHENTICATED)
17 | @Produces(MediaType.TEXT_PLAIN)
18 | public String hello(Principal principal) {
19 | return "Hello, " + principal.getName() + "!";
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/micronaut/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | micronaut:
2 | application:
3 | name: app
4 | security.token.jwt.enabled: true
5 | security.token.jwt.signatures.jwks.okta.url: https://dev-17700857.okta.com/oauth2/default/v1/keys
6 | netty:
7 | default:
8 | allocator:
9 | max-order: 3
10 |
--------------------------------------------------------------------------------
/micronaut/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 |
7 |
8 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/micronaut/src/test/java/com/okta/rest/AppTest.java:
--------------------------------------------------------------------------------
1 | package com.okta.rest;
2 |
3 | import io.micronaut.runtime.EmbeddedApplication;
4 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
5 | import org.junit.jupiter.api.Test;
6 | import org.junit.jupiter.api.Assertions;
7 |
8 | import jakarta.inject.Inject;
9 |
10 | @MicronautTest
11 | class AppTest {
12 |
13 | @Inject
14 | EmbeddedApplication> application;
15 |
16 | @Test
17 | void testItWorks() {
18 | Assertions.assertTrue(application.isRunning());
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/quarkus/.dockerignore:
--------------------------------------------------------------------------------
1 | *
2 | !target/*-runner
3 | !target/*-runner.jar
4 | !target/lib/*
5 | !target/quarkus-app/*
--------------------------------------------------------------------------------
/quarkus/.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 |
--------------------------------------------------------------------------------
/quarkus/.mvn/wrapper/.gitignore:
--------------------------------------------------------------------------------
1 | maven-wrapper.jar
2 |
--------------------------------------------------------------------------------
/quarkus/.mvn/wrapper/MavenWrapperDownloader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 |
20 | import java.net.*;
21 | import java.io.*;
22 | import java.nio.channels.*;
23 | import java.util.Properties;
24 |
25 | public class MavenWrapperDownloader
26 | {
27 | private static final String WRAPPER_VERSION = "3.1.1";
28 |
29 | /**
30 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
31 | */
32 | private static final String DEFAULT_DOWNLOAD_URL =
33 | "https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/" + WRAPPER_VERSION
34 | + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
35 |
36 | /**
37 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to use instead of the
38 | * default one.
39 | */
40 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = ".mvn/wrapper/maven-wrapper.properties";
41 |
42 | /**
43 | * Path where the maven-wrapper.jar will be saved to.
44 | */
45 | private static final String MAVEN_WRAPPER_JAR_PATH = ".mvn/wrapper/maven-wrapper.jar";
46 |
47 | /**
48 | * Name of the property which should be used to override the default download url for the wrapper.
49 | */
50 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
51 |
52 | public static void main( String args[] )
53 | {
54 | System.out.println( "- Downloader started" );
55 | File baseDirectory = new File( args[0] );
56 | System.out.println( "- Using base directory: " + baseDirectory.getAbsolutePath() );
57 |
58 | // If the maven-wrapper.properties exists, read it and check if it contains a custom
59 | // wrapperUrl parameter.
60 | File mavenWrapperPropertyFile = new File( baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH );
61 | String url = DEFAULT_DOWNLOAD_URL;
62 | if ( mavenWrapperPropertyFile.exists() )
63 | {
64 | FileInputStream mavenWrapperPropertyFileInputStream = null;
65 | try
66 | {
67 | mavenWrapperPropertyFileInputStream = new FileInputStream( mavenWrapperPropertyFile );
68 | Properties mavenWrapperProperties = new Properties();
69 | mavenWrapperProperties.load( mavenWrapperPropertyFileInputStream );
70 | url = mavenWrapperProperties.getProperty( PROPERTY_NAME_WRAPPER_URL, url );
71 | }
72 | catch ( IOException e )
73 | {
74 | System.out.println( "- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'" );
75 | }
76 | finally
77 | {
78 | try
79 | {
80 | if ( mavenWrapperPropertyFileInputStream != null )
81 | {
82 | mavenWrapperPropertyFileInputStream.close();
83 | }
84 | }
85 | catch ( IOException e )
86 | {
87 | // Ignore ...
88 | }
89 | }
90 | }
91 | System.out.println( "- Downloading from: " + url );
92 |
93 | File outputFile = new File( baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH );
94 | if ( !outputFile.getParentFile().exists() )
95 | {
96 | if ( !outputFile.getParentFile().mkdirs() )
97 | {
98 | System.out.println( "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath()
99 | + "'" );
100 | }
101 | }
102 | System.out.println( "- Downloading to: " + outputFile.getAbsolutePath() );
103 | try
104 | {
105 | downloadFileFromURL( url, outputFile );
106 | System.out.println( "Done" );
107 | System.exit( 0 );
108 | }
109 | catch ( Throwable e )
110 | {
111 | System.out.println( "- Error downloading" );
112 | e.printStackTrace();
113 | System.exit( 1 );
114 | }
115 | }
116 |
117 | private static void downloadFileFromURL( String urlString, File destination )
118 | throws Exception
119 | {
120 | if ( System.getenv( "MVNW_USERNAME" ) != null && System.getenv( "MVNW_PASSWORD" ) != null )
121 | {
122 | String username = System.getenv( "MVNW_USERNAME" );
123 | char[] password = System.getenv( "MVNW_PASSWORD" ).toCharArray();
124 | Authenticator.setDefault( new Authenticator()
125 | {
126 | @Override
127 | protected PasswordAuthentication getPasswordAuthentication()
128 | {
129 | return new PasswordAuthentication( username, password );
130 | }
131 | } );
132 | }
133 | URL website = new URL( urlString );
134 | ReadableByteChannel rbc;
135 | rbc = Channels.newChannel( website.openStream() );
136 | FileOutputStream fos = new FileOutputStream( destination );
137 | fos.getChannel().transferFrom( rbc, 0, Long.MAX_VALUE );
138 | fos.close();
139 | rbc.close();
140 | }
141 |
142 | }
143 |
--------------------------------------------------------------------------------
/quarkus/.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.8.6/apache-maven-3.8.6-bin.zip
18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
19 |
--------------------------------------------------------------------------------
/quarkus/README.md:
--------------------------------------------------------------------------------
1 | # quarkus Project
2 |
3 | This project uses Quarkus, the Supersonic Subatomic Java Framework.
4 |
5 | If you want to learn more about Quarkus, please visit its website: https://quarkus.io/ .
6 |
7 | ## Running the application in dev mode
8 |
9 | You can run your application in dev mode that enables live coding using:
10 | ```shell script
11 | ./mvnw compile quarkus:dev
12 | ```
13 |
14 | > **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/.
15 |
16 | ## Packaging and running the application
17 |
18 | The application can be packaged using:
19 | ```shell script
20 | ./mvnw package
21 | ```
22 | It produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory.
23 | Be aware that it’s not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory.
24 |
25 | The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`.
26 |
27 | If you want to build an _über-jar_, execute the following command:
28 | ```shell script
29 | ./mvnw package -Dquarkus.package.type=uber-jar
30 | ```
31 |
32 | The application, packaged as an _über-jar_, is now runnable using `java -jar target/*-runner.jar`.
33 |
34 | ## Creating a native executable
35 |
36 | You can create a native executable using:
37 | ```shell script
38 | ./mvnw package -Pnative
39 | ```
40 |
41 | Or, if you don't have GraalVM installed, you can run the native executable build in a container using:
42 | ```shell script
43 | ./mvnw package -Pnative -Dquarkus.native.container-build=true
44 | ```
45 |
46 | You can then execute your native executable with: `./target/quarkus-1.0.0-SNAPSHOT-runner`
47 |
48 | If you want to learn more about building native executables, please consult https://quarkus.io/guides/maven-tooling.
49 |
50 | ## Related Guides
51 |
52 | - SmallRye JWT ([guide](https://quarkus.io/guides/security-jwt)): Secure your applications with JSON Web Token
53 | - RESTEasy Reactive ([guide](https://quarkus.io/guides/resteasy-reactive)): A JAX-RS implementation utilizing build time processing and Vert.x. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it.
54 |
55 | ## Provided Code
56 |
57 | ### RESTEasy Reactive
58 |
59 | Easily start your Reactive RESTful Web Services
60 |
61 | [Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources)
62 |
--------------------------------------------------------------------------------
/quarkus/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # https://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /usr/local/etc/mavenrc ] ; then
40 | . /usr/local/etc/mavenrc
41 | fi
42 |
43 | if [ -f /etc/mavenrc ] ; then
44 | . /etc/mavenrc
45 | fi
46 |
47 | if [ -f "$HOME/.mavenrc" ] ; then
48 | . "$HOME/.mavenrc"
49 | fi
50 |
51 | fi
52 |
53 | # OS specific support. $var _must_ be set to either true or false.
54 | cygwin=false;
55 | darwin=false;
56 | mingw=false
57 | case "`uname`" in
58 | CYGWIN*) cygwin=true ;;
59 | MINGW*) mingw=true;;
60 | Darwin*) darwin=true
61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
63 | if [ -z "$JAVA_HOME" ]; then
64 | if [ -x "/usr/libexec/java_home" ]; then
65 | export JAVA_HOME="`/usr/libexec/java_home`"
66 | else
67 | export JAVA_HOME="/Library/Java/Home"
68 | fi
69 | fi
70 | ;;
71 | esac
72 |
73 | if [ -z "$JAVA_HOME" ] ; then
74 | if [ -r /etc/gentoo-release ] ; then
75 | JAVA_HOME=`java-config --jre-home`
76 | fi
77 | fi
78 |
79 | if [ -z "$M2_HOME" ] ; then
80 | ## resolve links - $0 may be a link to maven's home
81 | PRG="$0"
82 |
83 | # need this for relative symlinks
84 | while [ -h "$PRG" ] ; do
85 | ls=`ls -ld "$PRG"`
86 | link=`expr "$ls" : '.*-> \(.*\)$'`
87 | if expr "$link" : '/.*' > /dev/null; then
88 | PRG="$link"
89 | else
90 | PRG="`dirname "$PRG"`/$link"
91 | fi
92 | done
93 |
94 | saveddir=`pwd`
95 |
96 | M2_HOME=`dirname "$PRG"`/..
97 |
98 | # make it fully qualified
99 | M2_HOME=`cd "$M2_HOME" && pwd`
100 |
101 | cd "$saveddir"
102 | # echo Using m2 at $M2_HOME
103 | fi
104 |
105 | # For Cygwin, ensure paths are in UNIX format before anything is touched
106 | if $cygwin ; then
107 | [ -n "$M2_HOME" ] &&
108 | M2_HOME=`cygpath --unix "$M2_HOME"`
109 | [ -n "$JAVA_HOME" ] &&
110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
111 | [ -n "$CLASSPATH" ] &&
112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
113 | fi
114 |
115 | # For Mingw, ensure paths are in UNIX format before anything is touched
116 | if $mingw ; then
117 | [ -n "$M2_HOME" ] &&
118 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
119 | [ -n "$JAVA_HOME" ] &&
120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
121 | fi
122 |
123 | if [ -z "$JAVA_HOME" ]; then
124 | javaExecutable="`which javac`"
125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
126 | # readlink(1) is not available as standard on Solaris 10.
127 | readLink=`which readlink`
128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
129 | if $darwin ; then
130 | javaHome="`dirname \"$javaExecutable\"`"
131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
132 | else
133 | javaExecutable="`readlink -f \"$javaExecutable\"`"
134 | fi
135 | javaHome="`dirname \"$javaExecutable\"`"
136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
137 | JAVA_HOME="$javaHome"
138 | export JAVA_HOME
139 | fi
140 | fi
141 | fi
142 |
143 | if [ -z "$JAVACMD" ] ; then
144 | if [ -n "$JAVA_HOME" ] ; then
145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
146 | # IBM's JDK on AIX uses strange locations for the executables
147 | JAVACMD="$JAVA_HOME/jre/sh/java"
148 | else
149 | JAVACMD="$JAVA_HOME/bin/java"
150 | fi
151 | else
152 | JAVACMD="`\\unset -f command; \\command -v java`"
153 | fi
154 | fi
155 |
156 | if [ ! -x "$JAVACMD" ] ; then
157 | echo "Error: JAVA_HOME is not defined correctly." >&2
158 | echo " We cannot execute $JAVACMD" >&2
159 | exit 1
160 | fi
161 |
162 | if [ -z "$JAVA_HOME" ] ; then
163 | echo "Warning: JAVA_HOME environment variable is not set."
164 | fi
165 |
166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
167 |
168 | # traverses directory structure from process work directory to filesystem root
169 | # first directory with .mvn subdirectory is considered project base directory
170 | find_maven_basedir() {
171 |
172 | if [ -z "$1" ]
173 | then
174 | echo "Path not specified to find_maven_basedir"
175 | return 1
176 | fi
177 |
178 | basedir="$1"
179 | wdir="$1"
180 | while [ "$wdir" != '/' ] ; do
181 | if [ -d "$wdir"/.mvn ] ; then
182 | basedir=$wdir
183 | break
184 | fi
185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
186 | if [ -d "${wdir}" ]; then
187 | wdir=`cd "$wdir/.."; pwd`
188 | fi
189 | # end of workaround
190 | done
191 | echo "${basedir}"
192 | }
193 |
194 | # concatenates all lines of a file
195 | concat_lines() {
196 | if [ -f "$1" ]; then
197 | echo "$(tr -s '\n' ' ' < "$1")"
198 | fi
199 | }
200 |
201 | BASE_DIR=`find_maven_basedir "$(pwd)"`
202 | if [ -z "$BASE_DIR" ]; then
203 | exit 1;
204 | fi
205 |
206 | ##########################################################################################
207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
208 | # This allows using the maven wrapper in projects that prohibit checking in binary data.
209 | ##########################################################################################
210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
211 | if [ "$MVNW_VERBOSE" = true ]; then
212 | echo "Found .mvn/wrapper/maven-wrapper.jar"
213 | fi
214 | else
215 | if [ "$MVNW_VERBOSE" = true ]; then
216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
217 | fi
218 | if [ -n "$MVNW_REPOURL" ]; then
219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
220 | else
221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
222 | fi
223 | while IFS="=" read key value; do
224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
225 | esac
226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
227 | if [ "$MVNW_VERBOSE" = true ]; then
228 | echo "Downloading from: $jarUrl"
229 | fi
230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
231 | if $cygwin; then
232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
233 | fi
234 |
235 | if command -v wget > /dev/null; then
236 | if [ "$MVNW_VERBOSE" = true ]; then
237 | echo "Found wget ... using wget"
238 | fi
239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
241 | else
242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
243 | fi
244 | elif command -v curl > /dev/null; then
245 | if [ "$MVNW_VERBOSE" = true ]; then
246 | echo "Found curl ... using curl"
247 | fi
248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
249 | curl -o "$wrapperJarPath" "$jarUrl" -f
250 | else
251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
252 | fi
253 |
254 | else
255 | if [ "$MVNW_VERBOSE" = true ]; then
256 | echo "Falling back to using Java to download"
257 | fi
258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
259 | # For Cygwin, switch paths to Windows format before running javac
260 | if $cygwin; then
261 | javaClass=`cygpath --path --windows "$javaClass"`
262 | fi
263 | if [ -e "$javaClass" ]; then
264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
265 | if [ "$MVNW_VERBOSE" = true ]; then
266 | echo " - Compiling MavenWrapperDownloader.java ..."
267 | fi
268 | # Compiling the Java class
269 | ("$JAVA_HOME/bin/javac" "$javaClass")
270 | fi
271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
272 | # Running the downloader
273 | if [ "$MVNW_VERBOSE" = true ]; then
274 | echo " - Running MavenWrapperDownloader.java ..."
275 | fi
276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
277 | fi
278 | fi
279 | fi
280 | fi
281 | ##########################################################################################
282 | # End of extension
283 | ##########################################################################################
284 |
285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
286 | if [ "$MVNW_VERBOSE" = true ]; then
287 | echo $MAVEN_PROJECTBASEDIR
288 | fi
289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
290 |
291 | # For Cygwin, switch paths to Windows format before running java
292 | if $cygwin; then
293 | [ -n "$M2_HOME" ] &&
294 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
295 | [ -n "$JAVA_HOME" ] &&
296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
297 | [ -n "$CLASSPATH" ] &&
298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
299 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
301 | fi
302 |
303 | # Provide a "standardized" way to retrieve the CLI args that will
304 | # work with both Windows and non-Windows executions.
305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
306 | export MAVEN_CMD_LINE_ARGS
307 |
308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
309 |
310 | exec "$JAVACMD" \
311 | $MAVEN_OPTS \
312 | $MAVEN_DEBUG_OPTS \
313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
314 | "-Dmaven.home=${M2_HOME}" \
315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
317 |
--------------------------------------------------------------------------------
/quarkus/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM https://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM set title of command window
39 | title %0
40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
42 |
43 | @REM set %HOME% to equivalent of $HOME
44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
45 |
46 | @REM Execute a user defined script before this one
47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
51 | :skipRcPre
52 |
53 | @setlocal
54 |
55 | set ERROR_CODE=0
56 |
57 | @REM To isolate internal variables from possible post scripts, we use another setlocal
58 | @setlocal
59 |
60 | @REM ==== START VALIDATION ====
61 | if not "%JAVA_HOME%" == "" goto OkJHome
62 |
63 | echo.
64 | echo Error: JAVA_HOME not found in your environment. >&2
65 | echo Please set the JAVA_HOME variable in your environment to match the >&2
66 | echo location of your Java installation. >&2
67 | echo.
68 | goto error
69 |
70 | :OkJHome
71 | if exist "%JAVA_HOME%\bin\java.exe" goto init
72 |
73 | echo.
74 | echo Error: JAVA_HOME is set to an invalid directory. >&2
75 | echo JAVA_HOME = "%JAVA_HOME%" >&2
76 | echo Please set the JAVA_HOME variable in your environment to match the >&2
77 | echo location of your Java installation. >&2
78 | echo.
79 | goto error
80 |
81 | @REM ==== END VALIDATION ====
82 |
83 | :init
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
122 |
123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
124 |
125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
127 | )
128 |
129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data.
131 | if exist %WRAPPER_JAR% (
132 | if "%MVNW_VERBOSE%" == "true" (
133 | echo Found %WRAPPER_JAR%
134 | )
135 | ) else (
136 | if not "%MVNW_REPOURL%" == "" (
137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
138 | )
139 | if "%MVNW_VERBOSE%" == "true" (
140 | echo Couldn't find %WRAPPER_JAR%, downloading it ...
141 | echo Downloading from: %DOWNLOAD_URL%
142 | )
143 |
144 | powershell -Command "&{"^
145 | "$webclient = new-object System.Net.WebClient;"^
146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
148 | "}"^
149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
150 | "}"
151 | if "%MVNW_VERBOSE%" == "true" (
152 | echo Finished downloading %WRAPPER_JAR%
153 | )
154 | )
155 | @REM End of extension
156 |
157 | @REM Provide a "standardized" way to retrieve the CLI args that will
158 | @REM work with both Windows and non-Windows executions.
159 | set MAVEN_CMD_LINE_ARGS=%*
160 |
161 | %MAVEN_JAVA_EXE% ^
162 | %JVM_CONFIG_MAVEN_PROPS% ^
163 | %MAVEN_OPTS% ^
164 | %MAVEN_DEBUG_OPTS% ^
165 | -classpath %WRAPPER_JAR% ^
166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
168 | if ERRORLEVEL 1 goto error
169 | goto end
170 |
171 | :error
172 | set ERROR_CODE=1
173 |
174 | :end
175 | @endlocal & set ERROR_CODE=%ERROR_CODE%
176 |
177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
181 | :skipRcPost
182 |
183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause
185 |
186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
187 |
188 | cmd /C exit /B %ERROR_CODE%
189 |
--------------------------------------------------------------------------------
/quarkus/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.okta.rest
6 | quarkus
7 | 1.0.0-SNAPSHOT
8 |
9 | 3.10.1
10 | 17
11 | UTF-8
12 | UTF-8
13 | quarkus-bom
14 | io.quarkus.platform
15 | 2.13.3.Final
16 | true
17 | 3.0.0-M7
18 |
19 |
20 |
21 |
22 | ${quarkus.platform.group-id}
23 | ${quarkus.platform.artifact-id}
24 | ${quarkus.platform.version}
25 | pom
26 | import
27 |
28 |
29 |
30 |
31 |
32 | io.quarkus
33 | quarkus-smallrye-jwt
34 |
35 |
36 | io.quarkus
37 | quarkus-resteasy-reactive
38 |
39 |
40 | io.quarkus
41 | quarkus-arc
42 |
43 |
44 | io.quarkus
45 | quarkus-junit5
46 | test
47 |
48 |
49 | io.rest-assured
50 | rest-assured
51 | test
52 |
53 |
54 |
55 |
56 |
57 | ${quarkus.platform.group-id}
58 | quarkus-maven-plugin
59 | ${quarkus.platform.version}
60 | true
61 |
62 |
63 |
64 | build
65 | generate-code
66 | generate-code-tests
67 |
68 |
69 |
70 |
71 |
72 | maven-compiler-plugin
73 | ${compiler-plugin.version}
74 |
75 |
76 | -parameters
77 |
78 |
79 |
80 |
81 | maven-surefire-plugin
82 | ${surefire-plugin.version}
83 |
84 |
85 | org.jboss.logmanager.LogManager
86 | ${maven.home}
87 |
88 |
89 |
90 |
91 | maven-failsafe-plugin
92 | ${surefire-plugin.version}
93 |
94 |
95 |
96 | integration-test
97 | verify
98 |
99 |
100 |
101 | ${project.build.directory}/${project.build.finalName}-runner
102 | org.jboss.logmanager.LogManager
103 | ${maven.home}
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | native
114 |
115 |
116 | native
117 |
118 |
119 |
120 | false
121 | native
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/quarkus/src/main/docker/Dockerfile.jvm:
--------------------------------------------------------------------------------
1 | ####
2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
3 | #
4 | # Before building the container image run:
5 | #
6 | # ./mvnw package
7 | #
8 | # Then, build the image with:
9 | #
10 | # docker build -f src/main/docker/Dockerfile.jvm -t quarkus/quarkus-jvm .
11 | #
12 | # Then run the container using:
13 | #
14 | # docker run -i --rm -p 8080:8080 quarkus/quarkus-jvm
15 | #
16 | # If you want to include the debug port into your docker image
17 | # you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005
18 | #
19 | # Then run the container using :
20 | #
21 | # docker run -i --rm -p 8080:8080 quarkus/quarkus-jvm
22 | #
23 | # This image uses the `run-java.sh` script to run the application.
24 | # This scripts computes the command line to execute your Java application, and
25 | # includes memory/GC tuning.
26 | # You can configure the behavior using the following environment properties:
27 | # - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
28 | # - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
29 | # in JAVA_OPTS (example: "-Dsome.property=foo")
30 | # - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
31 | # used to calculate a default maximal heap memory based on a containers restriction.
32 | # If used in a container without any memory constraints for the container then this
33 | # option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
34 | # of the container available memory as set here. The default is `50` which means 50%
35 | # of the available memory is used as an upper boundary. You can skip this mechanism by
36 | # setting this value to `0` in which case no `-Xmx` option is added.
37 | # - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
38 | # is used to calculate a default initial heap memory based on the maximum heap memory.
39 | # If used in a container without any memory constraints for the container then this
40 | # option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
41 | # of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
42 | # is used as the initial heap size. You can skip this mechanism by setting this value
43 | # to `0` in which case no `-Xms` option is added (example: "25")
44 | # - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
45 | # This is used to calculate the maximum value of the initial heap memory. If used in
46 | # a container without any memory constraints for the container then this option has
47 | # no effect. If there is a memory constraint then `-Xms` is limited to the value set
48 | # here. The default is 4096MB which means the calculated value of `-Xms` never will
49 | # be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
50 | # - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
51 | # when things are happening. This option, if set to true, will set
52 | # `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
53 | # - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
54 | # true").
55 | # - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
56 | # - CONTAINER_CORE_LIMIT: A calculated core limit as described in
57 | # https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
58 | # - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
59 | # - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
60 | # (example: "20")
61 | # - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
62 | # (example: "40")
63 | # - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
64 | # (example: "4")
65 | # - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
66 | # previous GC times. (example: "90")
67 | # - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
68 | # - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
69 | # - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
70 | # contain the necessary JRE command-line options to specify the required GC, which
71 | # will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
72 | # - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
73 | # - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
74 | # - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
75 | # accessed directly. (example: "foo.example.com,bar.example.com")
76 | #
77 | ###
78 | FROM registry.access.redhat.com/ubi8/openjdk-17:1.14
79 |
80 | ENV LANGUAGE='en_US:en'
81 |
82 |
83 | # We make four distinct layers so if there are application changes the library layers can be re-used
84 | COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/
85 | COPY --chown=185 target/quarkus-app/*.jar /deployments/
86 | COPY --chown=185 target/quarkus-app/app/ /deployments/app/
87 | COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/
88 |
89 | EXPOSE 8080
90 | USER 185
91 | ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
92 | ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
93 |
94 |
--------------------------------------------------------------------------------
/quarkus/src/main/docker/Dockerfile.legacy-jar:
--------------------------------------------------------------------------------
1 | ####
2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
3 | #
4 | # Before building the container image run:
5 | #
6 | # ./mvnw package -Dquarkus.package.type=legacy-jar
7 | #
8 | # Then, build the image with:
9 | #
10 | # docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/quarkus-legacy-jar .
11 | #
12 | # Then run the container using:
13 | #
14 | # docker run -i --rm -p 8080:8080 quarkus/quarkus-legacy-jar
15 | #
16 | # If you want to include the debug port into your docker image
17 | # you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5005
18 | #
19 | # Then run the container using :
20 | #
21 | # docker run -i --rm -p 8080:8080 quarkus/quarkus-legacy-jar
22 | #
23 | # This image uses the `run-java.sh` script to run the application.
24 | # This scripts computes the command line to execute your Java application, and
25 | # includes memory/GC tuning.
26 | # You can configure the behavior using the following environment properties:
27 | # - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
28 | # - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
29 | # in JAVA_OPTS (example: "-Dsome.property=foo")
30 | # - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
31 | # used to calculate a default maximal heap memory based on a containers restriction.
32 | # If used in a container without any memory constraints for the container then this
33 | # option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
34 | # of the container available memory as set here. The default is `50` which means 50%
35 | # of the available memory is used as an upper boundary. You can skip this mechanism by
36 | # setting this value to `0` in which case no `-Xmx` option is added.
37 | # - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
38 | # is used to calculate a default initial heap memory based on the maximum heap memory.
39 | # If used in a container without any memory constraints for the container then this
40 | # option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
41 | # of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
42 | # is used as the initial heap size. You can skip this mechanism by setting this value
43 | # to `0` in which case no `-Xms` option is added (example: "25")
44 | # - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
45 | # This is used to calculate the maximum value of the initial heap memory. If used in
46 | # a container without any memory constraints for the container then this option has
47 | # no effect. If there is a memory constraint then `-Xms` is limited to the value set
48 | # here. The default is 4096MB which means the calculated value of `-Xms` never will
49 | # be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
50 | # - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
51 | # when things are happening. This option, if set to true, will set
52 | # `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
53 | # - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
54 | # true").
55 | # - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
56 | # - CONTAINER_CORE_LIMIT: A calculated core limit as described in
57 | # https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
58 | # - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
59 | # - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
60 | # (example: "20")
61 | # - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
62 | # (example: "40")
63 | # - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
64 | # (example: "4")
65 | # - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
66 | # previous GC times. (example: "90")
67 | # - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
68 | # - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
69 | # - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
70 | # contain the necessary JRE command-line options to specify the required GC, which
71 | # will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
72 | # - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
73 | # - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
74 | # - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
75 | # accessed directly. (example: "foo.example.com,bar.example.com")
76 | #
77 | ###
78 | FROM registry.access.redhat.com/ubi8/openjdk-17:1.14
79 |
80 | ENV LANGUAGE='en_US:en'
81 |
82 |
83 | COPY target/lib/* /deployments/lib/
84 | COPY target/*-runner.jar /deployments/quarkus-run.jar
85 |
86 | EXPOSE 8080
87 | USER 185
88 | ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
89 | ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
90 |
--------------------------------------------------------------------------------
/quarkus/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 -Pnative
7 | #
8 | # Then, build the image with:
9 | #
10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus .
11 | #
12 | # Then run the container using:
13 | #
14 | # docker run -i --rm -p 8080:8080 quarkus/quarkus
15 | #
16 | ###
17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6
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 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
28 |
--------------------------------------------------------------------------------
/quarkus/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 -Pnative
10 | #
11 | # Then, build the image with:
12 | #
13 | # docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/quarkus .
14 | #
15 | # Then run the container using:
16 | #
17 | # docker run -i --rm -p 8080:8080 quarkus/quarkus
18 | #
19 | ###
20 | FROM quay.io/quarkus/quarkus-micro-image:1.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 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
31 |
--------------------------------------------------------------------------------
/quarkus/src/main/java/com/okta/rest/quarkus/HelloResource.java:
--------------------------------------------------------------------------------
1 | package com.okta.rest.quarkus;
2 |
3 | import io.quarkus.security.Authenticated;
4 |
5 | import javax.ws.rs.GET;
6 | import javax.ws.rs.Path;
7 | import javax.ws.rs.Produces;
8 | import javax.ws.rs.core.Context;
9 | import javax.ws.rs.core.MediaType;
10 | import javax.ws.rs.core.SecurityContext;
11 | import java.security.Principal;
12 |
13 | @Path("/hello")
14 | public class HelloResource {
15 |
16 | @GET
17 | @Authenticated
18 | @Produces(MediaType.TEXT_PLAIN)
19 | public String hello(@Context SecurityContext context) {
20 | Principal userPrincipal = context.getUserPrincipal();
21 | return "Hello, " + userPrincipal.getName() + "!";
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/quarkus/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | mp.jwt.verify.issuer: https://dev-17700857.okta.com/oauth2/default
2 | mp.jwt.verify.publickey.location: ${mp.jwt.verify.issuer}/v1/keys
3 |
--------------------------------------------------------------------------------
/quarkus/src/test/java/com/okta/rest/quarkus/HelloResourceIT.java:
--------------------------------------------------------------------------------
1 | package com.okta.rest.quarkus;
2 |
3 | import io.quarkus.test.junit.QuarkusIntegrationTest;
4 |
5 | @QuarkusIntegrationTest
6 | public class HelloResourceIT extends HelloResourceTest {
7 | // Execute the same tests but in packaged mode.
8 | }
9 |
--------------------------------------------------------------------------------
/quarkus/src/test/java/com/okta/rest/quarkus/HelloResourceTest.java:
--------------------------------------------------------------------------------
1 | package com.okta.rest.quarkus;
2 |
3 | import io.quarkus.test.junit.QuarkusTest;
4 | import org.junit.jupiter.api.Test;
5 |
6 | import static io.restassured.RestAssured.given;
7 |
8 | @QuarkusTest
9 | public class HelloResourceTest {
10 |
11 | @Test
12 | public void testHelloEndpoint() {
13 | given()
14 | .when().get("/hello")
15 | .then()
16 | .statusCode(401);
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/spring-boot/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 | !**/src/main/**/target/
4 | !**/src/test/**/target/
5 |
6 | ### STS ###
7 | .apt_generated
8 | .classpath
9 | .factorypath
10 | .project
11 | .settings
12 | .springBeans
13 | .sts4-cache
14 |
15 | ### IntelliJ IDEA ###
16 | .idea
17 | *.iws
18 | *.iml
19 | *.ipr
20 |
21 | ### NetBeans ###
22 | /nbproject/private/
23 | /nbbuild/
24 | /dist/
25 | /nbdist/
26 | /.nb-gradle/
27 | build/
28 | !**/src/main/**/build/
29 | !**/src/test/**/build/
30 |
31 | ### VS Code ###
32 | .vscode/
33 |
--------------------------------------------------------------------------------
/spring-boot/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oktadev/native-java-examples/2c9d53a25150a0a9febcbfd9e9edf08186c6ee02/spring-boot/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/spring-boot/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
3 |
--------------------------------------------------------------------------------
/spring-boot/HELP.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | ### Reference Documentation
4 | For further reference, please consider the following sections:
5 |
6 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
7 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.0.0-RC1/maven-plugin/reference/html/)
8 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.0.0-RC1/maven-plugin/reference/html/#build-image)
9 | * [GraalVM Native Image Support](https://docs.spring.io/spring-boot/docs/3.0.0-RC1/reference/html/native-image.html#native-image)
10 | * [Spring Web](https://docs.spring.io/spring-boot/docs/3.0.0-RC1/reference/htmlsingle/#web)
11 | * [OAuth2 Resource Server](https://docs.spring.io/spring-boot/docs/3.0.0-RC1/reference/htmlsingle/#web.security.oauth2.server)
12 |
13 | ### Guides
14 | The following guides illustrate how to use some features concretely:
15 |
16 | * [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
17 | * [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
18 | * [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
19 |
20 | ### Additional Links
21 | These additional references should also help you:
22 |
23 | * [Configure AOT settings in Build Plugin](https://docs.spring.io/spring-boot/docs/3.0.0-RC1/maven-plugin/reference/htmlsingle/#aot)
24 |
25 | ## GraalVM Native Support
26 |
27 | This project has been configured to let you generate either a lightweight container or a native executable.
28 | It is also possible to run your tests in a native image.
29 |
30 | ### Lightweight Container with Cloud Native Buildpacks
31 | If you're already familiar with Spring Boot container images support, this is the easiest way to get started.
32 | Docker should be installed and configured on your machine prior to creating the image.
33 |
34 | To create the image, run the following goal:
35 |
36 | ```
37 | $ ./mvnw spring-boot:build-image -Pnative
38 | ```
39 |
40 | Then, you can run the app like any other container:
41 |
42 | ```
43 | $ docker run --rm -p 8080:8080 demo:0.0.1-SNAPSHOT
44 | ```
45 |
46 | ### Executable with Native Build Tools
47 | Use this option if you want to explore more options such as running your tests in a native image.
48 | The GraalVM `native-image` compiler should be installed and configured on your machine.
49 |
50 | NOTE: GraalVM 22.3+ is required.
51 |
52 | To create the executable, run the following goal:
53 |
54 | ```
55 | $ ./mvnw native:compile -Pnative
56 | ```
57 |
58 | Then, you can run the app as follows:
59 | ```
60 | $ target/demo
61 | ```
62 |
63 | You can also run your existing tests suite in a native image.
64 | This is an efficient way to validate the compatibility of your application.
65 |
66 | To run your existing tests in a native image, run the following goal:
67 |
68 | ```
69 | $ ./mvnw test -PnativeTest
70 | ```
71 |
72 |
--------------------------------------------------------------------------------
/spring-boot/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # https://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /usr/local/etc/mavenrc ] ; then
40 | . /usr/local/etc/mavenrc
41 | fi
42 |
43 | if [ -f /etc/mavenrc ] ; then
44 | . /etc/mavenrc
45 | fi
46 |
47 | if [ -f "$HOME/.mavenrc" ] ; then
48 | . "$HOME/.mavenrc"
49 | fi
50 |
51 | fi
52 |
53 | # OS specific support. $var _must_ be set to either true or false.
54 | cygwin=false;
55 | darwin=false;
56 | mingw=false
57 | case "`uname`" in
58 | CYGWIN*) cygwin=true ;;
59 | MINGW*) mingw=true;;
60 | Darwin*) darwin=true
61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
63 | if [ -z "$JAVA_HOME" ]; then
64 | if [ -x "/usr/libexec/java_home" ]; then
65 | export JAVA_HOME="`/usr/libexec/java_home`"
66 | else
67 | export JAVA_HOME="/Library/Java/Home"
68 | fi
69 | fi
70 | ;;
71 | esac
72 |
73 | if [ -z "$JAVA_HOME" ] ; then
74 | if [ -r /etc/gentoo-release ] ; then
75 | JAVA_HOME=`java-config --jre-home`
76 | fi
77 | fi
78 |
79 | if [ -z "$M2_HOME" ] ; then
80 | ## resolve links - $0 may be a link to maven's home
81 | PRG="$0"
82 |
83 | # need this for relative symlinks
84 | while [ -h "$PRG" ] ; do
85 | ls=`ls -ld "$PRG"`
86 | link=`expr "$ls" : '.*-> \(.*\)$'`
87 | if expr "$link" : '/.*' > /dev/null; then
88 | PRG="$link"
89 | else
90 | PRG="`dirname "$PRG"`/$link"
91 | fi
92 | done
93 |
94 | saveddir=`pwd`
95 |
96 | M2_HOME=`dirname "$PRG"`/..
97 |
98 | # make it fully qualified
99 | M2_HOME=`cd "$M2_HOME" && pwd`
100 |
101 | cd "$saveddir"
102 | # echo Using m2 at $M2_HOME
103 | fi
104 |
105 | # For Cygwin, ensure paths are in UNIX format before anything is touched
106 | if $cygwin ; then
107 | [ -n "$M2_HOME" ] &&
108 | M2_HOME=`cygpath --unix "$M2_HOME"`
109 | [ -n "$JAVA_HOME" ] &&
110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
111 | [ -n "$CLASSPATH" ] &&
112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
113 | fi
114 |
115 | # For Mingw, ensure paths are in UNIX format before anything is touched
116 | if $mingw ; then
117 | [ -n "$M2_HOME" ] &&
118 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
119 | [ -n "$JAVA_HOME" ] &&
120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
121 | fi
122 |
123 | if [ -z "$JAVA_HOME" ]; then
124 | javaExecutable="`which javac`"
125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
126 | # readlink(1) is not available as standard on Solaris 10.
127 | readLink=`which readlink`
128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
129 | if $darwin ; then
130 | javaHome="`dirname \"$javaExecutable\"`"
131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
132 | else
133 | javaExecutable="`readlink -f \"$javaExecutable\"`"
134 | fi
135 | javaHome="`dirname \"$javaExecutable\"`"
136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
137 | JAVA_HOME="$javaHome"
138 | export JAVA_HOME
139 | fi
140 | fi
141 | fi
142 |
143 | if [ -z "$JAVACMD" ] ; then
144 | if [ -n "$JAVA_HOME" ] ; then
145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
146 | # IBM's JDK on AIX uses strange locations for the executables
147 | JAVACMD="$JAVA_HOME/jre/sh/java"
148 | else
149 | JAVACMD="$JAVA_HOME/bin/java"
150 | fi
151 | else
152 | JAVACMD="`\\unset -f command; \\command -v java`"
153 | fi
154 | fi
155 |
156 | if [ ! -x "$JAVACMD" ] ; then
157 | echo "Error: JAVA_HOME is not defined correctly." >&2
158 | echo " We cannot execute $JAVACMD" >&2
159 | exit 1
160 | fi
161 |
162 | if [ -z "$JAVA_HOME" ] ; then
163 | echo "Warning: JAVA_HOME environment variable is not set."
164 | fi
165 |
166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
167 |
168 | # traverses directory structure from process work directory to filesystem root
169 | # first directory with .mvn subdirectory is considered project base directory
170 | find_maven_basedir() {
171 |
172 | if [ -z "$1" ]
173 | then
174 | echo "Path not specified to find_maven_basedir"
175 | return 1
176 | fi
177 |
178 | basedir="$1"
179 | wdir="$1"
180 | while [ "$wdir" != '/' ] ; do
181 | if [ -d "$wdir"/.mvn ] ; then
182 | basedir=$wdir
183 | break
184 | fi
185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
186 | if [ -d "${wdir}" ]; then
187 | wdir=`cd "$wdir/.."; pwd`
188 | fi
189 | # end of workaround
190 | done
191 | echo "${basedir}"
192 | }
193 |
194 | # concatenates all lines of a file
195 | concat_lines() {
196 | if [ -f "$1" ]; then
197 | echo "$(tr -s '\n' ' ' < "$1")"
198 | fi
199 | }
200 |
201 | BASE_DIR=`find_maven_basedir "$(pwd)"`
202 | if [ -z "$BASE_DIR" ]; then
203 | exit 1;
204 | fi
205 |
206 | ##########################################################################################
207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
208 | # This allows using the maven wrapper in projects that prohibit checking in binary data.
209 | ##########################################################################################
210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
211 | if [ "$MVNW_VERBOSE" = true ]; then
212 | echo "Found .mvn/wrapper/maven-wrapper.jar"
213 | fi
214 | else
215 | if [ "$MVNW_VERBOSE" = true ]; then
216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
217 | fi
218 | if [ -n "$MVNW_REPOURL" ]; then
219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
220 | else
221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
222 | fi
223 | while IFS="=" read key value; do
224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
225 | esac
226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
227 | if [ "$MVNW_VERBOSE" = true ]; then
228 | echo "Downloading from: $jarUrl"
229 | fi
230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
231 | if $cygwin; then
232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
233 | fi
234 |
235 | if command -v wget > /dev/null; then
236 | if [ "$MVNW_VERBOSE" = true ]; then
237 | echo "Found wget ... using wget"
238 | fi
239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
241 | else
242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
243 | fi
244 | elif command -v curl > /dev/null; then
245 | if [ "$MVNW_VERBOSE" = true ]; then
246 | echo "Found curl ... using curl"
247 | fi
248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
249 | curl -o "$wrapperJarPath" "$jarUrl" -f
250 | else
251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
252 | fi
253 |
254 | else
255 | if [ "$MVNW_VERBOSE" = true ]; then
256 | echo "Falling back to using Java to download"
257 | fi
258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
259 | # For Cygwin, switch paths to Windows format before running javac
260 | if $cygwin; then
261 | javaClass=`cygpath --path --windows "$javaClass"`
262 | fi
263 | if [ -e "$javaClass" ]; then
264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
265 | if [ "$MVNW_VERBOSE" = true ]; then
266 | echo " - Compiling MavenWrapperDownloader.java ..."
267 | fi
268 | # Compiling the Java class
269 | ("$JAVA_HOME/bin/javac" "$javaClass")
270 | fi
271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
272 | # Running the downloader
273 | if [ "$MVNW_VERBOSE" = true ]; then
274 | echo " - Running MavenWrapperDownloader.java ..."
275 | fi
276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
277 | fi
278 | fi
279 | fi
280 | fi
281 | ##########################################################################################
282 | # End of extension
283 | ##########################################################################################
284 |
285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
286 | if [ "$MVNW_VERBOSE" = true ]; then
287 | echo $MAVEN_PROJECTBASEDIR
288 | fi
289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
290 |
291 | # For Cygwin, switch paths to Windows format before running java
292 | if $cygwin; then
293 | [ -n "$M2_HOME" ] &&
294 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
295 | [ -n "$JAVA_HOME" ] &&
296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
297 | [ -n "$CLASSPATH" ] &&
298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
299 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
301 | fi
302 |
303 | # Provide a "standardized" way to retrieve the CLI args that will
304 | # work with both Windows and non-Windows executions.
305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
306 | export MAVEN_CMD_LINE_ARGS
307 |
308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
309 |
310 | exec "$JAVACMD" \
311 | $MAVEN_OPTS \
312 | $MAVEN_DEBUG_OPTS \
313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
314 | "-Dmaven.home=${M2_HOME}" \
315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
317 |
--------------------------------------------------------------------------------
/spring-boot/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM https://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM set title of command window
39 | title %0
40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
42 |
43 | @REM set %HOME% to equivalent of $HOME
44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
45 |
46 | @REM Execute a user defined script before this one
47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
51 | :skipRcPre
52 |
53 | @setlocal
54 |
55 | set ERROR_CODE=0
56 |
57 | @REM To isolate internal variables from possible post scripts, we use another setlocal
58 | @setlocal
59 |
60 | @REM ==== START VALIDATION ====
61 | if not "%JAVA_HOME%" == "" goto OkJHome
62 |
63 | echo.
64 | echo Error: JAVA_HOME not found in your environment. >&2
65 | echo Please set the JAVA_HOME variable in your environment to match the >&2
66 | echo location of your Java installation. >&2
67 | echo.
68 | goto error
69 |
70 | :OkJHome
71 | if exist "%JAVA_HOME%\bin\java.exe" goto init
72 |
73 | echo.
74 | echo Error: JAVA_HOME is set to an invalid directory. >&2
75 | echo JAVA_HOME = "%JAVA_HOME%" >&2
76 | echo Please set the JAVA_HOME variable in your environment to match the >&2
77 | echo location of your Java installation. >&2
78 | echo.
79 | goto error
80 |
81 | @REM ==== END VALIDATION ====
82 |
83 | :init
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
122 |
123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
124 |
125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
127 | )
128 |
129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data.
131 | if exist %WRAPPER_JAR% (
132 | if "%MVNW_VERBOSE%" == "true" (
133 | echo Found %WRAPPER_JAR%
134 | )
135 | ) else (
136 | if not "%MVNW_REPOURL%" == "" (
137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
138 | )
139 | if "%MVNW_VERBOSE%" == "true" (
140 | echo Couldn't find %WRAPPER_JAR%, downloading it ...
141 | echo Downloading from: %DOWNLOAD_URL%
142 | )
143 |
144 | powershell -Command "&{"^
145 | "$webclient = new-object System.Net.WebClient;"^
146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
148 | "}"^
149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
150 | "}"
151 | if "%MVNW_VERBOSE%" == "true" (
152 | echo Finished downloading %WRAPPER_JAR%
153 | )
154 | )
155 | @REM End of extension
156 |
157 | @REM Provide a "standardized" way to retrieve the CLI args that will
158 | @REM work with both Windows and non-Windows executions.
159 | set MAVEN_CMD_LINE_ARGS=%*
160 |
161 | %MAVEN_JAVA_EXE% ^
162 | %JVM_CONFIG_MAVEN_PROPS% ^
163 | %MAVEN_OPTS% ^
164 | %MAVEN_DEBUG_OPTS% ^
165 | -classpath %WRAPPER_JAR% ^
166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
168 | if ERRORLEVEL 1 goto error
169 | goto end
170 |
171 | :error
172 | set ERROR_CODE=1
173 |
174 | :end
175 | @endlocal & set ERROR_CODE=%ERROR_CODE%
176 |
177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
181 | :skipRcPost
182 |
183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause
185 |
186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
187 |
188 | cmd /C exit /B %ERROR_CODE%
189 |
--------------------------------------------------------------------------------
/spring-boot/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.0.0-RC1
9 |
10 |
11 | com.example
12 | demo
13 | 0.0.1-SNAPSHOT
14 | spring-boot
15 | Demo project for Spring Boot
16 |
17 | 17
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-oauth2-resource-server
23 |
24 |
25 | org.springframework.boot
26 | spring-boot-starter-web
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-test
32 | test
33 |
34 |
35 |
36 |
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-maven-plugin
41 |
42 |
43 |
44 | gcr.io/paketo-buildpacks/bellsoft-liberica:9.9.0-ea
45 | gcr.io/paketo-buildpacks/java-native-image
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | spring-milestones
55 | Spring Milestones
56 | https://repo.spring.io/milestone
57 |
58 | false
59 |
60 |
61 |
62 |
63 |
64 | spring-milestones
65 | Spring Milestones
66 | https://repo.spring.io/milestone
67 |
68 | false
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/spring-boot/src/main/java/com/okta/rest/Application.java:
--------------------------------------------------------------------------------
1 | package com.okta.rest;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Application.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/spring-boot/src/main/java/com/okta/rest/controller/HelloController.java:
--------------------------------------------------------------------------------
1 | package com.okta.rest.controller;
2 |
3 | import org.springframework.web.bind.annotation.GetMapping;
4 | import org.springframework.web.bind.annotation.RestController;
5 |
6 | import java.security.Principal;
7 |
8 | @RestController
9 | public class HelloController {
10 |
11 | @GetMapping("/hello")
12 | public String hello(Principal principal) {
13 | return "Hello, " + principal.getName() + "!";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/spring-boot/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-17700857.okta.com/oauth2/default
2 |
--------------------------------------------------------------------------------
/spring-boot/src/test/java/com/okta/rest/ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.okta.rest;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class ApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------