├── .gitignore
├── LICENSE
├── README.md
├── enter-serverless-functions
├── .dockerignore
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── .gitignore
│ │ ├── MavenWrapperDownloader.java
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── docker
│ │ ├── Dockerfile.jvm
│ │ ├── Dockerfile.legacy-jar
│ │ ├── Dockerfile.native
│ │ └── Dockerfile.native-micro
│ ├── java
│ │ └── org
│ │ │ └── acme
│ │ │ ├── GreetingResource.java
│ │ │ └── GreetingService.java
│ └── resources
│ │ ├── META-INF
│ │ └── resources
│ │ │ └── index.html
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── acme
│ ├── GreetingResourceIT.java
│ └── GreetingResourceTest.java
├── images
├── aws-function-detail.png
├── aws-function.png
├── aws-function2.png
├── aws-funqy.png
├── aws-gateapi.png
├── aws-gateapi2.png
├── aws-iam.png
├── aws-metrics.png
├── aws-signin.png
├── aws-test-result.png
├── aws-test.png
├── copy-login-token.png
├── copy-login.png
├── dev-sandbox.png
├── devui-ct.png
├── devui-open-terminal.png
├── devui.png
├── openshift-cloudevent-log.png
├── openshift-funq-up.png
├── openshift-funq.png
├── openshift-kn-funq.png
├── quarkus-container-first.png
├── quarkus-funqy.png
└── quarkus-serverless-logo.png
├── instructions
├── 1-prerequisites.adoc
├── 2-generate-quarkus-project.adoc
├── 3-deploy-aws-lambda.adoc
├── 4-optimize-quarkus-functions.adoc
├── 5-deploy-quarkus-functions.adoc
├── 6-generate-kn-functions.adoc
└── 7-summary.adoc
└── quarkus-func
├── .gitignore
├── .mvn
└── wrapper
│ ├── MavenWrapperDownloader.java
│ └── maven-wrapper.properties
├── README.md
├── func.yaml
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
├── java
│ └── functions
│ │ ├── Function.java
│ │ ├── Input.java
│ │ └── Output.java
└── resources
│ └── application.properties
└── test
└── java
└── functions
├── FunctionTest.java
└── NativeFunctionIT.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | target/
5 |
6 | # Log file
7 | *.log
8 |
9 | # BlueJ files
10 | *.ctxt
11 |
12 | # Mobile Tools for Java (J2ME)
13 | .mtj.tmp/
14 |
15 | # Package Files #
16 | *.jar
17 | *.war
18 | *.nar
19 | *.ear
20 | *.zip
21 | *.tar.gz
22 | *.rar
23 |
24 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
25 | hs_err_pid*
26 |
--------------------------------------------------------------------------------
/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 [yyyy] [name of copyright owner]
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 |
2 |
3 | # Enter Serverless Functions Journey with Quarkus
4 |
5 | This hands-on lab showcases how quickly developers can create cloud-native microservice project using [Quarkus](https://quarkus.io/). Then, the application can be deployed to a function to [AWS Lambda](https://aws.amazon.com/lambda/) and [Kubernetes](https://kubernetes.io/) [Knative](https://knative.dev/docs/) with `JVM` and `Native` mode.
6 |
7 | 
8 |
9 | ## Instructions
10 |
11 | 1. [Prerequisites](instructions/1-prerequisites.adoc)
12 | 2. [Generate a new Quarkus project](instructions/2-generate-quarkus-project.adoc)
13 | 3. [Deploy to AWS Lambda with HTTP API](instructions/3-deploy-aws-lambda.adoc)
14 | 4. [Optimize the function and make it portable using Quarkus Funqy](instructions/4-optimize-quarkus-functions.adoc)
15 | 5. [Deploy the function to Red Hat OpenShift Serverless](instructions/5-deploy-quarkus-functions.adoc)
16 | 6. [Generate a new function project using Kn func CLI](instructions/6-generate-kn-functions.adoc)
17 | 7. [Summary](instructions/7-summary.adoc)
--------------------------------------------------------------------------------
/enter-serverless-functions/.dockerignore:
--------------------------------------------------------------------------------
1 | *
2 | !target/*-runner
3 | !target/*-runner.jar
4 | !target/lib/*
5 | !target/quarkus-app/*
--------------------------------------------------------------------------------
/enter-serverless-functions/.gitignore:
--------------------------------------------------------------------------------
1 | #Maven
2 | target/
3 | pom.xml.tag
4 | pom.xml.releaseBackup
5 | pom.xml.versionsBackup
6 | release.properties
7 |
8 | # Eclipse
9 | .project
10 | .classpath
11 | .settings/
12 | bin/
13 |
14 | # IntelliJ
15 | .idea
16 | *.ipr
17 | *.iml
18 | *.iws
19 |
20 | # NetBeans
21 | nb-configuration.xml
22 |
23 | # Visual Studio Code
24 | .vscode
25 | .factorypath
26 |
27 | # OSX
28 | .DS_Store
29 |
30 | # Vim
31 | *.swp
32 | *.swo
33 |
34 | # patch
35 | *.orig
36 | *.rej
37 |
38 | # Local environment
39 | .env
40 |
--------------------------------------------------------------------------------
/enter-serverless-functions/.mvn/wrapper/.gitignore:
--------------------------------------------------------------------------------
1 | maven-wrapper.jar
2 |
--------------------------------------------------------------------------------
/enter-serverless-functions/.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.io.IOException;
21 | import java.io.InputStream;
22 | import java.net.Authenticator;
23 | import java.net.PasswordAuthentication;
24 | import java.net.URL;
25 | import java.nio.file.Files;
26 | import java.nio.file.Path;
27 | import java.nio.file.Paths;
28 | import java.nio.file.StandardCopyOption;
29 |
30 | public final class MavenWrapperDownloader
31 | {
32 | private static final String WRAPPER_VERSION = "3.2.0";
33 |
34 | private static final boolean VERBOSE = Boolean.parseBoolean( System.getenv( "MVNW_VERBOSE" ) );
35 |
36 | public static void main( String[] args )
37 | {
38 | log( "Apache Maven Wrapper Downloader " + WRAPPER_VERSION );
39 |
40 | if ( args.length != 2 )
41 | {
42 | System.err.println( " - ERROR wrapperUrl or wrapperJarPath parameter missing" );
43 | System.exit( 1 );
44 | }
45 |
46 | try
47 | {
48 | log( " - Downloader started" );
49 | final URL wrapperUrl = new URL( args[0] );
50 | final String jarPath = args[1].replace( "..", "" ); // Sanitize path
51 | final Path wrapperJarPath = Paths.get( jarPath ).toAbsolutePath().normalize();
52 | downloadFileFromURL( wrapperUrl, wrapperJarPath );
53 | log( "Done" );
54 | }
55 | catch ( IOException e )
56 | {
57 | System.err.println( "- Error downloading: " + e.getMessage() );
58 | if ( VERBOSE )
59 | {
60 | e.printStackTrace();
61 | }
62 | System.exit( 1 );
63 | }
64 | }
65 |
66 | private static void downloadFileFromURL( URL wrapperUrl, Path wrapperJarPath )
67 | throws IOException
68 | {
69 | log( " - Downloading to: " + wrapperJarPath );
70 | if ( System.getenv( "MVNW_USERNAME" ) != null && System.getenv( "MVNW_PASSWORD" ) != null )
71 | {
72 | final String username = System.getenv( "MVNW_USERNAME" );
73 | final char[] password = System.getenv( "MVNW_PASSWORD" ).toCharArray();
74 | Authenticator.setDefault( new Authenticator()
75 | {
76 | @Override
77 | protected PasswordAuthentication getPasswordAuthentication()
78 | {
79 | return new PasswordAuthentication( username, password );
80 | }
81 | } );
82 | }
83 | try ( InputStream inStream = wrapperUrl.openStream() )
84 | {
85 | Files.copy( inStream, wrapperJarPath, StandardCopyOption.REPLACE_EXISTING );
86 | }
87 | log( " - Downloader complete" );
88 | }
89 |
90 | private static void log( String msg )
91 | {
92 | if ( VERBOSE )
93 | {
94 | System.out.println( msg );
95 | }
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/enter-serverless-functions/.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.8/apache-maven-3.8.8-bin.zip
18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
19 |
--------------------------------------------------------------------------------
/enter-serverless-functions/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 | # http://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 | # Apache Maven Wrapper startup batch script, version 3.2.0
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | # e.g. to debug Maven itself, use
32 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | # ----------------------------------------------------------------------------
35 |
36 | if [ -z "$MAVEN_SKIP_RC" ] ; then
37 |
38 | if [ -f /usr/local/etc/mavenrc ] ; then
39 | . /usr/local/etc/mavenrc
40 | fi
41 |
42 | if [ -f /etc/mavenrc ] ; then
43 | . /etc/mavenrc
44 | fi
45 |
46 | if [ -f "$HOME/.mavenrc" ] ; then
47 | . "$HOME/.mavenrc"
48 | fi
49 |
50 | fi
51 |
52 | # OS specific support. $var _must_ be set to either true or false.
53 | cygwin=false;
54 | darwin=false;
55 | mingw=false
56 | case "$(uname)" in
57 | CYGWIN*) cygwin=true ;;
58 | MINGW*) mingw=true;;
59 | Darwin*) darwin=true
60 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
61 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
62 | if [ -z "$JAVA_HOME" ]; then
63 | if [ -x "/usr/libexec/java_home" ]; then
64 | JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
65 | else
66 | JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
67 | fi
68 | fi
69 | ;;
70 | esac
71 |
72 | if [ -z "$JAVA_HOME" ] ; then
73 | if [ -r /etc/gentoo-release ] ; then
74 | JAVA_HOME=$(java-config --jre-home)
75 | fi
76 | fi
77 |
78 | # For Cygwin, ensure paths are in UNIX format before anything is touched
79 | if $cygwin ; then
80 | [ -n "$JAVA_HOME" ] &&
81 | JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
82 | [ -n "$CLASSPATH" ] &&
83 | CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
84 | fi
85 |
86 | # For Mingw, ensure paths are in UNIX format before anything is touched
87 | if $mingw ; then
88 | [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
89 | JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
90 | fi
91 |
92 | if [ -z "$JAVA_HOME" ]; then
93 | javaExecutable="$(which javac)"
94 | if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
95 | # readlink(1) is not available as standard on Solaris 10.
96 | readLink=$(which readlink)
97 | if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
98 | if $darwin ; then
99 | javaHome="$(dirname "\"$javaExecutable\"")"
100 | javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
101 | else
102 | javaExecutable="$(readlink -f "\"$javaExecutable\"")"
103 | fi
104 | javaHome="$(dirname "\"$javaExecutable\"")"
105 | javaHome=$(expr "$javaHome" : '\(.*\)/bin')
106 | JAVA_HOME="$javaHome"
107 | export JAVA_HOME
108 | fi
109 | fi
110 | fi
111 |
112 | if [ -z "$JAVACMD" ] ; then
113 | if [ -n "$JAVA_HOME" ] ; then
114 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
115 | # IBM's JDK on AIX uses strange locations for the executables
116 | JAVACMD="$JAVA_HOME/jre/sh/java"
117 | else
118 | JAVACMD="$JAVA_HOME/bin/java"
119 | fi
120 | else
121 | JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
122 | fi
123 | fi
124 |
125 | if [ ! -x "$JAVACMD" ] ; then
126 | echo "Error: JAVA_HOME is not defined correctly." >&2
127 | echo " We cannot execute $JAVACMD" >&2
128 | exit 1
129 | fi
130 |
131 | if [ -z "$JAVA_HOME" ] ; then
132 | echo "Warning: JAVA_HOME environment variable is not set."
133 | fi
134 |
135 | # traverses directory structure from process work directory to filesystem root
136 | # first directory with .mvn subdirectory is considered project base directory
137 | find_maven_basedir() {
138 | if [ -z "$1" ]
139 | then
140 | echo "Path not specified to find_maven_basedir"
141 | return 1
142 | fi
143 |
144 | basedir="$1"
145 | wdir="$1"
146 | while [ "$wdir" != '/' ] ; do
147 | if [ -d "$wdir"/.mvn ] ; then
148 | basedir=$wdir
149 | break
150 | fi
151 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
152 | if [ -d "${wdir}" ]; then
153 | wdir=$(cd "$wdir/.." || exit 1; pwd)
154 | fi
155 | # end of workaround
156 | done
157 | printf '%s' "$(cd "$basedir" || exit 1; pwd)"
158 | }
159 |
160 | # concatenates all lines of a file
161 | concat_lines() {
162 | if [ -f "$1" ]; then
163 | # Remove \r in case we run on Windows within Git Bash
164 | # and check out the repository with auto CRLF management
165 | # enabled. Otherwise, we may read lines that are delimited with
166 | # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
167 | # splitting rules.
168 | tr -s '\r\n' ' ' < "$1"
169 | fi
170 | }
171 |
172 | log() {
173 | if [ "$MVNW_VERBOSE" = true ]; then
174 | printf '%s\n' "$1"
175 | fi
176 | }
177 |
178 | BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
179 | if [ -z "$BASE_DIR" ]; then
180 | exit 1;
181 | fi
182 |
183 | MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
184 | log "$MAVEN_PROJECTBASEDIR"
185 |
186 | ##########################################################################################
187 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
188 | # This allows using the maven wrapper in projects that prohibit checking in binary data.
189 | ##########################################################################################
190 | wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
191 | if [ -r "$wrapperJarPath" ]; then
192 | log "Found $wrapperJarPath"
193 | else
194 | log "Couldn't find $wrapperJarPath, downloading it ..."
195 |
196 | if [ -n "$MVNW_REPOURL" ]; then
197 | wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
198 | else
199 | wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
200 | fi
201 | while IFS="=" read -r key value; do
202 | # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
203 | safeValue=$(echo "$value" | tr -d '\r')
204 | case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
205 | esac
206 | done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
207 | log "Downloading from: $wrapperUrl"
208 |
209 | if $cygwin; then
210 | wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
211 | fi
212 |
213 | if command -v wget > /dev/null; then
214 | log "Found wget ... using wget"
215 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
216 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
217 | wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
218 | else
219 | wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
220 | fi
221 | elif command -v curl > /dev/null; then
222 | log "Found curl ... using curl"
223 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
224 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
225 | curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
226 | else
227 | curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
228 | fi
229 | else
230 | log "Falling back to using Java to download"
231 | javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
232 | javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
233 | # For Cygwin, switch paths to Windows format before running javac
234 | if $cygwin; then
235 | javaSource=$(cygpath --path --windows "$javaSource")
236 | javaClass=$(cygpath --path --windows "$javaClass")
237 | fi
238 | if [ -e "$javaSource" ]; then
239 | if [ ! -e "$javaClass" ]; then
240 | log " - Compiling MavenWrapperDownloader.java ..."
241 | ("$JAVA_HOME/bin/javac" "$javaSource")
242 | fi
243 | if [ -e "$javaClass" ]; then
244 | log " - Running MavenWrapperDownloader.java ..."
245 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
246 | fi
247 | fi
248 | fi
249 | fi
250 | ##########################################################################################
251 | # End of extension
252 | ##########################################################################################
253 |
254 | # If specified, validate the SHA-256 sum of the Maven wrapper jar file
255 | wrapperSha256Sum=""
256 | while IFS="=" read -r key value; do
257 | case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
258 | esac
259 | done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
260 | if [ -n "$wrapperSha256Sum" ]; then
261 | wrapperSha256Result=false
262 | if command -v sha256sum > /dev/null; then
263 | if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
264 | wrapperSha256Result=true
265 | fi
266 | elif command -v shasum > /dev/null; then
267 | if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
268 | wrapperSha256Result=true
269 | fi
270 | else
271 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
272 | echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
273 | exit 1
274 | fi
275 | if [ $wrapperSha256Result = false ]; then
276 | echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
277 | echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
278 | echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
279 | exit 1
280 | fi
281 | fi
282 |
283 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
284 |
285 | # For Cygwin, switch paths to Windows format before running java
286 | if $cygwin; then
287 | [ -n "$JAVA_HOME" ] &&
288 | JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
289 | [ -n "$CLASSPATH" ] &&
290 | CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
291 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
292 | MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
293 | fi
294 |
295 | # Provide a "standardized" way to retrieve the CLI args that will
296 | # work with both Windows and non-Windows executions.
297 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
298 | export MAVEN_CMD_LINE_ARGS
299 |
300 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
301 |
302 | # shellcheck disable=SC2086 # safe args
303 | exec "$JAVACMD" \
304 | $MAVEN_OPTS \
305 | $MAVEN_DEBUG_OPTS \
306 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
307 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
308 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
309 |
--------------------------------------------------------------------------------
/enter-serverless-functions/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 |
--------------------------------------------------------------------------------
/enter-serverless-functions/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | org.acme
6 | enter-serverless-functions
7 | 1.0.0-SNAPSHOT
8 |
9 | 3.12.1
10 | 17
11 | UTF-8
12 | UTF-8
13 | quarkus-bom
14 | io.quarkus.platform
15 | 3.16.1
16 | true
17 | 3.2.3
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-arc
34 |
35 |
36 | io.quarkus
37 | quarkus-rest
38 |
39 |
51 |
52 | io.quarkus
53 | quarkus-junit5
54 | test
55 |
56 |
57 | io.rest-assured
58 | rest-assured
59 | test
60 |
61 |
62 |
63 |
64 |
65 | ${quarkus.platform.group-id}
66 | quarkus-maven-plugin
67 | ${quarkus.platform.version}
68 | true
69 |
70 |
71 |
72 | build
73 | generate-code
74 | generate-code-tests
75 |
76 |
77 |
78 |
79 |
80 | maven-compiler-plugin
81 | ${compiler-plugin.version}
82 |
83 |
84 | -parameters
85 |
86 |
87 |
88 |
89 | maven-surefire-plugin
90 | ${surefire-plugin.version}
91 |
92 |
93 | org.jboss.logmanager.LogManager
94 | ${maven.home}
95 |
96 |
97 |
98 |
99 | maven-failsafe-plugin
100 | ${surefire-plugin.version}
101 |
102 |
103 |
104 | integration-test
105 | verify
106 |
107 |
108 |
109 | ${project.build.directory}/${project.build.finalName}-runner
110 | org.jboss.logmanager.LogManager
111 | ${maven.home}
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | native
122 |
123 |
124 | native
125 |
126 |
127 |
128 | false
129 | true
130 | false
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/enter-serverless-functions/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/enter-serverless-function-jvm .
11 | #
12 | # Then run the container using:
13 | #
14 | # docker run -i --rm -p 8080:8080 quarkus/enter-serverless-function-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 being the default) like this : EXPOSE 8080 5005.
18 | # Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
19 | # when running the container
20 | #
21 | # Then run the container using :
22 | #
23 | # docker run -i --rm -p 8080:8080 quarkus/enter-serverless-function-jvm
24 | #
25 | # This image uses the `run-java.sh` script to run the application.
26 | # This scripts computes the command line to execute your Java application, and
27 | # includes memory/GC tuning.
28 | # You can configure the behavior using the following environment properties:
29 | # - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
30 | # - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
31 | # in JAVA_OPTS (example: "-Dsome.property=foo")
32 | # - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
33 | # used to calculate a default maximal heap memory based on a containers restriction.
34 | # If used in a container without any memory constraints for the container then this
35 | # option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
36 | # of the container available memory as set here. The default is `50` which means 50%
37 | # of the available memory is used as an upper boundary. You can skip this mechanism by
38 | # setting this value to `0` in which case no `-Xmx` option is added.
39 | # - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
40 | # is used to calculate a default initial heap memory based on the maximum heap memory.
41 | # If used in a container without any memory constraints for the container then this
42 | # option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
43 | # of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
44 | # is used as the initial heap size. You can skip this mechanism by setting this value
45 | # to `0` in which case no `-Xms` option is added (example: "25")
46 | # - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
47 | # This is used to calculate the maximum value of the initial heap memory. If used in
48 | # a container without any memory constraints for the container then this option has
49 | # no effect. If there is a memory constraint then `-Xms` is limited to the value set
50 | # here. The default is 4096MB which means the calculated value of `-Xms` never will
51 | # be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
52 | # - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
53 | # when things are happening. This option, if set to true, will set
54 | # `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
55 | # - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
56 | # true").
57 | # - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
58 | # - CONTAINER_CORE_LIMIT: A calculated core limit as described in
59 | # https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
60 | # - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
61 | # - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
62 | # (example: "20")
63 | # - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
64 | # (example: "40")
65 | # - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
66 | # (example: "4")
67 | # - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
68 | # previous GC times. (example: "90")
69 | # - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
70 | # - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
71 | # - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
72 | # contain the necessary JRE command-line options to specify the required GC, which
73 | # will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
74 | # - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
75 | # - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
76 | # - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
77 | # accessed directly. (example: "foo.example.com,bar.example.com")
78 | #
79 | ###
80 | FROM registry.access.redhat.com/ubi8/openjdk-17:1.15
81 |
82 | ENV LANGUAGE='en_US:en'
83 |
84 |
85 | # We make four distinct layers so if there are application changes the library layers can be re-used
86 | COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/
87 | COPY --chown=185 target/quarkus-app/*.jar /deployments/
88 | COPY --chown=185 target/quarkus-app/app/ /deployments/app/
89 | COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/
90 |
91 | EXPOSE 8080
92 | USER 185
93 | ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
94 | ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
95 |
96 |
--------------------------------------------------------------------------------
/enter-serverless-functions/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/enter-serverless-function-legacy-jar .
11 | #
12 | # Then run the container using:
13 | #
14 | # docker run -i --rm -p 8080:8080 quarkus/enter-serverless-function-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 being the default) like this : EXPOSE 8080 5005.
18 | # Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
19 | # when running the container
20 | #
21 | # Then run the container using :
22 | #
23 | # docker run -i --rm -p 8080:8080 quarkus/enter-serverless-function-legacy-jar
24 | #
25 | # This image uses the `run-java.sh` script to run the application.
26 | # This scripts computes the command line to execute your Java application, and
27 | # includes memory/GC tuning.
28 | # You can configure the behavior using the following environment properties:
29 | # - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
30 | # - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
31 | # in JAVA_OPTS (example: "-Dsome.property=foo")
32 | # - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
33 | # used to calculate a default maximal heap memory based on a containers restriction.
34 | # If used in a container without any memory constraints for the container then this
35 | # option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
36 | # of the container available memory as set here. The default is `50` which means 50%
37 | # of the available memory is used as an upper boundary. You can skip this mechanism by
38 | # setting this value to `0` in which case no `-Xmx` option is added.
39 | # - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
40 | # is used to calculate a default initial heap memory based on the maximum heap memory.
41 | # If used in a container without any memory constraints for the container then this
42 | # option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
43 | # of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
44 | # is used as the initial heap size. You can skip this mechanism by setting this value
45 | # to `0` in which case no `-Xms` option is added (example: "25")
46 | # - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
47 | # This is used to calculate the maximum value of the initial heap memory. If used in
48 | # a container without any memory constraints for the container then this option has
49 | # no effect. If there is a memory constraint then `-Xms` is limited to the value set
50 | # here. The default is 4096MB which means the calculated value of `-Xms` never will
51 | # be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
52 | # - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
53 | # when things are happening. This option, if set to true, will set
54 | # `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
55 | # - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
56 | # true").
57 | # - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
58 | # - CONTAINER_CORE_LIMIT: A calculated core limit as described in
59 | # https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
60 | # - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
61 | # - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
62 | # (example: "20")
63 | # - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
64 | # (example: "40")
65 | # - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
66 | # (example: "4")
67 | # - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
68 | # previous GC times. (example: "90")
69 | # - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
70 | # - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
71 | # - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
72 | # contain the necessary JRE command-line options to specify the required GC, which
73 | # will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
74 | # - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
75 | # - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
76 | # - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
77 | # accessed directly. (example: "foo.example.com,bar.example.com")
78 | #
79 | ###
80 | FROM registry.access.redhat.com/ubi8/openjdk-17:1.15
81 |
82 | ENV LANGUAGE='en_US:en'
83 |
84 |
85 | COPY target/lib/* /deployments/lib/
86 | COPY target/*-runner.jar /deployments/quarkus-run.jar
87 |
88 | EXPOSE 8080
89 | USER 185
90 | ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
91 | ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
92 |
--------------------------------------------------------------------------------
/enter-serverless-functions/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/enter-serverless-function .
11 | #
12 | # Then run the container using:
13 | #
14 | # docker run -i --rm -p 8080:8080 quarkus/enter-serverless-function
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 |
--------------------------------------------------------------------------------
/enter-serverless-functions/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/enter-serverless-function .
14 | #
15 | # Then run the container using:
16 | #
17 | # docker run -i --rm -p 8080:8080 quarkus/enter-serverless-function
18 | #
19 | ###
20 | FROM quay.io/quarkus/quarkus-micro-image:2.0
21 | WORKDIR /work/
22 | RUN chown 1001 /work \
23 | && chmod "g+rwX" /work \
24 | && chown 1001:root /work
25 | COPY --chown=1001:root target/*-runner /work/application
26 |
27 | EXPOSE 8080
28 | USER 1001
29 |
30 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
31 |
--------------------------------------------------------------------------------
/enter-serverless-functions/src/main/java/org/acme/GreetingResource.java:
--------------------------------------------------------------------------------
1 | package org.acme;
2 | import jakarta.inject.Inject;
3 | import jakarta.ws.rs.GET;
4 | import jakarta.ws.rs.Path;
5 | import jakarta.ws.rs.Produces;
6 | import jakarta.ws.rs.core.MediaType;
7 |
8 | // import io.quarkus.funqy.Funq;
9 |
10 | @Path("/hello")
11 | public class GreetingResource {
12 |
13 | @Inject
14 | GreetingService greetingService;
15 |
16 | @GET
17 | @Produces(MediaType.TEXT_PLAIN)
18 | @Path("/greeting/{name}")
19 | public String greeting(String name) {
20 | return greetingService.greeting(name);
21 | }
22 |
23 | @GET
24 | @Produces(MediaType.TEXT_PLAIN)
25 | public String hello() {
26 | return "Hello Serverless";
27 | }
28 |
29 | // @Funq
30 | // public String greeting(String name) {
31 | // return greetingService.greeting(name);
32 | // }
33 |
34 | // @Funq
35 | // public String hello() {
36 | // return "Hello Serverless";
37 | // }
38 |
39 | }
--------------------------------------------------------------------------------
/enter-serverless-functions/src/main/java/org/acme/GreetingService.java:
--------------------------------------------------------------------------------
1 | package org.acme;
2 |
3 | import jakarta.enterprise.context.ApplicationScoped;
4 |
5 | @ApplicationScoped
6 | public class GreetingService {
7 |
8 | public String greeting(String name) {
9 | return "Enter Serverless Functions with Quarkus, " + name;
10 | }
11 |
12 | }
--------------------------------------------------------------------------------
/enter-serverless-functions/src/main/resources/META-INF/resources/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | enter-serverless-functions - 1.0.0-SNAPSHOT
6 |
108 |
109 |
110 |
111 |
112 | Your new Cloud-Native application is ready!
113 |
114 |
115 |
116 |
117 |
Congratulations, you have created a new Quarkus cloud application.
118 |
119 |
What is this page?
120 |
121 |
This page is served by Quarkus. The source is in
122 | src/main/resources/META-INF/resources/index.html.
123 |
124 |
What are your next steps?
125 |
126 |
If not already done, run the application in dev mode using: ./mvnw compile quarkus:dev.
127 |
128 |
129 |
Your static assets are located in src/main/resources/META-INF/resources.
130 |
Configure your application in src/main/resources/application.properties.
131 |
Quarkus now ships with a Dev UI (available in dev mode only)
132 |
Play with the provided code located in src/main/java:
169 |
170 |
--------------------------------------------------------------------------------
/enter-serverless-functions/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | # quarkus.native.container-runtime=docker
2 | # quarkus.funqy.export=greeting
3 |
4 | # kubernetes.deployment.target=knative
5 | # quarkus.container-image.group=quarkus-serverless
6 | # quarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000
7 | # quarkus.kubernetes-client.trust-certs=true
8 | # quarkus.kubernetes.deploy=true
9 | # quarkus.openshift.build-strategy=docker
--------------------------------------------------------------------------------
/enter-serverless-functions/src/test/java/org/acme/GreetingResourceIT.java:
--------------------------------------------------------------------------------
1 | package org.acme;
2 |
3 | import io.quarkus.test.junit.QuarkusIntegrationTest;
4 |
5 | @QuarkusIntegrationTest
6 | public class GreetingResourceIT extends GreetingResourceTest {
7 | // Execute the same tests but in packaged mode.
8 | }
9 |
--------------------------------------------------------------------------------
/enter-serverless-functions/src/test/java/org/acme/GreetingResourceTest.java:
--------------------------------------------------------------------------------
1 | package org.acme;
2 |
3 | import io.quarkus.test.junit.QuarkusTest;
4 | import org.junit.jupiter.api.Test;
5 |
6 | import static io.restassured.RestAssured.given;
7 | import static org.hamcrest.CoreMatchers.is;
8 |
9 | @QuarkusTest
10 | public class GreetingResourceTest {
11 |
12 | @Test
13 | public void testHelloEndpoint() {
14 | given()
15 | .when().get("/hello")
16 | .then()
17 | .statusCode(200)
18 | .body(is("Hello Serverless"));
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/images/aws-function-detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/aws-function-detail.png
--------------------------------------------------------------------------------
/images/aws-function.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/aws-function.png
--------------------------------------------------------------------------------
/images/aws-function2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/aws-function2.png
--------------------------------------------------------------------------------
/images/aws-funqy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/aws-funqy.png
--------------------------------------------------------------------------------
/images/aws-gateapi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/aws-gateapi.png
--------------------------------------------------------------------------------
/images/aws-gateapi2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/aws-gateapi2.png
--------------------------------------------------------------------------------
/images/aws-iam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/aws-iam.png
--------------------------------------------------------------------------------
/images/aws-metrics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/aws-metrics.png
--------------------------------------------------------------------------------
/images/aws-signin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/aws-signin.png
--------------------------------------------------------------------------------
/images/aws-test-result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/aws-test-result.png
--------------------------------------------------------------------------------
/images/aws-test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/aws-test.png
--------------------------------------------------------------------------------
/images/copy-login-token.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/copy-login-token.png
--------------------------------------------------------------------------------
/images/copy-login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/copy-login.png
--------------------------------------------------------------------------------
/images/dev-sandbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/dev-sandbox.png
--------------------------------------------------------------------------------
/images/devui-ct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/devui-ct.png
--------------------------------------------------------------------------------
/images/devui-open-terminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/devui-open-terminal.png
--------------------------------------------------------------------------------
/images/devui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/devui.png
--------------------------------------------------------------------------------
/images/openshift-cloudevent-log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/openshift-cloudevent-log.png
--------------------------------------------------------------------------------
/images/openshift-funq-up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/openshift-funq-up.png
--------------------------------------------------------------------------------
/images/openshift-funq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/openshift-funq.png
--------------------------------------------------------------------------------
/images/openshift-kn-funq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/openshift-kn-funq.png
--------------------------------------------------------------------------------
/images/quarkus-container-first.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/quarkus-container-first.png
--------------------------------------------------------------------------------
/images/quarkus-funqy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/quarkus-funqy.png
--------------------------------------------------------------------------------
/images/quarkus-serverless-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RedHat-Middleware-Workshops/enter-serverless-functions/c8c21304a0e8c7a5b348dd109c19e1c4967f441f/images/quarkus-serverless-logo.png
--------------------------------------------------------------------------------
/instructions/1-prerequisites.adoc:
--------------------------------------------------------------------------------
1 | = 1. Prerequisites
2 |
3 | Before you get started with the hands-on labs, if you already haven't user accounts in the sandbox and AWS, you might need to sign in two cloud services for function deployments such as OpenShift(Kubernetes) and AWS Lambda as below:
4 |
5 | * Sign up the [Developer Sandbox for Red Hat OpenShift](https://developers.redhat.com/developer-sandbox/get-started) to deploy Quarkus serverless functions to Kubernetes/OpenShift cluster. Click on `Start your sandbox for free` in the _Get Started in the Sandbox_ page. You will need to create a new user account using your email address then your sandbox will stand up in 5 minutes.
6 |
7 | image::../images/dev-sandbox.png[dev-sandbox]
8 |
9 | * Sing up [Amazon Web Services](https://aws.amazon.com/marketplace/management/signin). You might need to add your personal credit card information which *won't* charge for the function deployment during the lab. Because the function will be deleted at the end of the workshop.
10 |
11 | image::../images/aws-signin.png[aws-signin]
12 |
13 | * https://developers.redhat.com/products/openjdk/download[JDK 17] installed with `JAVA_HOME` configured appropriately
14 |
15 | * https://maven.apache.org/download.cgi[Apache Maven 3.9.1^]
16 |
17 | * https://docs.openshift.com/container-platform/latest/serverless/install/installing-kn.html[Knative CLI^]
18 |
19 | * https://quarkus.io/guides/cli-tooling[Quarkus CLI^]
20 |
21 | * https://httpie.io[HTTPie^]
22 |
23 | ➡️ link:./2-generate-quarkus-project.adoc[2. Generate a new Quarkus project]
24 |
--------------------------------------------------------------------------------
/instructions/2-generate-quarkus-project.adoc:
--------------------------------------------------------------------------------
1 | = 2. Generate a new Quarkus project
2 |
3 | Use `Quarkus CLI` to scaffold a new Quarkus project based on Maven. Run the following command locally in the Terminal:
4 |
5 | [NOTE]
6 | ====
7 | You can use https://maven.apache.org/download.cgi[Maven^] or https://gradle.org/install[Gradle^] or Quarks tools in IDE instead of **Quarkus CLI**.
8 | ====
9 |
10 | [source,sh]
11 | ----
12 | quarkus create app enter-serverless-function
13 |
14 | ----
15 |
16 | The output looks like:
17 |
18 | [source,sh]
19 | ----
20 | Creating an app (default project type, see --help).
21 | -----------
22 |
23 | applying codestarts...
24 | 📚 java
25 | 🔨 maven
26 | 📦 quarkus
27 | 📝 config-properties
28 | 🔧 dockerfiles
29 | 🔧 maven-wrapper
30 | 🚀 resteasy-codestart
31 |
32 | -----------
33 | [SUCCESS] ✅ quarkus project has been successfully generated in:
34 | --> /YOUR_WORKING_DIR/enter-serverless-function
35 | -----------
36 | Navigate into this directory and get started: quarkus dev
37 | ----
38 |
39 | == Test the application locally
40 |
41 | First thing first! Run the Quarkus Dev Mode using the following Quarkus CLI:
42 |
43 | [source,sh]
44 | ----
45 | cd enter-serverless-function
46 | quarkus dev
47 | ----
48 |
49 | The output looks like:
50 |
51 | [source,sh]
52 | ----
53 | Listening for transport dt_socket at address: 5005
54 |
55 | __ ____ __ _____ ___ __ ____ ______
56 | --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
57 | -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
58 | --\___\_\____/_/ |_/_/|_/_/|_|\____/___/
59 | INFO [io.quarkus] (Quarkus Main Thread) enter-serverless-function 1.0.0-SNAPSHOT on JVM (powered by Quarkus xx.xx.xx.Final) started in 1.612s. Listening on: http://localhost:8080
60 |
61 | INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
62 | INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy-reactive, smallrye-context-propagation, vertx]
63 |
64 | --
65 | Tests paused
66 | Press [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>
67 | ----
68 |
69 | Press `r` to start the _continuous testing_ then press `d` to open a _DEV UI_. It will open a new web browser then access to http://localhost:8080/q/dev/[DEV UI^].
70 |
71 | You'll also see `All tests passed` on the right bottom that points the result of the continuous testing.
72 |
73 | image::../images/devui.png[devui]
74 |
75 | When you select the down arrow on the left bottom, you will see the readonly log terminal.
76 |
77 | image::../images/devui-open-terminal.png[devui-open-terminal]
78 |
79 | Select `Continuous Testing` menu on the left, you will see the same testing result as you saw in your terminal.
80 |
81 | image::../images/devui-ct.png[devui-ct]
82 |
83 | Verify the RESTful API if it works well. For example, use https://httpie.io[HTTPie^] to invoke the endpoint in your local terminal:
84 |
85 | [source,sh]
86 | ----
87 | http :8080/hello
88 | ----
89 |
90 | The output should be:
91 |
92 | [source,sh]
93 | ----
94 | HTTP/1.1 200 OK
95 | Content-Type: text/plain;charset=UTF-8
96 | content-length: 28
97 |
98 | Hello from RESTEasy Reactive
99 | ----
100 |
101 | You can also use `curl` command to access the endpoint:
102 |
103 | [source,sh]
104 | ----
105 | curl localhost:8080/hello
106 | ----
107 |
108 | Keep *running* your Quarkus dev mode!!
109 |
110 | ➡️ link:./3-deploy-aws-lambda.adoc[3. Deploy to AWS Lambda with HTTP API]
111 |
112 | ⬅️ link:./1-prerequisites.adoc[1. Prerequisites]
--------------------------------------------------------------------------------
/instructions/3-deploy-aws-lambda.adoc:
--------------------------------------------------------------------------------
1 | = 3. Deploy to AWS Lambda with HTTP API
2 |
3 | To deploy this application to AWS Lambda with HTTP API, add a new Quarkus extension(_quarkus-amazon-lambda-http_) using Quarkus CLI:
4 |
5 | [source,sh]
6 | ----
7 | quarkus ext add quarkus-amazon-lambda-http
8 | ----
9 |
10 | The output should be:
11 |
12 | [source,sh]
13 | ----
14 | [SUCCESS] ✅ Extension io.quarkus:quarkus-amazon-lambda-http has been installed
15 | ----
16 |
17 | You can also search what kinds of extensions are available to install on the working project:
18 |
19 | [source,sh]
20 | ----
21 | quarkus ext --installable -s aws
22 | ----
23 |
24 | The output looks like:
25 |
26 | [source,sh]
27 | ----
28 | Listing extensions (default action, see --help).
29 | Current Quarkus extensions installable:
30 |
31 | ✬ ArtifactId Extension Name
32 | ✬ camel-quarkus-aws2-athena Camel AWS 2 Athena
33 | ✬ camel-quarkus-aws2-cw Camel AWS 2 CloudWatch
34 | ✬ camel-quarkus-aws2-ddb Camel AWS 2 DynamoDB
35 | ...
36 | ✬ quarkus-amazon-lambda AWS Lambda
37 | ✬ quarkus-amazon-lambda-http AWS Lambda HTTP
38 | ✬ quarkus-amazon-lambda-rest AWS Lambda Gateway REST API
39 | ✬ quarkus-amazon-lambda-xray AWS Lambda X-Ray
40 | ✬ quarkus-amazon-s3 Amazon S3
41 | ✬ quarkus-amazon-secretsmanager Amazon Secrets Manager
42 | ✬ quarkus-amazon-ses Amazon SES
43 | ✬ quarkus-amazon-sns Amazon SNS
44 | ✬ quarkus-amazon-sqs Amazon SQS
45 | ✬ quarkus-amazon-ssm Amazon SSM
46 | ✬ quarkus-funqy-amazon-lambda Funqy AWS Lambda Binding
47 | quarkus-hibernate-search-orm-elasticsearch-aws Hibernate Search + Elasticsearch - AWS authentication and request signing
48 | ----
49 |
50 | Before we deploy, let's add a new method and class to expose a new function on AWS Lambda.
51 |
52 | Create a new `GreetingService.java` file in _src/main/java/org/acme/_. Then copy the following code:
53 |
54 | [source,java]
55 | ----
56 | package org.acme;
57 |
58 | import jakarta.enterprise.context.ApplicationScoped;
59 |
60 | @ApplicationScoped
61 | public class GreetingService {
62 |
63 | public String greeting(String name) {
64 | return "Enter Serverless Functions with Quarkus, " + name;
65 | }
66 |
67 | }
68 | ----
69 |
70 | Update `GreetingResource.java` file in _src/main/java/org/acme/_ to inject a CDI bean as well as modifying the return string in _hello_ method:
71 |
72 | [source,java]
73 | ----
74 | package org.acme;
75 |
76 | import jakarta.inject.Inject;
77 | import jakarta.ws.rs.GET;
78 | import jakarta.ws.rs.Path;
79 |
80 | @Path("/hello")
81 | public class GreetingResource {
82 |
83 | @Inject
84 | GreetingService greetingService;
85 |
86 | @GET
87 | @Path("/greeting/{name}")
88 | public String greeting(String name) {
89 | return greetingService.greeting(name);
90 | }
91 |
92 | @GET
93 | public String hello() {
94 | return "Hello Serverless";
95 | }
96 | }
97 | ----
98 |
99 | Verify both a new endpoint(_/hello/greeting/{name}_) and an existing one(_/hello_) using HTTPie:
100 |
101 | [source,sh]
102 | ----
103 | http :8080/hello
104 | ----
105 |
106 | The output looks like:
107 |
108 | [source,sh]
109 | ----
110 | HTTP/1.1 200 OK
111 | Content-Length: 16
112 | Content-Type: text/plain;charset=UTF-8
113 |
114 | Hello Serverless
115 | ----
116 |
117 | Access another REST API:
118 |
119 | [source,sh]
120 | ----
121 | http :8080/hello/greeting/daniel
122 | ----
123 |
124 | The output looks like:
125 |
126 | [source,sh]
127 | ----
128 | HTTP/1.1 200 OK
129 | Content-Length: 47
130 | Content-Type: text/plain;charset=UTF-8
131 |
132 | Enter Serverless Functions with Quarkus, daniel
133 | ----
134 |
135 | [NOTE]
136 | ====
137 | You don’t need to stop and re-run the serverless application because Quarkus will reload the changes automatically via the `Live Coding` feature.
138 |
139 | In case you're stuck when you invoke the REST APIs, make sure to close the Dev UI and restart the Quarkus dev mode.
140 | ====
141 |
142 | To mirror the AWS Lambda environment as closely as possible in a dev environment, the Quarkus Amazon Lambda extension boots up a mock AWS Lambda event server in Quarkus Dev and Test mode. This mock event server simulates a true AWS Lambda environment.
143 |
144 | While running in *Quarkus Dev Mode*, you can feed events to it by doing an `HTTP POST` to http://localhost:8080. The mock event server will receive the events and your lambda will be invoked. You can perform live coding on your lambda and changes will automatically be recompiled and available the next invocation you make.
145 |
146 | Furthermore, if you're still running (or re-run) the *continuous testing*, you can see the following `TEST REPORT` in the terminal because you only changed the business application code (e.g. _hello()_) without the test code.
147 |
148 | [source,sh]
149 | ----
150 | ERROR [io.qua.test] (Test runner thread) ==================== TEST REPORT #1 ====================
151 | ERROR [io.qua.test] (Test runner thread) Test GreetingResourceTest#testHelloEndpoint() failed
152 | : java.lang.AssertionError: 1 expectation failed.
153 | Response body doesn't match expectation.
154 | Expected: is "Hello from RESTEasy Reactive"
155 | Actual: Hello Serverless
156 |
157 | at io.restassured.internal.ValidatableResponseImpl.body(ValidatableResponseImpl.groovy)
158 | at org.acme.GreetingResourceTest.testHelloEndpoint(GreetingResourceTest.java:18)
159 | ----
160 |
161 | To fix the test error, update the test case along with the modified __hello__ function. Open the `GreetingResourceTest.java` file in __src/test/java/org/acme__ directory and replace `testHelloEndpoint()` method with the following code:
162 |
163 | [source,java]
164 | ----
165 | @Test
166 | public void testHelloEndpoint() {
167 | given()
168 | .when().get("/hello")
169 | .then()
170 | .statusCode(200)
171 | .body(is("Hello Serverless"));
172 | }
173 | ----
174 |
175 | `Save` the file then go back to the terminal where Quarkus Dev mode is running.
176 |
177 | Then, you will see the test case passed as below:
178 |
179 | [source,sh]
180 | ----
181 | All 1 test is passing (0 skipped), 1 test was run in 828ms. Tests completed at 10:59:56 due to changes to GreetingResourceTest.class.
182 | ----
183 |
184 | Stop the Dev Mode using `CTRL-C`! Package the application using the following Quarkus CLI:
185 |
186 | [source,sh]
187 | ----
188 | quarkus build --no-tests
189 | ----
190 |
191 | or Use maven package command as below:
192 |
193 | [source,sh]
194 | ----
195 | ./mvnw clean package
196 | ----
197 |
198 | The output will end with `BUILD SUCCESS`.
199 |
200 | Inspect generated files in the _target_ directory:
201 |
202 | * **function.zip** - lambda deployment file
203 | * **bootstrap-example.sh** - example bootstrap script for native deployments
204 | * **sam.jvm.yaml** - (optional) for use with sam cli and local testing
205 | * **sam.native.yaml** - (optional) for use with sam cli and native local testing
206 |
207 | [NOTE]
208 | ====
209 | If you have already tested the function using live coding with Quarkus Dev mode, you can skip the function simulation locally. Then jump into the deployment step.
210 | ====
211 |
212 | To simulate the function locally using https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html[SAM CLI^]. The AWS SAM command line interface (CLI) requires you to set AWS credentials so that it can make calls to AWS services on your behalf. Find more information how to set up AWS credentials for SAM CLI https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started-set-up-credentials.html[here^].
213 |
214 | [NOTE]
215 | ====
216 | You need to run a container runtime(e.g. https://www.docker.com/products/docker-desktop[Docker^]) to run the SAM emulator.
217 | ====
218 |
219 | Open the `sam.jvm.yaml` file in the *target* directory. Then, update the `Runtime` to use Java 17. Currently, Quarkus doesn't generate the Java17 runtime by default.
220 |
221 | [source,sh]
222 | ----
223 | Runtime: java17
224 | ----
225 |
226 | Save the file. Then, run the following SAM command:
227 |
228 | [source,sh]
229 | ----
230 | sam local start-api -t target/sam.jvm.yaml
231 | ----
232 |
233 | Output should look like:
234 |
235 | [source,sh]
236 | ----
237 | Mounting EnterServerlessFunction at http://127.0.0.1:3000$default [X-AMAZON-APIGATEWAY-ANY-METHOD]
238 | You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. If you used sam build before running local commands, you will need to re-run sam build for the changes to be picked up. You only need to restart SAM CLI if you update your AWS SAM template
239 | YYYY-MM-SS HH:MM:SS WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
240 | * Running on http://127.0.0.1:3000
241 | YYYY-MM-SS HH:MM:SS Press CTRL+C to quit
242 | ----
243 |
244 | Then, invoke the endpoint like in another terminal:
245 |
246 | * HTTPie:
247 |
248 | [source,sh]
249 | ----
250 | http http://127.0.0.1:3000/hello/greeting/awslocal
251 | ----
252 |
253 | * Curl:
254 |
255 | [source,sh]
256 | ----
257 | curl http://127.0.0.1:3000/hello
258 | ----
259 |
260 | When you go back to the terminal where the sam local command is running, you will see that the Quarkus application gets started. It takes a few seconds to complete getting ready in Quarkus runtime.
261 |
262 | Then, the output should look like:
263 |
264 | [source,sh]
265 | ----
266 | HTTP/1.0 200 OK
267 | Content-Type: text/plain;charset=UTF-8
268 | Wed, 2 Non 2022 08:01:55 GMT
269 | Server: Werkzeug/1.0.1 Python/3.8.13
270 | content-length: 49
271 |
272 | Enter Serverless Functions with Quarkus, awslocal
273 | ----
274 |
275 | Stop the local testing by `CTRL-C`!
276 |
277 | [NOTE]
278 | ====
279 | You can also use the live coding feature for Lambda functions development locally. Find more information https://quarkus.io/guides/amazon-lambda#live-coding-and-unitintegration-testing[here^]
280 | ====
281 |
282 | If you haven't already configured `AWS credential` locally (e.g., **~/.aws/credentials**) yet, run the following aws command line:
283 |
284 | [source,sh]
285 | ----
286 | aws configure
287 | ----
288 |
289 | Find more information about https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html[Configuration and credential file settings^].
290 |
291 | Deploy the function to AWS Lambda using SAM CLI:
292 |
293 | [source,sh]
294 | ----
295 | sam deploy -t target/sam.jvm.yaml -g
296 | ----
297 |
298 | Input the configuration for the SAM Deploy with your preferences (e.g., Stack Name: `quarkus-function`). For example,
299 |
300 | [source,sh]
301 | ----
302 | Configuring SAM deploy
303 | ======================
304 |
305 | Looking for config file [samconfig.toml] : Not found
306 |
307 | Setting default arguments for 'sam deploy'
308 | =========================================
309 | Stack Name [sam-app]: quarkus-function
310 | AWS Region [us-east-1]:
311 | #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
312 | Confirm changes before deploy [y/N]: y
313 | #SAM needs permission to be able to create roles to connect to the resources in your template
314 | Allow SAM CLI IAM role creation [Y/n]: y
315 | #Preserves the state of previously provisioned resources when an operation fails
316 | Disable rollback [y/N]: n
317 | EnterServerlessFunction may not have authorization defined, Is this okay? [y/N]: y
318 | Save arguments to configuration file [Y/n]: y
319 | SAM configuration file [samconfig.toml]:
320 | SAM configuration environment [default]:
321 | ...
322 | ----
323 |
324 | [NOTE]
325 | ====
326 | If you have a `S3 Bucket does not exist` error, you probably have old CloudFormation Stack that looks up to the `aws-sam-cli-managed-default-samclisourcebucket` service. In that case, Go to *CloundFormation Service* in the AWS portal. Then, delete *aws-sam-cli-managed-default* stack.
327 | ====
328 |
329 | Then, you might need to confirm your configurations as below:
330 |
331 | [source,sh]
332 | ----
333 | CloudFormation stack changeset
334 | -------------------------------------------------------------------------------------------------------------------------------------
335 | Operation LogicalResourceId ResourceType Replacement
336 | -------------------------------------------------------------------------------------------------------------------------------------
337 | + Add EnterServerlessFunctionsHttpApi AWS::Lambda::Permission N/A
338 | EventPermission
339 | + Add EnterServerlessFunctionsRole AWS::IAM::Role N/A
340 | + Add EnterServerlessFunctions AWS::Lambda::Function N/A
341 | + Add ServerlessHttpApiApiGatewayDefa AWS::ApiGatewayV2::Stage N/A
342 | ultStage
343 | + Add ServerlessHttpApi AWS::ApiGatewayV2::Api N/A
344 | -------------------------------------------------------------------------------------------------------------------------------------
345 |
346 | Changeset created successfully. arn:aws:cloudformation:us-east-1:716861016243:changeSet/samcli-deploy1633488868/1e632117-3395-4b76-8037-bc6529ace78d
347 |
348 |
349 | Previewing CloudFormation changeset before deployment
350 | ======================================================
351 | Deploy this changeset? [y/N]:
352 | ----
353 |
354 | Press `y` then you will receive the outputs by CloudFormation in a few minutes. It should look like:
355 |
356 | [source,sh]
357 | ----
358 | CloudFormation events from changeset
359 | -------------------------------------------------------------------------------------------------------------------------------------
360 | ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
361 | -------------------------------------------------------------------------------------------------------------------------------------
362 | CREATE_IN_PROGRESS AWS::IAM::Role EnterServerlessFunctionsRole Resource creation Initiated
363 | CREATE_IN_PROGRESS AWS::IAM::Role EnterServerlessFunctionsRole -
364 | CREATE_COMPLETE AWS::IAM::Role EnterServerlessFunctionsRole -
365 | CREATE_IN_PROGRESS AWS::Lambda::Function EnterServerlessFunctions -
366 | CREATE_IN_PROGRESS AWS::Lambda::Function EnterServerlessFunctions Resource creation Initiated
367 | CREATE_COMPLETE AWS::Lambda::Function EnterServerlessFunctions -
368 | CREATE_IN_PROGRESS AWS::ApiGatewayV2::Api ServerlessHttpApi -
369 | CREATE_COMPLETE AWS::ApiGatewayV2::Api ServerlessHttpApi -
370 | CREATE_IN_PROGRESS AWS::ApiGatewayV2::Api ServerlessHttpApi Resource creation Initiated
371 | CREATE_IN_PROGRESS AWS::Lambda::Permission EnterServerlessFunctionsHttpApi Resource creation Initiated
372 | EventPermission
373 | CREATE_IN_PROGRESS AWS::Lambda::Permission EnterServerlessFunctionsHttpApi -
374 | EventPermission
375 | CREATE_IN_PROGRESS AWS::ApiGatewayV2::Stage ServerlessHttpApiApiGatewayDefa -
376 | ultStage
377 | CREATE_COMPLETE AWS::ApiGatewayV2::Stage ServerlessHttpApiApiGatewayDefa -
378 | ultStage
379 | CREATE_IN_PROGRESS AWS::ApiGatewayV2::Stage ServerlessHttpApiApiGatewayDefa Resource creation Initiated
380 | ultStage
381 | CREATE_COMPLETE AWS::Lambda::Permission EnterServerlessFunctionsHttpApi -
382 | EventPermission
383 | CREATE_COMPLETE AWS::CloudFormation::Stack quarkus-function -
384 | -------------------------------------------------------------------------------------------------------------------------------------
385 |
386 | CloudFormation outputs from deployed stack
387 | ----------------------------------------------------------------------------------------------------------------------------------------
388 | Outputs
389 | ----------------------------------------------------------------------------------------------------------------------------------------
390 | Key EnterServerlessFunctionsApi
391 | Description URL for application
392 | Value https://wcji0ss0ge.execute-api.us-east-1.amazonaws.com/
393 | ----------------------------------------------------------------------------------------------------------------------------------------
394 |
395 | Successfully created/updated stack - quarkus-function in us-east-1
396 | ----
397 |
398 | [NOTE]
399 | ====
400 | During the `sam deploy`, CloudFormation template will be created automatically (This is not stored in target directory though). Then you can monitor the function in AWS console.
401 | ====
402 |
403 | == Verify the Function in AWS Console
404 |
405 | Go to https://console.aws.amazon.com[AWS Console^] then navigate the following resources if they are automatically created along with the Quarkus function.
406 |
407 | === AWS API Gateway
408 |
409 | A new API gateway(e.g., _quarkus-function_) will show up when you specified it during the SAM deployment:
410 |
411 | image::../images/aws-gateapi.png[aws-gateapi]
412 |
413 | === AWS Identity and Access Management (IAM)
414 |
415 | A new role for the Quarkus function will show up:
416 |
417 | image::../images/aws-iam.png[aws-iam]
418 |
419 | === AWS Lambda
420 |
421 | A new Quarkus function will show up:
422 |
423 | image::../images/aws-function.png[aws-function]
424 |
425 | When you click on the function name, you can see the details such as package sizes as well as testing the function:
426 |
427 | image::../images/aws-function-detail.png[aws-function-detail]
428 |
429 | Access the function via HTTP gateway API URL. For example:
430 |
431 | [source,sh]
432 | ----
433 | http https://wcji0ss0ge.execute-api.us-east-1.amazonaws.com/hello/greeting/awsprod
434 | ----
435 |
436 | The output should look like:
437 |
438 | [source,sh]
439 | ----
440 | HTTP/1.1 200 OK
441 | Apigw-Requestid: EUxSijdzoAMEJ4w=
442 | Connection: keep-alive
443 | Content-Length: 48
444 | Content-Type: text/plain;charset=UTF-8
445 | Date: Wed, 03 May 2023 02:37:20 GMT
446 |
447 | Enter Serverless Functions with Quarkus, awsprod
448 | ----
449 |
450 | Deploy a native executable to AWS Lambda. Package the application once again using the following command:
451 |
452 | [NOTE]
453 | ====
454 | When you build a native executable on *macOS* or *Windows*, you need to add the following configuration in _src/main/resources/application.properties_ for building a Linux format image using Docker runtime
455 | ====
456 |
457 | [source,yaml]
458 | ----
459 | quarkus.native.container-runtime=docker
460 | ----
461 |
462 | [source,sh]
463 | ----
464 | quarkus build --native --no-tests
465 | ----
466 |
467 | Or you can run the following maven command:
468 |
469 | [source,sh]
470 | ----
471 | ./mvnw clean package -DskipTests -Pnative
472 | ----
473 |
474 | Once the build is _complete_, run the SAM CLI to deploy it using the following command. It takes a few minutes to complete the build:
475 |
476 | [source,sh]
477 | ----
478 | sam deploy -t target/sam.native.yaml -g
479 | ----
480 |
481 | Key a different stack name (`quarkus-native-function`) in the prompt:
482 |
483 | [source,sh]
484 | ----
485 | Looking for config file [samconfig.toml] : Not found
486 |
487 | Setting default arguments for 'sam deploy'
488 | =========================================
489 | Stack Name [quarkus-function]: quarkus-native-function
490 | AWS Region [us-east-1]:
491 | #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
492 | Confirm changes before deploy [Y/n]: y
493 | #SAM needs permission to be able to create roles to connect to the resources in your template
494 | Allow SAM CLI IAM role creation [Y/n]: y
495 | #Preserves the state of previously provisioned resources when an operation fails
496 | Disable rollback [y/N]: n
497 | EnterServerlessFunctionNative may not have authorization defined, Is this okay? [y/N]: y
498 | Save arguments to configuration file [Y/n]: y
499 | SAM configuration file [samconfig.toml]:
500 | SAM configuration environment [default]:
501 | ...
502 | ----
503 |
504 | Once you deploy it successfully, go back to the AWS console. You have new resources now.
505 |
506 | === AWS HTTP Gateway API
507 |
508 | image::../images/aws-gateapi2.png[aws-gateapi2]
509 |
510 | === AWS Lambda
511 |
512 | image::../images/aws-function2.png[aws-function2]
513 |
514 | **Great job!** You can access the new Quarkus native function via the **new** HTTP Gateway API. For example,
515 |
516 | [source,sh]
517 | ----
518 | http https://whgv0dgboe.execute-api.us-east-1.amazonaws.com/hello/greeting/awsnativeprod
519 | ----
520 |
521 | The output should look like:
522 |
523 | [source,texinfo]
524 | ----
525 | HTTP/1.1 200 OK
526 | Apigw-Requestid: T4gs9iu3oAMEMWw
527 | Connection: keep-alive
528 | Content-Length: 54
529 | Content-Type: text/plain;charset=UTF-8
530 | Date: Wed, 2 Nov 2022 20:18:14 GMT
531 |
532 | Enter Serverless Functions with Quarkus, awsnativeprod
533 | ----
534 |
535 | You can showcase the performance stats to compare *JVM* vs. *Native* function in _CloudWatch_ metrics:
536 |
537 | image::../images/aws-metrics.png[aws-metrics]
538 |
539 | ➡️ link:./4-optimize-quarkus-functions.adoc[4. Optimize the function and make it portable using Quarkus Funqy]
540 |
541 | ⬅️ link:./2-generate-quarkus-project.adoc[2. Generate a new Quarkus project]
542 |
--------------------------------------------------------------------------------
/instructions/4-optimize-quarkus-functions.adoc:
--------------------------------------------------------------------------------
1 | = 4. Optimize the function and make it portable using Quarkus Funqy
2 |
3 | Add a Quarkus Funqy extension for Amazon Lambda deployment(_quarkus-funqy-amazon-lambda_) and remove the _quarkus-amazon-lambda-http_ extension:
4 |
5 | [source,sh]
6 | ----
7 | quarkus ext add quarkus-funqy-amazon-lambda
8 |
9 | quarkus ext remove quarkus-amazon-lambda-http
10 | ----
11 |
12 | Update the `GreetingResource.java` file to use `@funq` annotation. Then, remove unnecessary packages and annotations(_@Path, @PathParam, @GET_).
13 |
14 | [source,java]
15 | ----
16 | package org.acme;
17 |
18 | import jakarta.inject.Inject;
19 | import io.quarkus.funqy.Funq;
20 |
21 | public class GreetingResource {
22 |
23 | @Inject
24 | GreetingService greetingService;
25 |
26 | @Funq
27 | public String greeting(String name) {
28 | return greetingService.greeting(name);
29 | }
30 |
31 | @Funq
32 | public String hello() {
33 | return "Hello Serverless";
34 | }
35 | }
36 | ----
37 |
38 | Before you'll deploy the function to AWS Lambda, you need to specify a function name. Add the following key and value in `application.properties` file:
39 |
40 | [source,yaml]
41 | ----
42 | quarkus.funqy.export=greeting
43 | ----
44 |
45 | Then, package the application once again using the following command:
46 |
47 | [source,sh]
48 | ----
49 | quarkus build --no-tests
50 | ----
51 |
52 | Or run the following maven package command:
53 |
54 | [source,sh]
55 | ----
56 | ./mvnw clean package -DskipTests
57 | ----
58 |
59 | Now, you have a new bash script to make you easier to deploy the function to AWS Lambda without using HTTP Gateway API, S3, ARN:
60 |
61 | * `manage.sh` - wrapper around aws lambda cli calls
62 |
63 | Open and inspect `manage.sh` file in the _target_ directory.
64 |
65 | You don't need to use the _SAM CLI_ directly since *manage.sh* script is a wrapper to create and delete a function simply.
66 |
67 | Let's update the *RUNTIME* in the `target/manage.sh` file to use Java 17 again.
68 |
69 | [source,sh]
70 | ----
71 | RUNTIME=java17
72 | ----
73 |
74 | Save the file.
75 |
76 | Run the script file with _LAMBDA_ROLE_ARN_ resource. If you have no IAM roles, you need to create a new one in the AWS console. Find more information https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create.html[here^].
77 |
78 | [source,sh]
79 | ----
80 | LAMBDA_ROLE_ARN= sh target/manage.sh create
81 | ----
82 |
83 | The output should look like:
84 |
85 | [source,sh]
86 | ----
87 | {
88 | "FunctionName": "EnterServerlessFunction",
89 | "FunctionArn": "arn:aws:lambda:us-east-1:716861016243:function:EnterServerlessFunction",
90 | "Runtime": "java17",
91 | "Role": "arn:aws:iam::716861016243:role/lambda-role",
92 | "Handler": "io.quarkus.funqy.lambda.FunqyStreamHandler::handleRequest",
93 | "CodeSize": 15614407,
94 | "Description": "",
95 | "Timeout": 15,
96 | "MemorySize": 256,
97 | "LastModified": "2023-05-03T02:59:36.252+0000",
98 | "CodeSha256": "4F2ZIQVC5x4c5AMius5hM+815ZSLB1AyzfideNpNxLk=",
99 | "Version": "$LATEST",
100 | "TracingConfig": {
101 | "Mode": "PassThrough"
102 | },
103 | "RevisionId": "19f56627-6307-467f-a621-f01cd8d4a4b8",
104 | "State": "Pending",
105 | "StateReason": "The function is being created.",
106 | "StateReasonCode": "Creating",
107 | "PackageType": "Zip",
108 | "Architectures": [
109 | "x86_64"
110 | ],
111 | "EphemeralStorage": {
112 | "Size": 512
113 | },
114 | "SnapStart": {
115 | "ApplyOn": "None",
116 | "OptimizationStatus": "Off"
117 | }
118 | }
119 | ----
120 |
121 | [NOTE]
122 | ====
123 | You probably see _"State": "Pending"_ in the result then go back to AWS web console to check if a new function is created or not.
124 | ====
125 |
126 | Press `q` to exit from the output terminal.
127 |
128 | Go back to Amazon web console then validate a new function(`EnterServerlessFunctions`):
129 |
130 | image::../images/aws-funqy.png[aws-funqy]
131 |
132 | Click the function name(`EnterServerlessFunctions`) then select `Test` menu. Input `"Funqy"` in the text area and `greeting` in Name field:
133 |
134 | image::../images/aws-test.png[aws-test]
135 |
136 | Click on `Test` button. Then, you will see the result as below. Click on `Details` to collapse the test details.
137 |
138 | image::../images/aws-test-result.png[aws-test-result]
139 |
140 | If the function is not required to run on AWS Lambda, remove it using the following command:
141 |
142 | [source,sh]
143 | ----
144 | LAMBDA_ROLE_ARN= sh target/manage.sh delete
145 | ----
146 |
147 | You can also remove the other HTTP gateway API functions using the following command:
148 |
149 | [source,sh]
150 | ----
151 | sam delete --stack-name quarkus-native-function
152 | ----
153 |
154 | If you want to deploy the Quarkus Funqy application as a native executables, you need to package a native executable first using `./mvnw clean package -Pnative` then run the wrapper script using `LAMBDA_ROLE_ARN= sh target/manage.sh native create`.
155 |
156 | ➡️ link:./5-deploy-quarkus-functions.adoc[5. Deploy the function to Red Hat OpenShift Serverless]
157 |
158 | ⬅️ link:./3-deploy-aws-lambda.adoc[3. Deploy to AWS Lambda with HTTP API]
159 |
--------------------------------------------------------------------------------
/instructions/5-deploy-quarkus-functions.adoc:
--------------------------------------------------------------------------------
1 | = 5. Deploy the function to Red Hat OpenShift Serverless
2 |
3 | You'll use the https://developers.redhat.com/developer-sandbox[Developer Sandbox^] to deploy a Quarkus function. The sandbox allows developers to access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new sandbox environments for Red Hat OpenShift and CodeReady Workspaces. Try your hand at the technologies with our library of activities as well. You need to sign up the https://developers.redhat.com/developer-sandbox/get-started[Red Hat Developer Program^] first to provision a free sandbox. It will take less than 5 min from sign up to create a new cluster along the way.
4 |
5 | Add an OpenShift and Knative Funqy extensions then remove an existing AWS extension:
6 |
7 | [source,sh]
8 | ----
9 | quarkus ext add quarkus-funqy-knative-events quarkus-openshift
10 |
11 | quarkus ext remove quarkus-funqy-amazon-lambda
12 | ----
13 |
14 | Update the `application.properties` for OpenShift Serverless deployment:
15 |
16 | [NOTE]
17 | ====
18 | Replace `username` with your own account in the developer sandbox.
19 | ====
20 |
21 | [source,yaml]
22 | ----
23 | quarkus.container-image.group=username-dev
24 | quarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000
25 | quarkus.kubernetes-client.trust-certs=true
26 | quarkus.kubernetes.deploy=true
27 | quarkus.kubernetes.deployment-target=knative
28 | ----
29 |
30 | [NOTE]
31 | ====
32 | If you want to use your own OpenShift cluster, you need to install _OpenShift Serverless Operator_ and _Knative-Serving_. Find more information https://docs.openshift.com/container-platform/4.8/serverless/admin_guide/install-serverless-operator.html[here^].
33 | ====
34 |
35 | Make sure to log in the Developer Sandbox:
36 |
37 | image::../images/copy-login.png[copy-login]
38 |
39 | Click on `DevSandbox` then click on `Display Token`. It will show *Log in with this token*.
40 |
41 | image::../images/copy-login-token.png[copy-login-token]
42 |
43 | Copy the `oc login` command then paste it in your working terminal.
44 |
45 | Run the following Maven command to deploy the function to OpenShift Serverless:
46 |
47 | [source,sh]
48 | ----
49 | quarkus build --no-tests
50 | ----
51 |
52 | Or run the following maven package command:
53 |
54 | [source,sh]
55 | ----
56 | ./mvnw clean package -DskipTests
57 | ----
58 |
59 | The output will end with `BUILD SUCCESS`. You can overwrite the pod label to show the Quarkus icon by running the following https://docs.openshift.com/container-platform/4.9/cli_reference/openshift_cli/getting-started-cli.html[oc^] command:
60 |
61 |
62 | [source,sh]
63 | ----
64 | oc label rev/enter-serverless-function-00001 app.openshift.io/runtime=quarkus --overwrite
65 | ----
66 |
67 | If you deployed the function multiple times, the revision number (e.g. _00001_) should be different.
68 |
69 | Add the **function** icon to the Knative service by running the following oc command:
70 |
71 | [source,sh]
72 | ----
73 | oc label ksvc/enter-serverless-function boson.dev/function=true --overwrite
74 | ----
75 |
76 | Go to the `Topology` view in _OpenShift Developer console_:
77 |
78 | image::../images/openshift-funq.png[openshift-funq]
79 |
80 | You might see the pod is already **terminated** since the scale-down-to-zero is `30` seconds by default in Knative Serving.
81 |
82 | Copy the `Route URL` in Resource tab menu then invoke the function using HTTPie:
83 |
84 | [source,sh]
85 | ----
86 | echo '"Daniel Oh"' | http https://enter-serverless-function-doh-dev.apps.sandbox-m2.ll9k.p1.openshiftapps.com
87 | ----
88 |
89 | The output should look like:
90 |
91 | [source,sh]
92 | ----
93 | HTTP/1.1 200 OK
94 | content-length: 52
95 | content-type: application/json
96 | date: Wed, 2 Nov 2022 17:53:33 GMT
97 | server: envoy
98 | set-cookie: f301134c73b56fb5a7c418e831b3c2ee=a4a6175a464d76be57ebe4bdabb3decd; path=/; HttpOnly
99 | x-envoy-upstream-service-time: 23
100 |
101 | "Enter Serverless Functions with Quarkus, Daniel Oh"
102 | ----
103 |
104 | You can also use `curl` command to access the endpoint:
105 | [source,sh]
106 | ----
107 | curl -X POST -H "Content-Type: application/json" -d '"Daniel Oh"' https://enter-serverless-function-doh-dev.apps.sandbox-m2.ll9k.p1.openshiftapps.com ; echo
108 | ----
109 |
110 | When you got back to the Topology view, you will see the Quarkus pod is automatically scaled up in a second:
111 |
112 | image::../images/openshift-funq-up.png[openshift-funq-up]
113 |
114 | [NOTE]
115 | ====
116 | When you deploy a native executable, the build will take more than 5 mins to finish. You might also have an out of memory error. To fix it, make sure to set `Dquarkus.native.native-image-xmx=4g`.
117 | ====
118 |
119 | ➡️ link:./6-generate-kn-functions.adoc[6. Generate a new function project using Kn func CLI]
120 |
121 | ⬅️ link:./4-optimize-quarkus-functions.adoc[4. Optimize the function and make it portable using Quarkus Funqy]
122 |
--------------------------------------------------------------------------------
/instructions/6-generate-kn-functions.adoc:
--------------------------------------------------------------------------------
1 | = 6. Generate a new function project using Kn func CLI
2 |
3 | [NOTE]
4 | ====
5 | Red Hat OpenShift Serverless Function is still a Tech Preview feature. If you haven't installed Knative command (kn) yet, find more information https://docs.openshift.com/container-platform/4.11/serverless/cli_tools/advanced-kn-config.html[here^].
6 |
7 | In case you want to install *kn* command tool in the Developer Sandbox, run the following *curl* command. It will download the *kn* tool in */tmp* directory.
8 |
9 | [source,sh]
10 | ----
11 | curl -L -o /tmp/kn https://github.com/knative/client/releases/download/knative-v1.8.1/kn-linux-amd64 ; chmod a+x /tmp/kn; /tmp/kn version
12 | ----
13 | ====
14 |
15 | Run the following command:
16 |
17 | [source,sh]
18 | ----
19 | cd ..
20 | kn func create quarkus-func -l quarkus -t cloudevents
21 | ----
22 |
23 | The output should look like:
24 |
25 | [source,sh]
26 | ----
27 | Created quarkus Function in /serverless-workshop/quarkus-func
28 | ----
29 |
30 | Inspect the new function project such as `func.yaml` and `Function.java`.
31 |
32 | Deploy the function directly to Red Hat OpenShift. Make sure to change the directory where the _func.yaml_ exists:
33 |
34 | Replace `YOUR_USERNAME` with your own account in the developer sandbox. You also need to replace `YOUR_CONTAINER_REGISTRY` with an external container registry that you want to push the image. For example, *quay.io/danieloh30*
35 |
36 | [source,sh]
37 | ----
38 | cd quarkus-func
39 | kn func deploy -r YOUR_CONTAINER_REGISTRY -n YOUR_USERNAME-dev -v
40 | ----
41 |
42 | [NOTE]
43 | ====
44 | In case you want to build the image on macOS M1/M2, you need to append *--platform linux/x86_64* to the command line.
45 | ====
46 |
47 | Kn func uses https://buildpacks.io[Buildpack^] tool to build a function and deploy it to Kubernetes or OpenShift. Once the build is completed, you will see the output like:
48 |
49 | [source,sh]
50 | ----
51 | Waiting for Knative Service to become ready
52 | Function deployed at URL: https://quarkus-func-doh-dev.apps.sandbox-m2.ll9k.p1.openshiftapps.com
53 | ----
54 |
55 | Go back to the `Topology` view in the developer sandbox, you will see a new function deployed. You can also overwrite the Quarkus label by _oc_ command or OpenShift web console:
56 |
57 | image::../images/openshift-kn-funq.png[openshift-kn-funq]
58 |
59 | Send a new `cloudevent` message to the new function using Kn func emit:
60 |
61 | [source,sh]
62 | ----
63 | kn func invoke --content-type="application/json" --data="Daniel Oh" -f=cloudevent -t=YOUR_FUNCTION_URL
64 | ----
65 |
66 | The output should look like:
67 |
68 | [source,sh]
69 | ----
70 | p1.openshiftapps.com
71 | Context Attributes,
72 | specversion: 1.0
73 | type: function.output
74 | source: function
75 | id: ceb3f86a-bc4c-49db-8a82-d69b1ed81aab
76 | datacontenttype: application/json
77 | Data,
78 | {
79 | "message": "Daniel Oh"
80 | }
81 | ----
82 |
83 | When you go to the pod logs in OpenShift console, you will see the same cloudevent message output:
84 |
85 | image::../images/openshift-cloudevent-log.png[openshift-cloudevent-log]
86 |
87 | === Congratulations!
88 |
89 | ➡️ link:./7-summary.adoc[7. Summary]
90 |
91 | ⬅️ link:./5-deploy-quarkus-functions.adoc[5. Deploy the function to Red Hat OpenShift Serverless]
92 |
--------------------------------------------------------------------------------
/instructions/7-summary.adoc:
--------------------------------------------------------------------------------
1 | = 7. Summary
2 |
3 | You've learned today how quickly Java developers can create cloud-native microservice project using https://quarkus.io[Quarkus^]. Then, the applications were deployed to serverless functions to https://aws.amazon.com/lambda[AWS Lambda^] and https://kubernetes.io[Kubernetes^] https://knative.dev/docs[Knative^] with `JVM` and `Native` mode with the key benefits of Quarkus as below:
4 |
5 | * Move as much as possible to build phase
6 | * Minimize runtime dependencies
7 | * Maximize dead code elimination
8 | * Introduce clear metadata contracts
9 | * Enhance developer joy
10 |
11 | The Quarkus native compilation allows you to have high resource density as almost same as https://go.dev[Go programming language^] on the Kubernetes clusters.
12 |
13 | image::../images/quarkus-container-first.png[quarkus-container-first]
14 |
15 | Quarkus funqy also provides the other extensions for you to deploy the serverless functions to `Azure Function` and `Google Cloud Platform`.
16 |
17 | image::../images/quarkus-funqy.png[quarkus-funqy]
18 |
19 | == Resources
20 |
21 | === eBook and Blogs
22 |
23 | * https://opensource.com/downloads/java-serverless-ebook[A guide to Java serverless functions^]
24 | * https://dzone.com/refcardz/getting-started-with-quarkus-serverless-functions[Getting Started with Quarkus Serverless Functions^]
25 | * https://www.infoq.com/articles/reduce-CO2-with-serveless[Reduce Carbon Dioxide Emissions with Serverless and Kubernetes Native Java^]
26 | * https://youtu.be/W2QPxfEU_bw[Video - Build your first Java Serverless Function using Quarkus Quick start^]
27 |
28 | === Tutorial Videos
29 |
30 | * https://youtu.be/fQFVwoXWRto[Quarkus Funqy OpenShift Serverless^]
31 | * https://youtu.be/BOvxdY8cSHw[Deploying Quarkus based Amazon Lambdas^]
32 | * https://youtu.be/3LtTQml7Gv8[Make Quarkus Serverless from Devfiles to OpenShift^]
33 | * https://youtu.be/zYSQdX-tVsE[Microsweeper Demo with Quarkus on Azure Red Hat OpenShift^]
34 | * https://youtu.be/UBDzHnDjc_g[Microsweeper Demo with Quarkus on Red Hat OpenShift Service on AWS^]
35 |
36 | ⬅️ link:./6-generate-kn-functions.adoc[6. Generate a new function project using Kn func CLI]
--------------------------------------------------------------------------------
/quarkus-func/.gitignore:
--------------------------------------------------------------------------------
1 | # Eclipse
2 | .project
3 | .classpath
4 | .settings/
5 | bin/
6 |
7 | # IntelliJ
8 | .idea
9 | *.ipr
10 | *.iml
11 | *.iws
12 |
13 | # NetBeans
14 | nb-configuration.xml
15 |
16 | # Visual Studio Code
17 | .vscode
18 | .factorypath
19 |
20 | # OSX
21 | .DS_Store
22 |
23 | # Vim
24 | *.swp
25 | *.swo
26 |
27 | # patch
28 | *.orig
29 | *.rej
30 |
31 | # Maven
32 | target/
33 | pom.xml.tag
34 | pom.xml.releaseBackup
35 | pom.xml.versionsBackup
36 | release.properties
--------------------------------------------------------------------------------
/quarkus-func/.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 | * 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 | import java.net.*;
17 | import java.io.*;
18 | import java.nio.channels.*;
19 | import java.util.Properties;
20 |
21 | public class MavenWrapperDownloader {
22 |
23 | private static final String WRAPPER_VERSION = "0.5.6";
24 | /**
25 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
26 | */
27 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
28 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
29 |
30 | /**
31 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
32 | * use instead of the default one.
33 | */
34 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
35 | ".mvn/wrapper/maven-wrapper.properties";
36 |
37 | /**
38 | * Path where the maven-wrapper.jar will be saved to.
39 | */
40 | private static final String MAVEN_WRAPPER_JAR_PATH =
41 | ".mvn/wrapper/maven-wrapper.jar";
42 |
43 | /**
44 | * Name of the property which should be used to override the default download url for the wrapper.
45 | */
46 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
47 |
48 | public static void main(String args[]) {
49 | System.out.println("- Downloader started");
50 | File baseDirectory = new File(args[0]);
51 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
52 |
53 | // If the maven-wrapper.properties exists, read it and check if it contains a custom
54 | // wrapperUrl parameter.
55 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
56 | String url = DEFAULT_DOWNLOAD_URL;
57 | if(mavenWrapperPropertyFile.exists()) {
58 | FileInputStream mavenWrapperPropertyFileInputStream = null;
59 | try {
60 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
61 | Properties mavenWrapperProperties = new Properties();
62 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
63 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
64 | } catch (IOException e) {
65 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
66 | } finally {
67 | try {
68 | if(mavenWrapperPropertyFileInputStream != null) {
69 | mavenWrapperPropertyFileInputStream.close();
70 | }
71 | } catch (IOException e) {
72 | // Ignore ...
73 | }
74 | }
75 | }
76 | System.out.println("- Downloading from: " + url);
77 |
78 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
79 | if(!outputFile.getParentFile().exists()) {
80 | if(!outputFile.getParentFile().mkdirs()) {
81 | System.out.println(
82 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
83 | }
84 | }
85 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
86 | try {
87 | downloadFileFromURL(url, outputFile);
88 | System.out.println("Done");
89 | System.exit(0);
90 | } catch (Throwable e) {
91 | System.out.println("- Error downloading");
92 | e.printStackTrace();
93 | System.exit(1);
94 | }
95 | }
96 |
97 | private static void downloadFileFromURL(String urlString, File destination) throws Exception {
98 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
99 | String username = System.getenv("MVNW_USERNAME");
100 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
101 | Authenticator.setDefault(new Authenticator() {
102 | @Override
103 | protected PasswordAuthentication getPasswordAuthentication() {
104 | return new PasswordAuthentication(username, password);
105 | }
106 | });
107 | }
108 | URL website = new URL(urlString);
109 | ReadableByteChannel rbc;
110 | rbc = Channels.newChannel(website.openStream());
111 | FileOutputStream fos = new FileOutputStream(destination);
112 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
113 | fos.close();
114 | rbc.close();
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/quarkus-func/.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 |
--------------------------------------------------------------------------------
/quarkus-func/README.md:
--------------------------------------------------------------------------------
1 | # Function project
2 |
3 | Welcome to your new Quarkus function project!
4 |
5 | This sample project contains a single function: `functions.Function.function()`,
6 | the function just returns its argument.
7 |
8 | ## Local execution
9 | Make sure that `Java 11 SDK` is installed.
10 |
11 | To start server locally run `./mvnw quarkus:dev`.
12 | The command starts http server and automatically watches for changes of source code.
13 | If source code changes the change will be propagated to running server. It also opens debugging port `5005`
14 | so debugger can be attached if needed.
15 |
16 | To run test locally run `./mvnw test`.
17 |
18 | ## The `func` CLI
19 |
20 | It's recommended to set `FUNC_REGISTRY` environment variable.
21 | ```shell script
22 | # replace ~/.bashrc by your shell rc file
23 | # replace docker.io/johndoe with your registry
24 | export FUNC_REGISTRY=docker.io/johndoe
25 | echo "export FUNC_REGISTRY=docker.io/johndoe" >> ~/.bashrc
26 | ```
27 |
28 | ### Building
29 |
30 | This command builds OCI image for the function.
31 |
32 | ```shell script
33 | func build
34 | ```
35 |
36 | By default, JVM build is used.
37 | To enable native build set following environment variables to `func.yaml`:
38 | ```yaml
39 | buildEnvs:
40 | - name: BP_NATIVE_IMAGE
41 | value: "true"
42 | - name: BP_MAVEN_BUILT_ARTIFACT
43 | value: func.yaml target/native-sources/*
44 | - name: BP_MAVEN_BUILD_ARGUMENTS
45 | value: package -DskipTests=true -Dmaven.javadoc.skip=true -Dquarkus.package.type=native-sources
46 | - name: BP_NATIVE_IMAGE_BUILD_ARGUMENTS_FILE
47 | value: native-image.args
48 | - name: BP_NATIVE_IMAGE_BUILT_ARTIFACT
49 | value: '*-runner.jar'
50 | ```
51 |
52 | ### Running
53 |
54 | This command runs the function locally in a container
55 | using the image created above.
56 | ```shell script
57 | func run
58 | ```
59 |
60 | ### Deploying
61 |
62 | This commands will build and deploy the function into cluster.
63 |
64 | ```shell script
65 | func deploy # also triggers build
66 | ```
67 |
68 | ## Function invocation
69 |
70 | Do not forget to set `URL` variable to the route of your function.
71 |
72 | You get the route by following command.
73 | ```shell script
74 | func info
75 | ```
76 |
77 | ### cURL
78 |
79 | ```shell script
80 | URL=http://localhost:8080/
81 | curl -v ${URL} \
82 | -H "Content-Type:application/json" \
83 | -H "Ce-Id:1" \
84 | -H "Ce-Source:cloud-event-example" \
85 | -H "Ce-Type:dev.knative.example" \
86 | -H "Ce-Specversion:1.0" \
87 | -d "{\"message\": \"$(whoami)\"}\""
88 | ```
89 |
90 | ### HTTPie
91 |
92 | ```shell script
93 | URL=http://localhost:8080/
94 | http -v ${URL} \
95 | Content-Type:application/json \
96 | Ce-Id:1 \
97 | Ce-Source:cloud-event-example \
98 | Ce-Type:dev.knative.example \
99 | Ce-Specversion:1.0 \
100 | message=$(whoami)
101 | ```
102 |
--------------------------------------------------------------------------------
/quarkus-func/func.yaml:
--------------------------------------------------------------------------------
1 | specVersion: 0.35.0
2 | name: quarkus-func
3 | runtime: quarkus
4 | registry: quay.io/danieloh30
5 | image: ""
6 | imageDigest: ""
7 | created: 2023-05-02T23:21:26.219979-04:00
8 | invoke: cloudevent
9 | build:
10 | buildpacks: []
11 | builder: s2i
12 | buildEnvs:
13 | - name: BP_JVM_VERSION
14 | value: "17"
15 | - name: BP_NATIVE_IMAGE
16 | value: "false"
17 | - name: BP_MAVEN_BUILT_ARTIFACT
18 | value: func.yaml target/quarkus-app/lib/ target/quarkus-app/*.jar target/quarkus-app/app/
19 | target/quarkus-app/quarkus/
20 | - name: BP_MAVEN_BUILD_ARGUMENTS
21 | value: package -DskipTests=true -Dmaven.javadoc.skip=true -Dquarkus.package.type=fast-jar
22 | - name: MAVEN_S2I_ARTIFACT_DIRS
23 | value: target/quarkus-app
24 | - name: S2I_SOURCE_DEPLOYMENTS_FILTER
25 | value: lib quarkus-run.jar app quarkus
26 | run:
27 | volumes: []
28 | envs: []
29 | deploy:
30 | namespace: doh-dev
31 | remote: false
32 | annotations: {}
33 | options: {}
34 | labels: []
35 | healthEndpoints:
36 | liveness: /health/liveness
37 | readiness: /health/readiness
38 |
--------------------------------------------------------------------------------
/quarkus-func/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 | # http://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 |
--------------------------------------------------------------------------------
/quarkus-func/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 http://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 |
--------------------------------------------------------------------------------
/quarkus-func/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | org.acme
6 | function
7 | 1.0.0-SNAPSHOT
8 |
9 | 3.8.1
10 | 17
11 | UTF-8
12 | UTF-8
13 | quarkus-bom
14 | com.redhat.quarkus.platform
15 | 2.13.7.Final-redhat-00003
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-funqy-knative-events
34 |
35 |
36 | io.quarkus
37 | quarkus-smallrye-health
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 | true
58 |
59 |
60 | false
61 |
62 | redhat
63 | https://maven.repository.redhat.com/ga
64 |
65 |
66 |
67 |
68 |
69 | true
70 |
71 |
72 | false
73 |
74 | redhat
75 | https://maven.repository.redhat.com/ga
76 |
77 |
78 |
79 |
80 |
81 | ${quarkus.platform.group-id}
82 | quarkus-maven-plugin
83 | ${quarkus.platform.version}
84 | true
85 |
86 |
87 |
88 | build
89 | generate-code
90 | generate-code-tests
91 |
92 |
93 |
94 |
95 |
96 | maven-compiler-plugin
97 | ${compiler-plugin.version}
98 |
99 |
100 | -parameters
101 |
102 |
103 |
104 |
105 | maven-surefire-plugin
106 | ${surefire-plugin.version}
107 |
108 |
109 | org.jboss.logmanager.LogManager
110 | ${maven.home}
111 |
112 |
113 |
114 |
115 | maven-failsafe-plugin
116 | ${surefire-plugin.version}
117 |
118 |
119 |
120 | integration-test
121 | verify
122 |
123 |
124 |
125 | ${project.build.directory}/${project.build.finalName}-runner
126 | org.jboss.logmanager.LogManager
127 | ${maven.home}
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | native
138 |
139 |
140 | native
141 |
142 |
143 |
144 | false
145 | native
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/quarkus-func/src/main/java/functions/Function.java:
--------------------------------------------------------------------------------
1 | package functions;
2 |
3 | import io.quarkus.funqy.Funq;
4 | import io.quarkus.funqy.knative.events.CloudEvent;
5 | import io.quarkus.funqy.knative.events.CloudEventBuilder;
6 |
7 | /**
8 | * Your Function class
9 | */
10 | public class Function {
11 |
12 | /**
13 | * Use the Quarkus Funq extension for the function. This example
14 | * function simply echoes its input data.
15 | * @param input a CloudEvent
16 | * @return a CloudEvent
17 | */
18 | @Funq
19 | public CloudEvent